>> What version of the compiler are you using? Can you describe the
>> taxonmy and structure of the CtTracker class and the class where the
[quoted text clipped - 11 lines]
> although to be honest I don't understand that. Neither function is
> static.
Non-leftmost refers to the order of inheritance in a multiple inheritance
case. No MI - no non-leftmost bases.
> I suspect I'm stomping on memory somewhere in the "past". I ran the
> case through Rational Purify hoping to detect the stomping, but came
> up empty. I will try compiler option /RTCsu with which I am
> presently unfamiliar.
> Let me ask this question:How do I determine if stack corruption is
> taking place?
It's hard.
> Possible answer:
> Watch register ESP. If it changes while stepping through a function,
> you've got stack corruption.
ESP or EBP or the contents of the stack itself could be modified. Normally,
it's the contents of the stack that get modified, then on returning from a
function, an incorrect value of EBP gets picked up off the corrupted stack,
followed shortly by fireworks as your program blows holes in itself.
> Possible follow up question:
> Should changes in ESP be visible in the "disassembly" view?
Yes, it's visible in the Registers window along with all the others.
Debug|Windows|Registers from the menu or Ctrl-Alt-G from the keyboard if the
reigsters window isn't visible.
> etc. etc.
>
[quoted text clipped - 3 lines]
> are not changing while the function is executing. Disassembly does
> not show the offset values (I think).
The offsets are hard-wired into the code by the compiler, and may change
from point to point depending on calling patterns and optimization level.
Normally, in debug builds, all locals are accessed using offsets from EBP
and those offsets are fixed. However, in an optimized build, the compiler
may choose to not use EBP and reference variables directly off ESP. In this
case, the offset to a variable might be different at two points in a single
function if the compiler has pushed parameters for a function call, or
spilled temporary values to the stack. The compiler keeps track of
everything it's put on the stack at each point and will generate the correct
offset(s), but it can make the disassembly a bit hard(er) to follow.
> This is the "systematic" way I would like to go about solving this
> problem (I think).
>
> PS: When my local variable addresses change, ESP does not change.
How do you conlucde that the address changes?
Are you debugging an optimized build, or a debug build?
-cd
Chris Stankevitz - 15 Jun 2005 21:51 GMT
>> Should changes in ESP be visible in the "disassembly" view?
>
> Yes, it's visible in the Registers window along with all the others.
> Debug|Windows|Registers from the menu or Ctrl-Alt-G from the keyboard if
> the reigsters window isn't visible.
That wasn't quite my question, although the point is moot since ESP is not
changing in my case. What I was trying to ask was "What should one think if
ESP changed, but the corresponding assembly instruction did not reference
ESP? Is that even possible?"
> How do you conlucde that the address changes?
Watch window before F10:
dt = 100.0
&dt = 0x8812ab12 (Notional)
Watch window after F10:
dt = 3.12124554e-300
&dt = 0x125484ba (Notional)
Results consistent with small value of dt. More on that below.
> Are you debugging an optimized build, or a debug build?
unoptimized "debug" build.
There have been two important developments in the case. As I was trying to
make screenshots to illustrate the example I produced above, I found...
1. the bad behavior (local var addresses changing [LVAC]) stopped.
Yesterday it was repeatable, but not today.
2. I had a logic error which led me into the debugger and to the LVAC issue.
It may have be that LVAC is just a "debugger" issue. My logic error
produced results consistent with a very small value of dt - which further
convinced me that LVAC was really happening.
I should have (and next time I will):
cout << &dt << endl;
f();
cout << &dt << endl;
Thanks a million for your help guys,
Chris