1

I wrote a C++ CLI program with MS VC++ 2010 and GCC 4.2.1 (for Mac OS X 10.6 64 bit, in Eclipse). The program works well under GCC+OS X and most times under Windows. But sometimes it silently freezes. The command line cursor keeps blinking, but the program refuses to continue working.

The following configurations work well: GCC with 'Release' and 'Debug' configuration. VC++ with 'Debug' configuration

The error only occurs in the configuration 'VC++ with 'Release' configuration' under Win 7 32 bit and 64 bit. Unfortunately this is the configuration my customer wants to work with ;-(

I already checked my program high and low and fixed all memory leaks. But this error still occurs. Do you have any ideas how I can find the error?

Moshe Katz
  • 15,992
  • 7
  • 69
  • 116
John Doe III
  • 13
  • 2
  • 6
  • 1
    Have you tried attaching a debugger to the running application? You can still debug an app compiled in "Release" mode. That will give you some idea of what section of the code is causing the problem. This is basically impossible for us to debug remotely, using our crystal balls. – Cody Gray - on strike May 25 '12 at 10:22
  • 1
    Take a look at [this link](http://www.flounder.com/debug_release.htm). It discusses the differences between release and debug versions and how to resolve many of the issues that may arise. – MikMik May 25 '12 at 10:28
  • @Cody Gray: good suggestion. In fact, it's not even necessary to run the program inside a debugger / attach a full-featured debugger. Just stack traces obtainable e.g. with SysInternals Process Explorer at the point where it's frozen may provide a reasonable starting point. – FrankH. May 25 '12 at 14:46

3 Answers3

1

Debug versions usually initialize all allocated memory (MSVC fills them with 0xCD with the debug configuration). Maybe you have some uninitialized values in your classes, with the GCC configurations and MSVC Debug configuration it gets a "lucky" value, but in MSVC Release it doesn't.

Here are the rest of the magic numbers used by MSVC.

So look for uninitialized variables, attributes and allocated memory blocks.

Community
  • 1
  • 1
wrock
  • 1,349
  • 9
  • 9
  • This is all true enough, but doesn't really explain why the "Debug" version with the magic values *doesn't* crash. The point of filling with sentinel values is so that you can more easily debug the problem. `0xCD` doesn't actually point to a valid location in memory, so if this was the problem, you'd still get a hard crash. In fact, you're *guaranteed* to get one so you can debug it; that's the whole point. – Cody Gray - on strike May 25 '12 at 10:24
  • 1
    We know nothing about the code. The pointers might be properly initialized, but some scalars aren't, and suppose you use them as an index to an array. It happened to me once :) – wrock May 25 '12 at 11:05
  • @CodyGray: There is nothing that would guarantee `0xcdcdcdcd` to be invalid pointer, though it is rather unlikely to be. It won't be equal to anything ever returned by malloc/new, because it's not aligned, but it might not always cause crash. – Jan Hudec May 25 '12 at 11:14
1
  • Use logging to narrow down which part of code the program is executing when it crashes. Keep adding log until you narrow it down enough to see the issue.
  • Enable debug information in the release build (both compiler and linker); many variables won't show up correctly, but it should at least give you sensible backtrace (unless the freeze is due to stack smashing or stack overflow), which is usually enough if you keep functions short and doing just one thing.
  • Memory leaks can't cause freezes. Other forms of memory misuse are however quite likely to. In my experience overrunning a buffer often cause freezes when that buffer is freed as the free function follows the corrupted block chains. Also watch for any other kind of Undefined Behaviour. There is a lot of it in C/C++ and it usually behaves as you expect in debug and completely randomly when optimized.
  • Try building and running the program under DUMA library to check for buffer overruns. Be warned though that:
    • It requires a lot of memory. I mean easily like thousand times more. So you can only test on simple cases.
    • Microsoft headers tend to abuse their internal allocation functions and mismatch e.g. regular malloc and internal __debug_free (or the other way 'round). So might get a few cases that you'll have to carefully workaround by including those system headers into the duma one before it redefines the functions.
  • Try building the program for Linux and run it under Valgrind. That will check more problems in addition to buffer overruns and won't use that much memory (only twice as normal, but it is slower, approximately 20 times).
Jan Hudec
  • 73,652
  • 13
  • 125
  • 172
0

Thank you all, especially Cody Gray and MikMik, I found it! As some of you recommended I told VS to generate debug information and disabled optimizations in the release configuration. Then I started the program and paused it. Alternatively I remotely attached to the running process. This helped me finding the region where the error was. The reasons were infinite loops, caused by reads behind the boundaries of an array and a missing exclusion of an invalid case. Both led to unreachable stopping conditions at runtime. The esoteric part came from the fact, that my program uses some randomized values. That's life...

John Doe III
  • 13
  • 2
  • 6