views:

388

answers:

2

Hi everyone,

Look at this screenshot of a Visual C++ debugger session:

The execution point is now inside a virtual function. "mDb" is a reference to an object which is the member of that class. "mDb" has the type CDbBackend&. There is only one thread. The values in the red rectangles should be equal, ... but they're not. How can this be possible?

The code being debugged has been instrumented with BoundsChecker (a memory debugger and profiler). The discrepancy leads to a crash later on. Non-instrumented code doesn't lead to any of these effects. I think it's too early to blame BoundsChecker - it could well be a hidden bug in my program which BoundsChecker has revealed, which is why I'm very inclined to understand the situation.

The assembly generated for the "b = &mDb" statement is as follows, in case it's relevant. Stepping thhrough this assembly, with watch and registers visible, is captured here (500kb avi file).

007AB7B0  push        4    
007AB7B2  push        80000643h 
007AB7B7  push        4    
007AB7B9  push        0C0002643h 
007AB7BE  lea         eax,[ebp-10h] 
007AB7C1  push        eax  
007AB7C2  call        dword ptr [_numega_finalcheck_C_110456 (8FA8A8h)] 
007AB7C8  mov         eax,dword ptr [eax] 
007AB7CA  add         eax,1CCh 
007AB7CF  push        eax  
007AB7D0  call        dword ptr [_numega_finalcheck_C_110456 (8FA8A8h)] 
007AB7D6  mov         dword ptr [ebp-70h],eax 
007AB7D9  push        dword ptr [ebp-70h] 
007AB7DC  push        4    
007AB7DE  push        50000643h 
007AB7E3  lea         eax,[ebp-20h] 
007AB7E6  push        eax  
007AB7E7  call        dword ptr [_numega_finalcheck_Y_110456 (8FA8ECh)] 
007AB7ED  mov         ecx,dword ptr [ebp-70h] 
007AB7F0  mov         ecx,dword ptr [ecx] 
007AB7F2  mov         dword ptr [eax],ecx

Thanks!

Yaroslav

A: 

Is mDb also of type CDbBackend? If not, then discrepancy is due to casting.

Given:

class A
{
  // Stuff
};

class B : public A
{
  // More stuff
};

B *b = new B;
A *a = (A *)&b;

then b and a might or might not be equivalent depending on what exactly "Stuff" and "More Stuff" are. The biggest things that will change the pointer castings are virtuals and multiple inheritance. If this is the case in your example then your debugger's output is correct and normal behavior. If you expand the class view for mDb, I wouldn't be surprised if you find a CDbBackend pointer contained within it that matches your second output below.

Russell Newquist
+1  A: 
  1. Please rebuild and test it again. (I know it sounds stupid :)

  2. The code is compiled in debug mode w/o any optmizations, right? I guess so. But, in the disassembly, no symbolic information is presented. I can only see [ebp - offset]; this should be represented as some symbolic name such as b. Be sure turn on "Show symbol names" in disassembly view.

  3. I'm not sure the disassembly code you pasted are the code for b = &mDb. It looks like [ebp-10h] or [ebp-70h] would be b, but mDb does not seem to be here. All the code in here just is calling instrumented function. Could you give more disassembly with source code around them?

  4. I have an experience where debugging information is incorrectly generated, so symbolic debugging gave an incorrect value. My workaround was that changing member variable layout and putting some padding in local stack. But, I'm not sure that this was a really compiler's bug. I was working on Visual Studio 2008 with Intel C/C++ compiler, and the project was pretty complex.

The information is somewhat insufficient to resolve this problem. It would be better if you give more disassembly.

minjang
1. Doesn't sound so stupid, but I've tried it many times already, to no avail.2. Yes, debug and no optimizations. Regarding symbol substitution: that's how disassembly always looked for me... I don't remember any debugger substitute registers and addresses with symbols - it doesn't always make sense. "Show symbol names" is on.3. I'm sure it is the right disassembly. Please take a look yourself: I captured a video stepping through the disassembly of both instrumented and uninstrumented code. The videos are at http://yp.lviv.ua/tmp . Thanks!