Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I diagnose heap corruption errors on Windows?

I'm using Windows 8.1 64-bit with Visual Studio 2013 Ultimate. I am porting a program from Linux to Windows which uses C++, OpenGL and SDL. I have the appropriate libraries custom compiled through cmake on 64-bit on Windows. When I run the program from Visual Studio, the IDE says there's a head corruption. This is no surprise since I'm using pointers to instantiate objects, and I'm using raw pointers which I do plan to change to smart pointers for the sake of the argument. I'll be doing the boost magic later.

In the meantime, I used my Linux computer to diagnose any memory leaks through Valgrind and there was nothing serious reported from Valgrind. I then proceeded to use CppCheck but there was nothing serious on there either. Maybe I'm being too lenient here and Windows might actually be taking the less serious stuff more serious than Linux does, which is a surprise since MSVC tends to be more forgiving than GCC.

So, the program works on Linux and it doesn't on Windows. (Just great!) And Visual Studio isn't helping by throwing exceptions all over the place which makes me hate Windows even more. I started googling around for a solution and came across this thing called gflags or page helper, so I installed the debugging tools and tried to launch gflags but I have no idea how to use it! I then later found that you had to use some other tool called adp and then attach gflags to it, so when I launched adp it crashes. So now I have no idea what to do and am on the verge of aborting the port (which is funny since many people are complaining how hard it is to port programs from Windows to Linux while the opposite is true).

So, now I appeal to this community for help: how do I debug/diagnose heap corruption errors that occur on Windows but not on Linux? Am I really supposed to be using gflags or should I just use my guts on this?

like image 672
Poriferous Avatar asked May 23 '15 13:05

Poriferous


2 Answers

Use the debug heap and call this at the very beginning in main().

_CrtSetDbgFlag(_CRTDBG_CHECK_ALWAYS_DF);

It will slow down the program a lot but it should break as soon as corruption occurs.

Refer to this article for details: https://msdn.microsoft.com/en-us/library/974tc9t1.aspx#BKMK_Check_for_heap_integrity_and_memory_leaks

like image 162
Carlos A. Ibarra Avatar answered Oct 19 '22 06:10

Carlos A. Ibarra


The @Carlos's solution is perfect for smaller problems. But for huge problems, the resulting slow down is sometimes something you cannot stomach.

In this case, one can place

ASSERT(_CrtCheckMemory()); 

somewhere in the code, where one suspects the problem already to be present. This command checks the heap at (and only at) the spot it is inserted, and not after every new or delete call as in the case of _CRTDBG_CHECK_ALWAYS_DF. This keeps the execution time reasonable, compared to option _CRTDBG_CHECK_ALWAYS_DF.

One can find the problematic line of code pretty quickly by using a binary search kind of approach for placing the asserts.


However, sometimes _CrtSetDbgFlag(_CRTDBG_CHECK_ALWAYS_DF) and/or _CrtCheckMemory() aren't able to detect problems. Then using gflags is another possibility, which is able to show where the heap-corruption happens:

  • enable page heap, e.g.:
    C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\gflags.exe" -p /enable exe_to_debug.exe /full 
    
  • run program in debugger. Accesses out of bounds, which would corrupt the heap lead now to access violation and are easily seen in the the debugger.
  • disable page heap once debugging is done, e.g.:
    C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\gflags.exe" -p /disable exe_to_debug.exe  
    
like image 36
ead Avatar answered Oct 19 '22 07:10

ead