Discussion:
Debugger showing wrong info in release mode
(too old to reply)
ceh
2008-05-16 14:36:44 UTC
Permalink
My vs 2005 c++ debugger is screwy in release mode, debug mode is fine.
This just started yesterday out of no where.
Does anyone know of this? Is there a setting I toggled by accident
somewhere?

Memory is fine, but debugger shows wrong data in both watch and memory
windows

UNICODE is not defined.
If it is, then the correct data starts at sBuf[2], rather than 4

For some buffer, eg TCHAR sBuf[16]

_tcscpy( sBuf, _T("foobar") );

would show this in debug

sBuf[0] = junk
sBuf[1] = junk
sBuf[2] = junk
sBuf[3] = junk
sBuf[4] = 'f'
sBuf[5] = 'o'

but if you iterate over the buffer and print it, it's correct

sBuf[0] = 'f'
sBuf[1] = 'o'
sBuf[2] = 'o'
sBuf[3] = 'b'
sBuf[4] = 'a'
sBuf[5] = 'r'


// code start
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR sBuf[16];

_tcscpy( sBuf, _T("foobar") );

for( int i=0; i<16; i++ )
{
_tprintf( _T("sBuf[%d] = %c\n"), i, sBuf[i] );
}

_tprintf( sBuf );

return 0;
}
// code end

Thanks for any insight
David Lowndes
2008-05-16 16:33:49 UTC
Permalink
Post by ceh
My vs 2005 c++ debugger is screwy in release mode, debug mode is fine.
It's perfectly normal to get odd debugger behaviour in an optimised
release build. Code can get changed drastically, variables get left in
registers and not stored in memory.
Post by ceh
...
but if you iterate over the buffer and print it, it's correct
All that matters is that the end result is correct!

Dave
ceh
2008-05-20 01:00:20 UTC
Permalink
Post by David Lowndes
Post by ceh
My vs 2005 c++ debugger is screwy in release mode, debug mode is fine.
It's perfectly normal to get odd debugger behaviour in an optimised
release build. Code can get changed drastically, variables get left in
registers and not stored in memory.
Post by ceh
...
but if you iterate over the buffer and print it, it's correct
All that matters is that the end result is correct!
Dave
I'm aware of those things, I guess, I'm just a bit shocked how far off
this simple scenario is.
And I've never run into such a drastic example of the problem before.

Thanks.
Jon Pfeffer
2008-05-20 12:04:16 UTC
Permalink
Post by ceh
Post by David Lowndes
Post by ceh
My vs 2005 c++ debugger is screwy in release mode, debug mode is fine.
It's perfectly normal to get odd debugger behaviour in an optimised
release build. Code can get changed drastically, variables get left in
registers and not stored in memory.
Post by ceh
...
but if you iterate over the buffer and print it, it's correct
All that matters is that the end result is correct!
Dave
I'm aware of those things, I guess, I'm just a bit shocked how far off
this simple scenario is.
And I've never run into such a drastic example of the problem before.
Thanks.
This is a topic I find interesting. It takes more time to read the
disassembly window and register windows to figure out variable values
when the debugger is reporting wrong ones. There are lots of internet
links on the subject, but none of them I found so far are close to
complete. No books cover the topic in detail.

Effects of optimization on Debugging?
- Optimizer repositions and reorganizes instructions, resulting in
more efficient compiled code.
- Debugger often cannot identify the source code that corresponds
to a set of instructions
- Local variables – often removed or moved to locations the
debugger does not understand
- Positions inside a function – changed when blocks of code are
merged
Function names for frames on call stack – may be wrong if two
functions merged
- Frames on the call stack are almost always right – if you have
correct symbols
- Are wrong if stack corruption, functions written in assembly
language, or OS system frames without matching symbols on the call
stack
Global and static variables and structure layout are always shown
correctly
- Therefore a pointer to a structure (with correct value), will
show every member variable of the structure with correct value.

Optimizing compilers often use techniques like as follows:

Clearing a register value by xor reg (2 op code bytes) instead of mov
reg, 0 (say 5 op code bytes)
- Reduces code size which reduces expensive page faults
Constant zero register
- Compiler will sometimes dedicate an entire register to contain
the value zero throughout most of the function
xor esi, esi ; First clear the register
to 0
cmp [ebp+var_14], esi ; Now use that register for many
subsequent operations
Fast multiplication or addition with the lea instruction
other_local = some_local * 10 + X - 0x30; // C++
line of code
lea eax, [eax+eax*4]
lea eax, [ecx+eax*2-30h] ;
use lea instead of mul, add, and sub
Scaling array indices to their native type with the lea instruction
- E.g. indexing into an array of structures

Here is a few of the many useful links I've found:

MSDB Visual Studio 2008 Developer Center: http://msdn2.microsoft.com/en-us/library/606cbtzs.aspx
Intel 64 and IA-32 Architectures Software Developer’s Manual:
http://download.intel.com/design/processor/manuals/253665.pdf
Prefer Debugging with Release builds: http://www.nynaeve.net/?p=184
Surviving the Release Version: http://www.codeproject.com/KB/debug/cdbntsd7.aspx
Optimization – your worst enemy: http://www.codeproject.com/KB/tips/optimizationenemy.aspx
Debugging Release Mode Problems: http://www.codeproject.com/KB/debug/releasemode.aspx

Regards,
Jon

Loading...