Click to See Complete Forum and Search --> : Debug Assertion Failed ... CrtIsVaildHeadpPointer
garryMarshall
January 26th, 2005, 04:35 PM
I am using VS7.0 and have a C# UI that talks to a Managed DLL that includes a unmanaged class that includes a legacy C++ library. When the unmanaged class inherites a class from the legacy C++ library I get the following runtime error.
Debug Assertion Failed
Program: xxxx.exe
File: dbgheap.c
Line: 1291
Expression: _CrtIsValidHeapPointer(pUserData)
I looked with google others who had this same problem. Most talk about a problem linking between a debug and release code. I have done the clean and done a complete rebuild of everything in debug mode and still have the problem. I have inherited from other legacy C++ library classes without having this problem.
Anyone have any other ideas on correcting this problem?
Thanks, Garry
garryMarshall
January 27th, 2005, 01:05 PM
I corrected the problem by creating a new folder and copied the sources and projects to it. I recompiled and rebuilt everything and this time it worked.
I spoke too soon. I made a change in the code and recompiled, rebuilt and run it again, the problem returned with the Debug Assertion Failed error.
These Microsoft bugs are driving be crazy.
Anyone has any more ideas????
Mick
January 27th, 2005, 05:54 PM
_CrtIsValidHeapPointer occurs when you alllocate memory in one heap and delete it in another heap.
The two common cases are:
1) Release vs debug - different heap managers.
2) Using mixed versions of the CRT ie: allocated mem in exe linked with static version of CRT, pass pointer to function in DLL using DLL versions of the CRT and deallocating in that heap.
What does the call stack look like? And who owns pUserData when it occurs?
garryMarshall
January 27th, 2005, 08:08 PM
This happens within my constructor that is inherited from a legacy C++ class. When I single step through the code, I get the error within the std::String_val constructor. It causes this error when I single step out of the Tidy() method. All of this code is in the Microsoft xstring include code for vc7. I do not even get to my legacy class.
It now happens in both release and debug mode of operation. I just can't put breakpoint and single step through the release code. I am running managed C++ and C# that is interfacing with the legacy C++ library. Other classes that I interfaced with work without any problems.
As I said the call stack is in the Microsoft xstring include file. How do I find out who ownes pUserData?
Thanks for your help, Garry
Mick
January 27th, 2005, 08:33 PM
For your C++ projects look in the project settings under " use run time library" are they both using:
release: multithread dll
debug: debug multithreaded dll
Some simple ways you find out who owns pUserData by looking at the address that is being freed.
1) walking back up the call stack to see if where the object is created or at least the code path that is taken in the free.
2) Looking at what is in memory at that address via the memory window
3) setting a data watch breakpoint on that address.
garryMarshall
January 28th, 2005, 09:34 AM
I looked at the "Runtime Library" that I was using and it was set to /MTd for debug. The documentation says that the linker will put LIBCMT.lib to resolve externals. When I did this, when my managed class constructor called the unmanged class constructor, the 'new' operator caused a "System.StackOverflow Exception". I fixed this by adding to the Linker Input "Additional Dependencies" the library "msvcrt.lib" and to "Ignore Specific Library "libcmt.lib" while in Debug mode. This fix may be what is causing a conflict with the legacy C++ .LIB using the "Runtime Library" of /MTD which uses LIBCMT.LIB. Is this correct?
For me to use LIBCMT.LIB I need to find out why the 'new' operator goes to never land when I single step through the disassembly code in my constructor.
Any help with this problem? By fixing the "System.StackOverflowException" problem would also fix the "Debug Assertion Failed" problem.
Thanks for all of your help,
Garry
Mick
January 28th, 2005, 10:01 AM
Look over this chart....so you have an idea of the RTLs and their meaning.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_c_run.2d.time_libraries.asp
So from your comments I can see some things wrong [confusing as your comments are :)]
1) Your linking to msvcrt.lib which is the 'release' version. Your then linking to the debug static multi thread versions. So correct those things the easy way for now by using the Debug Multithreaded Dll /MDd[since I have no idea what you are passing back and forth].
Get that corrected first then explain any additional issues with the managed<->managed interfacing.
garryMarshall
January 28th, 2005, 11:41 AM
Sorry that I forgot to add the 'd'. Let me say this again.
I fixed this by adding to the Linker Input "Additional Dependencies" the library "msvcrtd.lib" and to "Ignore Specific Library "libcmtd.lib" while in Debug mode. I did it the other way in the Release mode.
As suggested I changed the debug version to use the /MDd "Runtime Library". Now when I rebuild, I get the 'new", "delete", etc operators already defined in msvprtd.lib (msvcp71d.dll) linker errors. From this, do I need to ignore some library that caused the operators to be defined again?
Note that I now have no "Additional Dependencies" and no "Ignore Specific Libraries".
Thanks for your help. This has been driving me crazy.
Garry
garryMarshall
January 28th, 2005, 04:54 PM
I did figure out that I needed to ignore the "libcpmtd.lib" to remove the duplicate entries. Now I get "LINK : error LNK2020: unresolved token (0A00008D) _DebugHeapTag" error. I found out that it is defined only in the libcpmtd.lib that I ignored.
Also I have to use the /MTd option instead of the /MDd because several places I have read that the DLL and LIB must be complied with the same runtime library. The legacy C++ library that I am interfacing with was compiled with the /MTd runtime library. Now I am back where I started from. I am still getting the same runtime error message.
Debug Assertion Failed
Program: xxxx.exe
File: dbgheap.c
Line: 1291
Expression: _CrtIsValidHeapPointer(pUserData)
Any help would be appreciated.
Thanks, Garry
Mick
January 29th, 2005, 04:34 PM
It would help if you post your project or clearly lay out what the flow of modules are. Or at least the code involved.
My take is you have:
1. Managed .exe
2. Unmanged dll
3. Legacy dll
Read this so you understand a bit more about what you are facing.
http://support.microsoft.com/default.aspx?scid=kb;en-us;190799
If you want to see the issue first hand:
Create a dll project and link with the static multithreaded CRT.
1) Export a function that takes a std::string* as an argument and
calls delete on the passed in * in the body of the function.
Create an exe project and link with the static multithreaded CRT or the mutithreaded dll...whichever doesn't matter.
1) new a std::string and call the dll function. You will get a CrtIsValidHeapPointer.
Change them both to using mulitthreaded dll and re-run...
garryMarshall
January 31st, 2005, 12:07 PM
My debug code is layed out as follows:
1. C# UI code
2. Interface DLL which includes: (DLL /MTd) (one DLL with two classes)
a. Managed class
b. unmanaged class
3. Legacy C++ lib (runtime library: /MTd) can not be changed
I understand now that I can NOT mix the defining of /MTd (multithreaded static linking) and then linking in the msvcrtd.lib which is a dynamic link library. Since I can not change the Legacy C++ lib, I must use only static linking libraries in my interface DLL code which is also defined as using the /MTd RTC.
Note that I now have no "Additional Dependencies" and no "Ignore Specific Libraries".
By defineding my Interface DLL to be /MTd with NO other Linker Dependencies libraries, it compiles and links with no errors.
When I run the debug code, the C# code calls the Managed class constructor which in turn calls the unmanaged class constructor. The managed class constructor is as follows:
Interface.cpp
ConfigClass::ConfigClass()
{
m_pUnmanagedConfig = new UnmanagedConfig();
}
With the disassemby enabled, I can step through the above constructor and when it calls the "new" operator, I get the "System.StackOverflowExecption" unhandled exception error. I assume from this that I must need another 'new' operator than that was linked in.
Is this correct or am I having another problem that I am missing? If this is correct, what 'new' operator must I include?
Thank you so much for all of your help in resolving this issue.
Garry
PS. I added to the above constructor
char * cKey = new char[21];
This 'new' operator also causes the same error. For some reason the system does not like the loaded 'new' operator.
Mick
January 31st, 2005, 07:53 PM
Well a couple of things first. It is kinda hard to tell what is going on from my end without the code to debug [which I can understand you may not be able to upload due to disclosure reasons] or at least a nice long disassembly listing. I do not use managed code all that much but I once stayed at a holiday inn express :p
Since we have moved away from the CrtIsValidHeapPointer issue we now come to the mixed dll issue. The exception you are getting is a stack overflow. So my "guess" is you are recursing inside of the loader within your mixed DLL which will exhaust the stack and generate the exception [setting aside that your code is not acutally doing the recursion] There are issues with using mixed dlls.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/vcconmixeddllloadingproblem.asp
http://support.microsoft.com/?id=814472
I will try and replicate a simple scenario for this and look at the disassembly [for my own knowledge] and see what is going on under the hood.
Mick
January 31st, 2005, 10:42 PM
You should probably concentrate on what I posted above...here is some more discussion on the topic [showing something similar to what you are seeing]
http://groups-beta.google.com/group/microsoft.public.dotnet.languages.vc/browse_thread/thread/2d7e5f7caa27aa22/9564dba0b8fe65ba?q=system.StackOverflowException+managed+unmanaged&_done=%2Fgroups%3Fq%3Dsystem.StackOverflowException+managed+unmanaged%26hl%3Den%26lr%3D%26sa%3DN%26tab%3Dwg%26&_doneTitle=Back+to+Search&&d#9564dba0b8fe65ba
http://groups-beta.google.com/group/microsoft.public.dotnet.languages.vc/browse_thread/thread/c340cd7b48d7356d/1c1d7372ebed5529?q=system.StackOverflowException+managed+unmanaged&_done=%2Fgroups%3Fq%3Dsystem.StackOverflowException+managed+unmanaged%26hl%3Den%26lr%3D%26sa%3DN%26tab%3Dwg%26&_doneTitle=Back+to+Search&&d#1c1d7372ebed5529
garryMarshall
February 1st, 2005, 12:01 PM
Thanks for the links. The articles were very interesting. I believe that explains some of my issues. I already had the items "To convert managed DLL to mixed mode" except the including of msvcrt.lib. When I add msvcrt.lib, I have to resolve conflicts that the libraries that are already included because it is using /MTd CRT. Mick keeps telling me that I should use the /MDd CRT, but then it creates a conflict with the legacy C++ .lib that uses /MTd CRT that can not be changed.
I have made the interface very simple now with only one class that only has a constructor. This is a DLL, /MTd CRT with no other libraries included.
Interface.cpp
ConfigClass::ConfigClass()
{
char * cKey = new char[21];
}
Now I have a C# code that only call as follows:
private Base.ConfigClass pConfig;
public void Init()
{
pConfig = new Base.ConfigClass();
}
I noticed that when I enble the Linker Show Progress to be /VERBOSE I do not see the new operator loaded in. But if I include the msvcrt.lib, I do see the new operator loaded in.
I feel that the "System.StackOverflowExecption" unhandled exception error is caused by the new operator is not really there.
Note that this small test project is included in my 35 mbyes legacy C++ .lib.
Anymore ideas on working around this Microsoft VS 2003 mixed managed and legacy code problem?
Thanks, Garry
garryMarshall
February 1st, 2005, 02:16 PM
HURRY !!!! Thanks to Mick for pointing me in the right direction. I looked at the links where it talked about in mixed mode some of the system variables are not setup, therefore you have to do it manually by calling the __crt_dll_initialize();. I added the two routines suggested as follows:
Interface.cpp
ConfigClass::ConfigClass()
{
minitialize() ; // must be first thing called
m_pUnmanagedConfig = new UnmanagedConfig();
}
~Config::ConfigClass()
{
delete m_pUnmandedConfig;
mterminate();
}
I have been working on this for weeks and thanks for finding the solution.
Thanks, Garry
atishanand
October 27th, 2005, 11:43 PM
Hi Gary & Mick,
I'm a new member to this forum.
I happened to face the sme problem you guys had an discussion on. I'm working on VC++ 7.0. The application which I've developed gives the same error on exiting while running in debug mode. I've tried changing the project settings mentioned in your follow up mails but it wouldn't wok. The problem doesn't come in release mode.
Can any of you guy help me out here.
Thansk,
Atish
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.