5

After some resource modification (an image), my program has been getting random crash (0xC0000005). I know these come from bad memory management, but I can't find where it comes from, because of two reasons: first, I don't use alot of pointers or dynamicaly allocated variables manually (I mean I use the standard library which does it for me), and second, the bug doesn't happen when I'm debugging with gdb (but it does appear when running the debug build, without gdb).

I tried to pinpoint the bug with sd::cout, but I still can't find it due to the way my program is written. I double, triple-checked the pointers and dynamic arrays I use, still can't find it. For info, debug is compiled with "-g -std=c++14", but no "-O2". I use Code::Block with a 64bit MingW with GCC 5.1.0 and gdb 7.9.

So, I read alot of things of those type of bug (0xC0000005) and Heisenbug, but I don't know understand how to deal with it, I don't know what to try now.

I'd show you the code, but it's spread across 30 files. If you really want to see, it's here on github though.

Also, you won't be able to test it out because I didn't upload the resource files (I don't own them).

So do you have any suggestion for me to be able to find where the bug comes from ?

Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
Corentin M
  • 107
  • 10
  • 1
    If it appears in a debug build, without gdb, can you generate a core file? – Pace Dec 11 '15 at 22:32
  • 2
    Both [gcc](http://stackoverflow.com/q/20738232/1708801) and [clang](http://stackoverflow.com/q/22699881/1708801) have sanitizers which may catch this. Also [valgrind is another option](http://stackoverflow.com/q/28211746/1708801). – Shafik Yaghmour Dec 11 '15 at 22:35
  • 2
    Don't thank the alot, thank the people who answer your question! – Kerrek SB Dec 11 '15 at 22:36
  • 1
    1) enable and fix all compiler warnings. 2) run the program through Valgrind and ASAN. – Kerrek SB Dec 11 '15 at 22:37
  • @Pace I have no idea how to do that, I practicaly never used the debugger before... I'm looking that up right now! – Corentin M Dec 11 '15 at 22:37
  • @KerrekSB The only warnings are comparison between unsigned and signed integer, which I believe are not harmfull in my case, right ? – Corentin M Dec 11 '15 at 22:39
  • 1
    Does your code compile with zero warnings? Even after you turn all the warnings on? `-Wall -Wextra -pedantic -Werror`. It sounds like some variables are not initialized (in debug they will default to zero but in release mode they will be indeterminate). Anyway reading from an un-initialized variable is undefined behavior. Fix all the warnings see if you still have a problem. – Martin York Dec 11 '15 at 22:45
  • 1
    This is a perfect question for Programmers.SE, as far as I can tell. Without an MCVE, it doesn't really belong here. – Lightness Races in Orbit Dec 11 '15 at 22:50

2 Answers2

8

Start the program, then attach gdb; if you start a program under a debugger Windows switches to the debug heap, which usually can help to detect memory usage problems, but sometimes hides Heisenbugs (because it actually changes the default content of uninitialized memory).

By starting the program first and then attaching the debugger you avoid this discrepancy between a "normal" run and a "debug" run, thus you should be able to catch the access violation directly in the debugger.

Aside from the "manage to reproduce the crash under a debugger" thing, you may want to use various tools that can help you to detect the bug earlier; recent g++ versions provide tools such as the address sanitizer and the debug STL, which helped me to pinpoint many serious bugs that went unresolved for years.

Incidentally, even when a program is not already under a debugger, Windows offers the possibility to start one of the registered ones in case of a crash, in the usual crash dialog there should be a "Debug" option. It doesn't seem that it's possible to register gdb between the system debuggers, but if you install Visual C++ Express or the Debugging tools for Windows you should at least have some kind of debugger always ready for these occasions (using them to debug g++-generated executables with dwarf debug information instead of PDB is a whole other can of worms, though).

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • Thanks, I think I'm on to something. attaching the program to gdb after its launch showed me two segmentation fault.Sadly, the exact line they point is in stl_pair.h, a standard header. But I think I know more or less where the error comes from nom ! – Corentin M Dec 11 '15 at 22:55
  • 2
    @CorentinM: use the `bt` command to get a backtrace and pinpoint where in your program was that code called. – Matteo Italia Dec 11 '15 at 22:56
  • Sorry to revive an old post, but does this apply to profilers as well? I am having a severe performance Heisenbug which simply vanishes when I start my application with dotTrace. Not sure though if profilers do change things the same way as a debugger does when launching it straight with a profiler instead of attaching. – SharpShade Jun 10 '20 at 09:46
  • @SharpShade: not through the same mechanisms, but it can happen. In particular, I see that dotTrace has various modes of working: the sampling profiling should be the least disturbing to your program, given that it samples "from the outside" and with a relatively coarse time interval. Of course it's still influencing your machine and in some way the execution of your program, but it should be light enough. The other two profiling modes instead add instrumentation to your code, and that can for sure alter its performance characteristics. – Matteo Italia Jun 10 '20 at 16:17
  • Okay thank you Matteo. If I remember correctly the last time I tried every type but always started the application through dotTrace instead of trying to append it. – SharpShade Jun 11 '20 at 09:51
0

Often, it is too late for a useful memory dump when a program actually crashes. Data-corruption might have happened a long time ago.

I would use valgrind to detect invalid memory access early. This does not discover all kinds of data corruption, but at least almost anything which has to do with illegal reads and writes (buffer overflows, uninitialized reads, etc).

This has already helped me a lot with "heisenbugs"

Ctx
  • 18,090
  • 24
  • 36
  • 51