Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

VC++5 BUG: throw causes double call of destructor !!!!!

15 views
Skip to first unread message

David Morgenlender

unread,
Oct 15, 1998, 3:00:00 AM10/15/98
to
I'm developing an app using Visual C++ 5.0, under Win95. I've encountered what
appears to be a VERY serious compiler bug, as shown in the excerpts below from
the actual code.

AppUnknownException is a class derived from CORBA::UserException.

The throw in _proxy_DvtDiagnostics::echoString() looks essentially like:

AppUnknownException ex;
throw ex;

This invokes the AppUnknownException copy constructor, passing the new object
via the throw. The destructor for this object is invoked as the stack frame is
unwound for the throw. The destructor for this object is invoked a 2nd time
when the catch(CORBA::UserException& ex) block in HandleException() exits.
Needless to say, calling the destructor twice results in all kinds of crashes!

I've confirmed the double destructor call. Any suggestions for a workaround?

=====================================================================

void DoEchoString()
{
try
{
// This correctly throws an AppUnknownException
// exception:
_proxy_DvtDiagnostics::echoString();
}
catch(...)
{
HandleException();
}
}

void HandleException()
{
try
{
throw;
}
// catches ...
// The following catches the AppUnknownException exception:
catch(CORBA::UserException& ex)
{
//...
// falls through
}
// more catches ...
catch(...)
{
//...
}
}

=======================================================
Dave Morgenlender
e-mail: dmo...@alum.mit.edu
=======================================================

Ron Natalie

unread,
Oct 15, 1998, 3:00:00 AM10/15/98
to David Morgenlender
> The destructor for this object is invoked a 2nd time
> when the catch(CORBA::UserException& ex) block in HandleException() exits.

Are you sure you've got the destructors paired with the right
objects. There are going to be two AppUnknownExceptions created
here, one local to the function echoString and one for the
exception handler.

My simple test case shows normal behavior:

Construct this 0x0012FF44
Throwing ex 0x0012FF44
Construct this 0x0012FF40 from that 0x0012FF44
Destruct this 0x0012FF44
Caught 0x0012FF40
Destruct this 0x0012FF40

David Morgenlender

unread,
Oct 15, 1998, 3:00:00 AM10/15/98
to
Ron,

>Are you sure you've got the destructors paired with the right
>objects. There are going to be two AppUnknownExceptions created
>here, one local to the function echoString and one for the
>exception handler.
>
>My simple test case shows normal behavior:
>
>Construct this 0x0012FF44
>Throwing ex 0x0012FF44
>Construct this 0x0012FF40 from that 0x0012FF44
>Destruct this 0x0012FF44
>Caught 0x0012FF40
>Destruct this 0x0012FF40

Yes, I'm pretty sure. I traced thru carefully, watching the addresses of the
objects.

Doug Harrison

unread,
Oct 15, 1998, 3:00:00 AM10/15/98
to
David Morgenlender wrote:

>I've confirmed the double destructor call. Any suggestions for a workaround?

try { throw; } catch (X&) {} does indeed double-destruct the caught object.
You might want to report this to MS again at:

http://support.microsoft.com/support/visualc/report/default.asp

I don't recall finding a reasonable workaround. Sorry.

--
Doug Harrison
dHar...@worldnet.att.net


David Morgenlender

unread,
Oct 16, 1998, 3:00:00 AM10/16/98
to
Doug,

>>I've confirmed the double destructor call. Any suggestions for a workaround?
>
>try { throw; } catch (X&) {} does indeed double-destruct the caught object.
>You might want to report this to MS again at:
>
> http://support.microsoft.com/support/visualc/report/default.asp

Thanks for the confirmation & the pointer to the site; I just went there. They
need a specific example that fails, so I'll have to find a few minutes to create
a simple example.

Did they reply to your bug report? How long ago did you submit it?

>I don't recall finding a reasonable workaround. Sorry.

If I can't find a workaround this is going to get very ugly!!! I will have
about 30 CORBA method calls & I want to have a single function process all
exceptions (which for this app is fairly straightforward & very consistent
between methods). I don't want to implement all that code as a macro repeated
30 times!!! I haven't given a lot of thought to a workaround ... but so far, I
haven't come up with anything ... it potentially even harder because I can't
modify the exception object implementation (it's generated by the IDL compiler).

Thanks for your help.

Doug Harrison

unread,
Oct 18, 1998, 3:00:00 AM10/18/98
to
David Morgenlender wrote:

>Thanks for the confirmation & the pointer to the site; I just went there. They
>need a specific example that fails, so I'll have to find a few minutes to create
>a simple example.

You can use the one below. Compiled with "cl -GX k1.cpp" under VC6, the
program output is:

D>k1
ctor: 0012FF6C
dtor: 0012FF6C
dtor: 0012FF6C

#include <iostream>
using namespace std;

struct A
{
A() { cout << "ctor: " << this << endl; }
A(const A&) { cout << "copy ctor: " << this << endl; }
~A() { cout << "dtor: " << this << endl; }
};

void main()
{
try
{
throw A();
}
catch (A&)
{
try
{
throw;
}
catch (A&)
{
}
}
}

>Did they reply to your bug report? How long ago did you submit it?

They normally don't reply at all to bugs submitted that way, but I know for
sure that it isn't a black hole. If you need an answer, and you have a free
support incident remaining, you might want to use it now. But I wouldn't
count on a quick fix.

--
Doug Harrison
dHar...@worldnet.att.net


Matt Gibson

unread,
Oct 19, 1998, 3:00:00 AM10/19/98
to
Doug Harrison wrote:
> They normally don't reply at all to bugs submitted that way, but I know for
> sure that it isn't a black hole. If you need an answer, and you have a free
> support incident remaining, you might want to use it now. But I wouldn't
> count on a quick fix.

Even if you don't have a free one left, I might report it through support -- you
don't pay for anything that's actually a bug, do you?

M

--
"It's the gaps between the rain that count,
and learning how to live amongst them."
-- Jeff Noon, _Pixel Juice_
Matt Gibson http://www.netgates.co.uk/mbmg001/

David Morgenlender

unread,
Oct 27, 1998, 3:00:00 AM10/27/98
to
Doug,

>You can use the one below. Compiled with "cl -GX k1.cpp" under VC6, the
>program output is:
>
>D>k1
>ctor: 0012FF6C
>dtor: 0012FF6C
>dtor: 0012FF6C

Your example proved most helpful. I reported the problem to Microsoft. A VC++
tech support engineer got back to me. Overall, I was pleasantly surprised by
the experience; the people I spoke with were very responsive, pleasant &
cooperative. The bad news ... he confirmed this was a compiler bug without a
workaround. However, he suggested a workaround that should work in my
particular situation ...

Since all the expected exception objects are derived by a single base class, I
can do something like:

try
{
CorbaMethodCall();
}
catch(ExceptionBaseClass& ex)
{
ExceptionHandler(ex);
}
catch(...)
{
HandleUnknownException();
}

ExceptionHandler() can use RTTI to determine the actual exception object
(derived from ExceptionBaseClass), and it can access all member variables of the
object.

Thanks for your help!

0 new messages