none
_CrtIsValidHeapPointer(pUserData) - why is this code broken. (vs2008)

    Question

  • I've created two projects in a fresh solution using Microsoft Visual C++ 2008 (Not Express).

     

    1. testui (managed Windows Forms Application /clr /MDd) (from the CLR Windows Forms Application template)

    2. testlib (unmanaged static library /MDd) (from the Empty Project template)

     

    The testui application is unmodified but is made to depend on the testlib.  It has had it's driver modified as follows:

     

    // testui.cpp : main project file.

    #include "stdafx.h"

    #include "Form1.h"

    #include "Test.h"

    using namespace testui;

    [STAThreadAttribute]

    int main(array<System:Tongue Tiedtring ^> ^args)

    {

    Test t;

    // Enabling Windows XP visual effects before any controls are created

    Application::EnableVisualStyles();

    Application:Tongue TiedetCompatibleTextRenderingDefault(false);

    // Create the main window and run it

    Application::Run(gcnew Form1());

    return 0;

    }

     

    Basically identical to the template, just we #include "Test.h" and create Test t;

     

    The testlib static library contains only one class as follows.

     

    // Test.h

    #include <vector>

    class Test

    {

    public:

    Test(void);

    private:

    static std::vector<void *> testvec;

    };

     

    // Test.cpp

    #include "Test.h"

    std::vector<void *> Test::testvec;

    Test::Test()

    {

    }

     

    When I run this program it fails with a Debug Assertion Failed! Expression: _CrtIsValidHeapPointer(pUserData) which of course is raised from _ASSERTE(_CrtIsValidHeapPointer(pUserData)); in dbgheap.c

     

    Why does this happen? && How do I fix this?  I developed this test case because it is occurring with a very large static library that uses a lot of stl based static member data similar to this test case.  Anyway, for completeness I have attached the output produced by vs2008 when it fails.

     

    Any help would be greately appreciated.

     

    Thanks

     

    'testui.exe': Loaded 'C:\Documents and Settings\Devel\Desktop\trees\test\testui\Debug\testui.exe', Symbols loaded.

    'testui.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll'

    'testui.exe': Loaded 'C:\WINDOWS\system32\mscoree.dll'

    'testui.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll'

    'testui.exe': Loaded 'C:\WINDOWS\system32\advapi32.dll'

    'testui.exe': Loaded 'C:\WINDOWS\system32\rpcrt4.dll'

    'testui.exe': Loaded 'C:\WINDOWS\system32\secur32.dll'

    'testui.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_597c3456\msvcr90d.dll', Symbols loaded.

    'testui.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_597c3456\msvcp90d.dll', Symbols loaded.

    'testui.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_597c3456\msvcm90d.dll', Symbols loaded.

    'testui.exe': Loaded 'C:\WINDOWS\system32\ole32.dll'

    'testui.exe': Loaded 'C:\WINDOWS\system32\gdi32.dll'

    'testui.exe': Loaded 'C:\WINDOWS\system32\user32.dll'

    'testui.exe': Loaded 'C:\WINDOWS\system32\msvcrt.dll'

    'testui.exe': Loaded 'C:\WINDOWS\system32\imm32.dll'

    'testui.exe': Loaded 'C:\WINDOWS\system32\shlwapi.dll'

    'testui.exe': Loaded 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll'

    'testui.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.1433_x-ww_5cf844d2\msvcr80.dll'

    'testui.exe': Loaded 'C:\WINDOWS\system32\shell32.dll'

    'testui.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.5512_x-ww_35d4ce83\comctl32.dll'

    'testui.exe': Loaded 'C:\WINDOWS\system32\comctl32.dll'

    'testui.exe': Loaded 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Culture.dll'

    'testui.exe': Unloaded 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Culture.dll'

    'testui.exe': Loaded 'C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\mscorlib\32e6f703c114f3a971cbe706586e3655\mscorlib.ni.dll'

    'testui.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll'

    'testui.exe': Loaded 'C:\WINDOWS\system32\uxtheme.dll'

    'testui.exe': Loaded 'C:\WINDOWS\system32\msctf.dll'

    'testui.exe' (Managed): Loaded 'c:\Documents and Settings\Devel\Desktop\trees\test\testui\Debug\testui.exe', Symbols loaded.

    'testui.exe': Loaded 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorjit.dll'

    'testui.exe': Loaded 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\diasymreader.dll'

    'testui.exe': Loaded 'C:\WINDOWS\system32\rsaenh.dll'

    'testui.exe' (Managed): Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_597c3456\msvcm90d.dll', Symbols loaded.

    'testui.exe': Loaded 'C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\System\ba0e3a22211ba7343e0116b051f2965a\System.ni.dll'

    'testui.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\System\2.0.0.0__b77a5c561934e089\System.dll'

    First-chance exception at 0x7c96c540 in testui.exe: 0xC0000005: Access violation reading location 0x23e7ad1a.

    'testui.exe': Loaded 'C:\WINDOWS\system32\version.dll'

    'testui.exe': Unloaded 'C:\WINDOWS\system32\version.dll'

    'testui.exe': Loaded 'C:\WINDOWS\system32\msctfime.ime'

    testui.exe has triggered a breakpoint

    The program '[0x184] testui.exe: Managed' has exited with code 0 (0x0).

    The program '[0x184] testui.exe: Native' has exited with code 0 (0x0).

     

     

    Monday, May 26, 2008 11:59 AM

Answers

  • I had a very similar problem with one of my mixed (managed and unmanaged) projects. I was using a Winforms with /clr specified for the GUI side calling into unmanaged code that at some point referenced a ATL header. Supposedly the winforms wizard configures the project by default to skip the CRT startup code when any ATL header file is detected and thus the reason for it crashing at the g_allocator initialization (this problem is not in the console /clr version). The fix below essentially reverses what the wizard does. On a side note, I included instructions below to obtain access to MSFTs symbols for use when debugging which helped me find this one, atleast to the point I knew what to search for in Google.

    Link describing the problem
    https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=99715&wa=wsignin1.0

    Anyhow here was what I had to do: add  __DllMainCRTStartup@12 in Force Symbols Reference section in the Linker section of the project settings.


    VS2008 - To configure Symbol Server, open the symbol search path options dialog. (From the Tools menu, click Options. In the left pane of the Options dialog box, Open the Debugging node and click Symbols.) Add the following search path to the search list: http://msdl.microsoft.com/download/symbols. Add a symbol cache directory to the symbol server cache text box. Click OK.
    • Proposed as answer by RobWW Monday, June 02, 2008 5:35 PM
    • Marked as answer by Yan-Fei Wei Sunday, August 03, 2008 2:35 PM
    Monday, June 02, 2008 5:35 PM
  • We are not looking at the code you've got that's crashing.  Your static member definition is not correct.  You'll need to post code that reproduces the Access violation exception as shown in your debug output.  Having the debugger stop at that exception with Debug + Exceptions might help you diagnose the problem.
    • Marked as answer by Yan-Fei Wei Sunday, August 03, 2008 2:36 PM
    Monday, May 26, 2008 3:01 PM
    Moderator

All replies

  • We are not looking at the code you've got that's crashing.  Your static member definition is not correct.  You'll need to post code that reproduces the Access violation exception as shown in your debug output.  Having the debugger stop at that exception with Debug + Exceptions might help you diagnose the problem.
    • Marked as answer by Yan-Fei Wei Sunday, August 03, 2008 2:36 PM
    Monday, May 26, 2008 3:01 PM
    Moderator
  • That is all of the code in both of the projects.  There is nothing else.  Commenting out the line Test t; in main stops the exception from occurring.

     

    I'm happy for you to state that the static member definition is incorrect.  But could you give some explanation, I mean if I thought it was incorrect I would have fixed it before posting.

     

    Why isn't it correct?

    What is the correct way to define a static std::vector<...> member in a class?

    Less important but still interesting why doesn't the compiler error/warn?

     

    By the way here is the callstack if I break for debug when it occurrs.

     

    > msvcr90d.dll!_msize_dbg(void * pUserData=0x9e202f1b, int nBlockUse=0x00000002)  Line 1511 + 0x30 bytes C++
      msvcr90d.dll!_dllonexit_nolock(int (void)* func=0x9e607abb, void (void)* * * pbegin=0x0012ee18, void (void)* * * pend=0x0012ee10)  Line 295 + 0xd bytes C
      msvcr90d.dll!__dllonexit(int (void)* func=0x9e607abb, void (void)* * * pbegin=0x0012ee18, void (void)* * * pend=0x0012ee10)  Line 273 + 0x11 bytes C
      testui.exe!_onexit(int (void)* func=0x004055a0)  Line 110 + 0x1b bytes C
      testui.exe!atexit(void (void)* func=0x004055a0)  Line 127 + 0x9 bytes C
      testui.exe!`dynamic initializer for 'Test::testvec''()  Line 3 + 0x32 bytes C++
      [Managed to Native Transition] 
      testui.exe!_initterm(void** pfbegin = 0x00406148, void pfend = ) Line 130 C++
      testui.exe!<CrtImplementationDetails>::LanguageSupport::InitializeNative() Line 534 C++
      testui.exe!<CrtImplementationDetails>::LanguageSupport::_Initialize() Line 657 C++
      testui.exe!<CrtImplementationDetails>::LanguageSupport::Initialize() Line 855 C++
      testui.exe!?.cctor@@$$FYMXXZ() Line 901 + 0x9 bytes C++
      [Frames below may be incorrect and/or missing, no symbols loaded for mscorwks.dll] 
      kernel32.dll!7c839736()  
      kernel32.dll!7c809af9()  
      kernel32.dll!7c839736()  
      kernel32.dll!7c809af9()  
      mscoree.dll!7900b1b3()  
      kernel32.dll!7c817067()  

     

    Thanks

    • Proposed as answer by RobWW Monday, June 02, 2008 5:20 PM
    Monday, May 26, 2008 11:17 PM
  • I had a very similar problem with one of my mixed (managed and unmanaged) projects. I was using a Winforms with /clr specified for the GUI side calling into unmanaged code that at some point referenced a ATL header. Supposedly the winforms wizard configures the project by default to skip the CRT startup code when any ATL header file is detected and thus the reason for it crashing at the g_allocator initialization (this problem is not in the console /clr version). The fix below essentially reverses what the wizard does. On a side note, I included instructions below to obtain access to MSFTs symbols for use when debugging which helped me find this one, atleast to the point I knew what to search for in Google.

    Link describing the problem
    https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=99715&wa=wsignin1.0

    Anyhow here was what I had to do: add  __DllMainCRTStartup@12 in Force Symbols Reference section in the Linker section of the project settings.


    VS2008 - To configure Symbol Server, open the symbol search path options dialog. (From the Tools menu, click Options. In the left pane of the Options dialog box, Open the Debugging node and click Symbols.) Add the following search path to the search list: http://msdl.microsoft.com/download/symbols. Add a symbol cache directory to the symbol server cache text box. Click OK.
    • Proposed as answer by RobWW Monday, June 02, 2008 5:35 PM
    • Marked as answer by Yan-Fei Wei Sunday, August 03, 2008 2:35 PM
    Monday, June 02, 2008 5:35 PM
  • I had the exact same problem while using a windows forms application with /clr that depended on a static library that referenced an ATL header, and adding __DllMainCRTStartup@12 in force Symbols Reference sectoin in the Linker section of the project worked for me.  Thanks for posting your solution RobWW.

    • Edited by ddbabich Friday, July 25, 2008 9:48 PM added more details
    Friday, July 25, 2008 9:45 PM
  • I don't know if the context of my application is the same as yours.  However, adding the mentioned symbol allowed my application to run without throwing an exception _CrtIsValidHeapPointer(pUserData)  I am using a VS2008 C++/CLI Winform project that does use the header atlstr.h (used for CString though not using MFC).  I only get the crash as long as atlstr. is used.

    Adding that (
    __DllMainCRTStartup@12) symbol solved it!

    If I don't put the link in the Symbol Server, can I still use the solution as-is?  Build times are longer with it in as opposed to without.

    Thanks for a huge help

    Jer 29:11
    Tuesday, August 11, 2009 3:20 PM
  • Hi,

     I am migrating my application which was developed in VC++ 6.0 to VS2010. The application has one exe and dlls. all the DLLs are linked statically. Now it throws exception in the below code.

    * * 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));

     In my output window i am having the below message

    Initializing GPSMGR.DLL from C:\APPS\GPS\GPS1200\Gps32d.exe HEAP[Gps32d.exe]: Invalid Address specified to RtlValidateHeap( 00B50000, 7907CD38 ) Windows has triggered a breakpoint in Gps32d.exe. This may be due to a corruption of the heap, which indicates a bug in Gps32d.exe or any of the DLLs it has loaded. This may also be due to the user pressing F12 while Gps32d.exe has focus. The output window may have more diagnostic information. 'Gps32d.exe': Loaded 'C:\WINDOWS\system32\msctfime.ime', Symbols loaded (source information stripped). Gps32d.exe has triggered a breakpoint

    My stack is looking like below >

    msvcr100d.dll!realloc_help(void * pUserData, unsigned int * pnNewSize, int nBlockUse, const char * szFileName, int nLine, int fRealloc) Line 793 + 0x30 bytes C++

     msvcr100d.dll!_realloc_dbg(void * pUserData, unsigned int nNewSize, int nBlockUse, const char * szFileName, int nLine) Line 1040 + 0x1b bytes C++

    mfc100d.dll!CAfxStringMgr::Reallocate(ATL::CStringData * pData, int nChars, int nCharSize) Line 188 + 0x1a bytes C++

    mfc100d.dll!ATL::CSimpleStringT<char,1>::Reallocate(int nLength) Line 881 + 0x17 bytes C++

     mfc100d.dll!ATL::CSimpleStringT<char,1>::PrepareWrite2(int nLength) Line 870 C++ mfc100d.dll!ATL::CSimpleStringT<char,1>::PrepareWrite(int nLength) Line 838 C++

    mfc100d.dll!ATL::CSimpleStringT<char,1>::GetBuffer(int nMinBufferLength) Line 535 C++

    mfc100d.dll!ATL::CSimpleStringT<char,1>::SetString(const char * pszSrc, int nLength) Line 654 + 0xc bytes C++ mfc100d.dll!ATL::CSimpleStringT<char,1>::SetString(const char * pszSrc) Line 629 C++ mfc100d.dll!ATL::CSimpleStringT<char,1>::operator=(const char * pszSrc) Line 342 C++

    mfc100d.dll!ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> > >::operator=(const char * pszSrc) Line 1235 C++ gpssc32d.dll!CMapStringToWord::operator[](const char * key) Line 277 C++

    gpssc32d.dll!CMapStringToWord::SetAt(const char * key, unsigned short newValue) Line 123 + 0x13 bytes C++

    GpsCt32d.Dll!CGpsInit::LoadOneName2Maps(const char * lpszColName, int nFillType, int fValueMap) Line 389 C++

    GpsCt32d.Dll!CGpsInit::LoadColName2Maps() Line 147 + 0x12 bytes C++ GpsCt32d.Dll!CGpsInit::Initialize() Line 329 + 0x5 bytes C++

     GpsMg32D.dll!InitGpsMgrDll(HINSTANCE__ * hInstance) Line 236 C++

    Gps32d.exe!0040bb86()

    [Frames below may be incorrect and/or missing, no symbols loaded for Gps32d.exe]

    ntdll.dll!_NtQueryDebugFilterState@8() + 0xc bytes

    ntdll.dll!_vDbgPrintExWithPrefix@20() + 0x43 bytes

    ntdll.dll!_RtlAllocateHeapSlowly@12() + 0x3da bytes

    I searched in the google that the c runtime in property page should be /MD or /MDd. i did it. but still i am facing the problem once it reaches to the below code in my application.

    AFXCOLL_INLINE void CMapStringToWord::SetAt(LPCTSTR key, WORD newValue) { (*this)[key] = newValue; }

    I am not facing this problem in release mode.

    Pls help me to resolve it.

    Thanks

    Rani

    Monday, August 22, 2011 4:41 AM
  • When you run the debug configuration make sure that all the projects (exe and dlls) are using the /MDd setting, and that all the projects are built in the debug configuration.  You should not mix debug and release parts together.

    The reason it does not happen in release mode is that the heap validity checks are not done in release mode.  The problem is still there, but the consequences become unknown in release mode.

    Monday, August 22, 2011 12:48 PM