8

I have an application that runs just fine in the debug build, but when I start it in the release build, I get a

unhandled Exception at 0x0043b134 in myapp.exe: 0xC0000005:
Access violation while reading at position 0x004bd96c

If I click on 'break' it tells me that there are no symbols loaded and the source code can't be displayed.

What can I do in such a situation to track down the problem?

Bart
  • 9,825
  • 5
  • 47
  • 73
Mat
  • 2,713
  • 5
  • 25
  • 25
  • This sometimes occurs because of memory issues. Often release builds are less forgiving in this area. Could your program maybe have memory leaks, buffer overflow problems, etc? – Cam Oct 25 '10 at 07:12
  • 1
    Looks like you've deleted something, but try to use it. Is there anyway you can actually post some code? We can't do anything if you don't tell us what you're doing. – GManNickG Oct 25 '10 at 07:14
  • the application is huge - don't even know what portion of code i could post since i've got no idea where the error happens – Mat Oct 25 '10 at 07:17
  • Unless you're able/prepared to do assembly level debugging, the version control idea from Daniel below is probably best. – Zooba Oct 25 '10 at 07:18
  • 10
    When this happens to me, I usually head to the bar early... – James McNellis Oct 25 '10 at 07:28
  • if I ACTIVATE "generate Debug info /DEBUG" in the Linker settings in RELEASE mode, then it doesn't crash in release. If I DEACTIVATE "generate Debug info" in DEBUG mode, then it still does not crash in debug mode. – Mat Oct 25 '10 at 07:56
  • 5
    This is usually caused because the debug build will initialize variables that you have not explicitly initialized. When you build in release mode these variables now contain a random value rather than the nice neat 0 (NULL) value that debug mode set for you. To fix this set the compiler warnings to a higher level and fix all the warnings (especially the ones that mention uninitialized variable). PS. Warnings are usually a problem so always fix them and always set the compiler warning level to max. – Martin York Oct 25 '10 at 08:07
  • @Martin: Except in VS, don't do `/Wall`, do `/W4` (which used to be max). `/Wall` is *stupid*, I was surprised when I first tried it. Beware! – GManNickG Oct 25 '10 at 17:53
  • Yes. I just tried that. The old max on VS was 4 and hence my project templates were all set to 4 so that new projects automatically inherited this level (the original templates had a level of 3). I just looked for the first time in years at this setting and there is a new higher level. The number of errors is ridiculous and a lot seem to come from standard libs which is a real pain. – Martin York Oct 25 '10 at 18:06
  • Please read the discussion here: http://stackoverflow.com/questions/312312/what-are-some-reasons-a-release-build-would-run-differently-than-a-debug-build – Sampath Jun 27 '16 at 14:16
  • Please read this article: http://www.codeproject.com/Articles/548/Surviving-the-Release-Version – Sampath Jun 29 '16 at 06:18

10 Answers10

12

This kind of problem is often due to unitialized variables. I'd start there looking for your problem.

Debug mode is more forgiving because it is often configured to initialize variables that have not been explicitly initialized.

Perhaps you're deleting an unitialized pointer. In debug mode it works because pointer was nulled and delete ptr will be ok on NULL. On release it's some rubbish, then delete ptr will actually cause a problem.

Montdidier
  • 1,181
  • 1
  • 8
  • 21
  • that sounds reasonable! can I tell Visual Studio not to initialize variables in debug build? – Mat Oct 25 '10 at 07:29
  • I activated /RTCu (non initialized variables) in my debug build - shouldn't this nag if there were any uninitialized variables? – Mat Oct 25 '10 at 07:32
  • yes in most cases, however not in all cases. If a pointer could have been initialized by other means, this check is ignored. In practice you might be have used the address-of & operator and initialized the variable via pointer. So it still might be missing an initialization and not producing a warning. See http://msdn.microsoft.com/en-us/library/8wtf2dfz.aspx – Montdidier Oct 25 '10 at 12:21
4

It could be two things:

  • One or more of your assertions does necessary work apart from the check itself
  • Something else

To rule out the former, try redefining assert as an empty operation in the debug build. If the absence of some assertion causes the crash, you will see it. Otherwise, it's something else.

Also, I assume you have version control. Did this just start happening? You can analyze the code changes from last week.

Finally, even in the absence of a crash in debug mode, running a memory checker tool may be useful to spot incorrect memory access.

Daniel Daranas
  • 22,454
  • 9
  • 63
  • 116
  • I use versioning control for all my projects except for that one since this particular machine i'm developing on is not connected to the internet :/ silly me... i redefined assert to do nothing and it does not crash in debug build. i'll google 'memory checker tool' - can you recommend one? – Mat Oct 25 '10 at 07:25
  • @Mat: Consider also @Grozz's suggestion of using log output. This will certainly put some light into it. – Daniel Daranas Oct 25 '10 at 07:45
  • @Mat: And about memory checking, see http://stackoverflow.com/questions/1010106/how-to-debug-heap-corruption-errors, http://stackoverflow.com/questions/167199/what-c-c-tools-can-check-for-buffer-overflows, http://stackoverflow.com/questions/638090/profiling-c-multi-threaded-applications and similar questions. – Daniel Daranas Oct 25 '10 at 07:47
3

Are you sure that both releases use the same .dll ? I spend an hour wondering why my program did compile in debug mode but not in release mode and I just forgot to update the dll's in the release folder.

mart
  • 41
  • 3
3

Two steps:

a) Build release build with debug symbols (possible with VS at least)

b) Build release build without optimization

If the problem still happens, it is very good and easy to fix. It is almsot as if the problem is in debug build.

If the problem happens with optimization settings on, then it is really tough and has to be handled in situation specific manner.

Chubsdad
  • 24,777
  • 4
  • 73
  • 129
  • if I build the release with debug symbols, it doesn't crash – Mat Oct 25 '10 at 08:01
  • @Mat: that is _very_ weird, as the binary should (for all purposes) be identical. The main difference is that the "debug symbols" option creates a separate .PDB file describing the relation between memory addresses and functions/variables. I.e. that should tell you what was at the address `0x0043b134` or the address `0x004bd96c`. – MSalters Oct 25 '10 at 09:29
  • @MSalters: I think the reason is that release binaries are always built with some optimization (/O2 e.g.). I suspect it has got to do with optimization flags. – Chubsdad Oct 25 '10 at 10:32
  • 1
    the claim here is that a "normal" release build crashes, but not a release build with symbols. That is weird, becuase both builds should have the same optimization flags etc. However, I did just notice that `/DEBUG` implies `/OPT:NOREF, /OPT:NOICF`; the documentation states that you need to set them explicitly for a release build with debug information. Those two flags would be my prime suspects now. – MSalters Oct 25 '10 at 11:57
1

I had this problem, release/debug worked fine inside visual studio, debug work stand alone, but release crashed stand alone. Debugging was not particularly accurate for me, my solution was:

Comment out most of the code, then build, test, uncomment, repeat, until you find the section that causes the crash.

In my case it was passing a pointer to an array that was too small to a function.

StanOverflow
  • 557
  • 1
  • 5
  • 21
1

Track down the problem inserting log output here and there right from the beginning of the main function.

Grozz
  • 8,317
  • 4
  • 38
  • 53
1

If it is not a memory issue, then you have to enable asserts in the release. For memory issues, I hope you got good unit tests. You can easily catch such problems with valgrind.

btw why are people disabling asserts in the release version? In 99% cases they do not cause performance problems, and are good in detecting errors.

BЈовић
  • 62,405
  • 41
  • 173
  • 273
1

Take a crash dump using Microsoft debugdiag on windows(it's free) and analyze the dump using the same. It gives a nice call stack for the function where it crashes. Although, if it keeps crashing all over the place, it could be an issue of heap corruption. You then need to use global flags(or gflags which is a part of microsoft tools for debugging suite which is free) in conjunction with debugdiag. Gflags would give you the location where the heap is actually getting corrupted. Hope that helps.

Samrat Patil
  • 788
  • 5
  • 23
0

For me, the problem was that a constructor was initializing 2 member variables in the wrong order. i.e. not the same order that they were declared in.
I'm surprised that initialization order actually makes any difference.

0

Without looking at the code, it is hard to tell what is bad. All the above suggestions are good and helpful but what I have found most helpful fixing this kind of things is to run certain parts of program in chunks. i.e., comment out a lot of code/functionality and then run the program and see if it crashes. If it doesn't, the uncomment some functionality and then re-run again and so on. This way you will be able to narrow down the problem to the exact code that is causing this.

In most of the cases this happens due to some Buffer overruns which Debug builds can guard against.

Aamir
  • 14,882
  • 6
  • 45
  • 69