[omniORB] compiling omniORB3 on NT -- Assertion failure

Steven W. Brenneis brennes1@rjrt.com
Mon, 01 Nov 1999 10:47:26 -0500


All is clear now.  I was worried when I saw the responses to my response
since I have about ten applications and nearly two dozen DLL's that
freely pass heap pointers back and forth.  For example:

In the OnNewDocument member of a class derived from CDocument, a call is
made to the make member of an abstract factory to return a pointer to an
object of the type specified by the string parameter in the
OnNewDocument override.  The implementation of the concrete factory is
contained wholly within a DLL and invokes new.  In the destructor of the
document class, the pointer which was returned by the factory is
deleted.  The document class is not contained in the DLL, but rather in
the application image.  If the runtime library required that the DLL
delete this pointer, this application would exhibit assertion failures
every time the document window is closed, which it does not.

What makes this clear is the explanation in the "Memory Management and
the Debug Heap" topic in the MSDN liibrary.  The determination of which
new and delete operators are invoked is made by the inclusion of
CRTDBG.h and the presence of the following macro:

#ifdef _DEBUG
#define new DEBUG_NEW

For the sake of discussion, I will call the case where these are present
managed allocation and the case where they are not present unmanaged
allocation.  Managed heap allocation is performed by the runtime library
as described in the MSDN topic.  In unmanaged allocation, the debug
version of the operator new override simply invokes malloc and the debug
version of the operator delete override simply invokes free.  In the
example above, the concrete factory uses unmanaged allocation but the
document class invokes the delete operator under managed allocation. 
The reason this works is that the managed allocation delete operator
checks to see if the block was allocated by an unmanaged new operator
and skips the assertions if this is true.  This is important because
third-party DLL's and libraries, such as omniORB or my DLL, may or may
not use managed heap.  All this is further complicated by the fact that
the debug and non-debug versions of managed heap are handled
differently.  The most likely explanation of the problems Ji-Yong
encountered is that a non-debug managed allocation was made followed by
an attempt to make a debug managed deallocation.  I would not be
surprised to discover that Microsoft maintains a separate "heap" in its
MFC DLL's, but this should not change the way we all deal with normal
C++ heap.  They clearly recognized this as a problem for multi-threaded
processes and simply disallow (via assertion failures) inter-thread
access of MFC objects created on their "heap".

The bottom line here is that IMHO nothing really needs to be
dramatically changed in onmiORB but it will be incumbent (as it always
has been) on developers using omniORB with the Visual C runtime library
to be aware of these possibilities.

Steve Brenneis

Ji-Yong D. Chung wrote:
> 
> <?fontfamily><?param Helvetica>
>     Thanks, Lars -- that cleared things up.
> 
[snipped for brevity]