Noah Roth
Noah Roth

Reputation: 276

Visual Studio: Debug before main() function call

I'm having an issue where my application is failing a debug assertion (_CrtIsValidHeapPointer) before anything is even executed. I know this because I added a breakpoint on the first statement of my main function, and it fails the assertion before the breakpoint is reached.

Is there a way to somehow "step through" everything that happens before my main function is called? Things like static member initializations, etc.

I should note that my program is written in C++/CLI. I recently upgraded to VS2015 and am targeting the v140 toolset. The C++ libraries I'm using (ImageMagick, libsquish, and one of my own C++ libraries) have been tested individually, and I do not receive the assertion failure with these libraries, so it has to be my main application.

I haven't changed any of the code since I upgraded from VS2013, so I'm a little stumped on what is going on.

EDIT: Here is the call stack. This is after I click "Retry" in the assertion failed window. I then get a multitude of other exceptions being thrown, but they are different each time I run the program.

>   ucrtbased.dll!527a6853()    
[Frames below may be incorrect and/or missing, no symbols loaded for ucrtbased.dll] 
ucrtbased.dll!527a7130()    
ucrtbased.dll!527a69cb()    
ucrtbased.dll!527c8116()    
ucrtbased.dll!527c7eb3()    
ucrtbased.dll!527c7fb3()    
ucrtbased.dll!527c84b0()    
PathCreator.exe!_onexit(int (void)* const function)  Line 268 + 0xe bytes   C++
PathCreator.exe!atexit(void (void)* const function)  Line 276 + 0x9 bytes   C++
PathCreator.exe!std::`dynamic initializer for '_Fac_tidy_reg''()  Line 65 + 0xd bytes   C++
[External Code] 
mscoreei.dll!7401cd87()     
mscoree.dll!741fdd05()  
kernel32.dll!76c33744()     
ntdll.dll!7720a064()    
ntdll.dll!7720a02f()    

Upvotes: 4

Views: 2304

Answers (1)

Hans Passant
Hans Passant

Reputation: 942119

You have to debug the C runtime initialization code. Not intuitive to do because the debugger tries hard to avoid it and get you into the main() entrypoint instead. But still possible, use Debug > New Breakpoint > Function Breakpoint.

Enter _initterm for the function name, Language = C.

Press F5 and the breakpoint will hit. You should see the C runtime source code. You can now single-step through the initialization functions of your program one-by-one, every call to (**it)() executes one.


That's exactly what you asked for. But not very likely what you actually want. The odds that your code produces this error are very low. Much more likely is that one of these libraries causes this problem. They are likely to be built targeting another version of the C runtime library. And therefore have their own _initterm() function.

Having more than one copy of the C runtime library in a process is generally very unhealthy. And highly likely to generate heap corruption. If you can't locate it from the stack trace (be sure to change the Debugger Type from Auto to Mixed, always post the stack trace in an SO question) then the next thing you should strongly consider is rebuilding those libraries with the VS version you use.

Upvotes: 6

Related Questions