Hi, I have an error here that gave me some headache. My program worked fine in the de bug build. But if I build it in the optimized / release build, it crashes somewhere in the middle of the program. How can i fix that?
Hi, I have an error here that gave me some headache. My program worked fine in the de bug build. But if I build it in the optimized / release build, it crashes somewhere in the middle of the program. How can i fix that?
Well, you see, that's the problem. I don't know exactly which part of my code that went wrong. The debug build runs smoothly. I can't debug the error because it's in release / optimized version. So, I'm asking can anybody give me some sugestion about what to do? BTW, what's the difference of debug and release besides the optimization? How can that make the program faulty in release but not in debug?Originally Posted by Osaou
> what's the difference of debug and release besides the optimization?
For correct programs, nothing at all except the speed with which it runs.
For buggy programs, all sorts of fun can happen.
> How can that make the program faulty in release but not in debug?
Assuming that uninitialised variables have a value is one cause.
Other things include
- assuming that arrays have a particular amount of "dead" space at the end
- assuming that allocated memory has a particular amount of "dead" space at the end
- assuming the order of variable declarations matters
- assuming the packing of structures is the same
Debug often pads the end of allocated memory to allow easy traps of off-by-one overwrites (for example). Try enabling such tools to see if you have any of these.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
Salem has described most of the common reasons for a program that runs fine when in "debug' (i.e. optimiser turned off) and crashes in release (optimiser turned on). Some less common reasons are compiler bugs (the optimiser is typically a fairly complex bit of code). There is also the fact and that some optimisers (depending on setting) merge duplicated data into one copy (eg if a string literal "Hello" is used twice in a function, the compiler makes both usages refer to the same data) which can confuse some functions which do obscure pointer arithmetic. An aggresive optimiser can also eliminate some variables, by reusing other variables. One symptom of this one is that adding additional I/O statements can make the problem go away (as fetching a value and outputting a variable reduces some choices the optimiser has to rearrange things).
Another common cause is a combination of multiple interacting bugs in the program. For example, functionA() falls off the end of an array and molests data it shouldn't, functionB() subsequently uses that data as an array index, and molests some other data and crashes. In this example, the problem is in functionA(), but the poor old programmer can wind up doing a lot of head-scratching while looking at functionB().
The various strategies for finding the cause (or causes) of such issues are tedious. Salem has suggested using various debugging tools (which can still be used, even in release mode, but it is more difficult to track back to the offending code). Another approach is to break down the program into pieces, and test the pieces. For example, comment out some calls to functions to main(), and see which ones (when commented out) cause the problem to disappear. The thing that makes it tedious is those interacting functions.
Weird. I only added a "cout" of two variables and the problem was solved. How funny is that? :?
EDIT: It gets funnier. After it worked for a while, the problem arises once more.
Okay, the problem is in a getter function. The getter function is used to get the current animation state whether it is still playing or stopped. In the debug, the getter returned either true or false (which is the supposed output). But in the release, it always returned 64. The current value itself in the animation object is true because it stopped when it supposed to stop. But when I wanted to get this value (to know if the animation is stopped or still being played) it always returned 64. Dunno where the hell did that value come from.
Last edited by g4j31a5; 10-10-2006 at 01:11 AM.
Problem solved. Forgot to add "return" in the getter. Actually, this error should've showed up in debug also (not returning a value when it should). But how come it didn't? Or maybe gcc is too permissive with boolean return value in the debug mode?
> Or maybe gcc is too permissive with boolean return value in the debug mode?
Or maybe you should turn up the warning level and pay attention to what it tells you.
Falling off the end of a non-void function usually gets a warning message where I am.
$ gcc -W -Wall -ansi -pedantic foo.c
foo.c: In function `foo':
foo.c:5: warning: control reaches end of non-void function
If you don't return a value, you just get any old rubbish. Sometimes, this is actually the result of your last calculation (which may be what you wanted).
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
That's actually a very good point, and probably something that should be done before bringing the debuggers in or cutting code out of a program.Originally Posted by Salem
By default, most compilers are fairly permissive in terms of what they allow to sail past. And the good compilers have settings that can make them become VERY picky.
In contrast, too many programmers look for ways to make the compiler complain less (eg turning off warnings) or assume things are OK if an executable is built despite the warnings. I've certainly been in teams where colleagues have wasted a few days trying to track down a problem. And it has turned out that the compiler had nagged them about the problem, and they had ignored the "irrelevant" warning.
Basic fact of life is that, if a compiler complains about some code construct, there is usually a better way of doing it. There are some cases where warnings are meaningless, but those are not that common.
Feeding code into another compiler is also a good way to find problems, unless you are using a compiler-specific library. Different compilers complain about different things, so using multiple compilers (all configured to be as picky as possible) is a good way to identify basic coding problems.
> $ gcc -W -Wall -ansi -pedantic foo.c
The 4 best friends of any coder. And if one really wants to be mean (read do a favor) to himself, then -Werror for all those warnings to not go unnoticed.
I would perhaps suggest -Wextra instead of -W. The trend is for the former to replace the latter. No biggy though.
Originally Posted by brewbuck:
Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.
-Weffc++ is another good one. It makes sure you aren't using very much that is depreciated in your code.