Re: Windows app crash with Pegasus library 2.91 when compiled with /MT option
Bala Gopalakrishnan <[email protected]>
| Newsgroups | gmane.network.open-pegasus.general |
|---|---|
| Message-ID | <[email protected]> |
Hi All,
I think the reason given below should explain the crash with our app. with
Pegasus libraries built with -MT option. When we invoke the commands from
our application, CIMAPI invokes the functions in the pegclient.dll which
inturn invokes the functions in pegcommon.dll. When we send a cim request,
the pegcommon allocates a buffer for the HTTP header and passes it to the
function in pegclient.dll. The function in pegclient.dll uses that buffer
for some manipulation and then tries to deallocate it which results in the
crash. The crash is because the function in pegclient.dll is trying to
dellocate the memory that was allocated by pegcommon.dll.
/*
* If this ASSERT fails, a bad pointer has been passed in. It may be
* totally bogus, or it may have been allocated from another heap.
* The pointer MUST come from the 'local' heap.
*/
_ASSERTE(_CrtIsValidHeapPointer (pUserData) );
Since the Pegasus libraries are built with /MT option – that means we are
using the static CRT libraries. This results in different heap for
pegclient and pegcommon dlls. Since the memory is from another heap, when
the pegclient.dll tries to dellocate, it crashes.
So the only we way is to use /MD option to build the libraries and use the
Microsoft redistributed libraries so that both the pegclient and pegcommon
dlls use the same heap because it uses the same shared library. This allows
us to allocate in pegcommon dll and deallocate in pegclient dll.
So, with this information, it seems to me that we can’t get rid of the
Microsoft dll dependency.
In the below link, people have discussed similar issue :-
http://stackoverflow.com/questions/1634773/freeing-memory-allocated-in-a-different-dll
Additional Notes:
Building Windows DLLs and C run-time (CRT) linkage issues
---------------------------------------------------------
As a general rule, building a DLL with static CRT linkage is highly
discouraged, and intermixing CRTs in the same app is something to
avoid at any cost.
Reading and comprehension of Microsoft Knowledge Base articles
KB94248 and KB140584 is a must for any Windows developer. Especially
important is full understanding if you are not going to follow the
advice given above.
KB94248 - How To Use the C Run-Time
http://support.microsoft.com/kb/94248/en-us
KB140584 - How to link with the correct C Run-Time (CRT) library
http://support.microsoft.com/kb/140584/en-us
KB190799 - Potential Errors Passing CRT Objects Across DLL Boundaries
http://msdn.microsoft.com/en-us/library/ms235460
If your app is misbehaving in some strange way, or it is suffering
from memory corruption, before asking for further help, please try
first to rebuild every single library your app uses as well as your
app using the debug multithreaded dynamic C runtime.
Thanks,
Bala
On Tue, Mar 23, 2010 at 3:53 PM, Bala Gopalakrishnan <
[email protected]> wrote:
> Our company has an Windows application that uses Open Pegasus common and
> client library/dll to communicate with ESX Vmware in-box cimmon. Currently
> we use Pegasus 2.71 version library/dll built with VC++ 6.0. We are facing
> issues when we attempt to move to 2.91 version to support x64 and Itanium
> builds. We use Visual Studio 2008 professional and Team edition. Our
> company has a restriction not have dependency on Microsoft redistributables.
> The default build done with /MD option has dependency on msvcrt90.dll and
> msvcrp90.dll files. To remove the dependency I used the following flag
> PEGASUS_EXTRA_CXX_FLAGS=-MT. This flag did remove the dependency but causes
> the application to crash. Application built with default /MD option doesn't
> crash. Even the cimcli program built with /MT option crashes. Please see the
> below environment variables that I use.
>
>
>
> set PEGDIR=%cd%\
>
> set PEGASUS_ROOT=%PEGDIR%
>
> set PEGASUS_HOME=%PEGASUS_ROOT%
>
> set PEGASUS_PLATFORM=WIN32_IX86_MSVC
>
> set PEGASUS_ENABLE_CMPI_PROVIDER_MANAGER=false
>
> set PEGASUS_EXTRA_CXX_FLAGS=-MT
>
> set PEGASUS_ENABLE_SLP=false
>
> cd %PEGASUS_ROOT%
>
> make clobber
>
> cd %PEGASUS_ROOT%\src\Pegasus\Common
>
> make -f Makefile
>
> cd %PEGASUS_ROOT%\src\Pegasus\Client
>
> make -f Makefile
>
>
>
>
>
> I believe the crash happen when the Highlighted Array<HTTPHeader> header
> goes out of scope, stack unwinds calling its destructor.
>
>
>
> $PEGASUS_HOME\src\Pegasus\Client\CIMOperationRequestEncoder.cpp
>
>
>
> HTTPMessage * http_request = new HTTPMessage(buffer);
>
>
>
> // these variables are needed to call HTTPMessage::parse, all we need
>
> // is contentLength
>
> String startLine;
>
> Array<HTTPHeader> headers;
>
> Uint32 contentLength;
>
>
>
> http_request->parse(startLine, headers, contentLength);
>
> if (dataStore_prt)
>
> {
>
> dataStore_prt->setRequestSize(contentLength);
>
> dataStore_prt->setStartNetworkTime();
>
> }
>
>
>
> _outputQueue->enqueue(http_request);
>
> }
>
>
>
>
>
>
>
> The operator delete causes crash. File name is
> $PEGASUS_HOME\src\Pegasus\Common\ArrayRep.h
>
>
>
> template<class T>
>
> inline void ArrayRep<T>::unref(const ArrayRep<T>* rep_)
>
> {
>
> ArrayRep<T>* rep = (ArrayRep<T>*)rep_;
>
>
>
> if (rep != &ArrayRepBase::_empty_rep && rep->refs.decAndTestIfZero())
>
> {
>
> Destroy(rep->data(), rep->size);
>
> rep->refs.~AtomicInt();
>
> ::operator delete(rep);
>
> }
>
> }
>
>
>
>
>
> If I comment out the delete operator in unref(const ArrayRep<T>* rep_)
> method in Pegasus\Common\ArrayRep.h file the crash goes away. But
> this is also causing huge memory leaks in my application. Any help is
> appreciated.
>
>
>
> Thanks,
>
> Bala Gopalakrishnan
>
>
>