Search code examples
windbgdumpdebug-symbols

How to interprete double entries in Windbg "x /2" result?


I'm debugging a dumpfile (memory dump, not a crashdump), which seems to contain two times the amount of expected objects. While investigating the corresponding symbols, I've noticed the following:

0:000> x /2 <product_name>!<company>::<main_product>::<chapter>::<subchapter>::<Current_Object>*
012511cc          <product_name>!<company>::<main_product>::<chapter>::<subchapter>::<Current_ObjectID>::`vftable'
012511b0          <product_name>!<company>::<main_product>::<chapter>::<subchapter>::<Current_ObjectID>::`vftable'
01251194          <product_name>!<company>::<main_product>::<chapter>::<subchapter>::<Current_Object>::`vftable'
0125115c          <product_name>!<company>::<main_product>::<chapter>::<subchapter>::<Current_Object>::`vftable'

For your information, the entries Current_Object and Current_ObjectID are present in the code, no problem there.

What I don't understand, is that there seem to be two entries for every symbol, and their memory addresses are very close to each other.

Does anybody know how I can interprete this?


Solution

  • it can be due to veriety of reasons Optimizations and redundant code elimination being one at the linking time (pdb is normally made when you compile) see this link by raymond chen for an overview

    quoting relevent paragraph from the link

     And when you step into the call to p->GetValue() you find yourself in Class1::GetQ.    
    What happened?
    
    What happened is that the Microsoft linker combined functions that are identical    
    at the code generation level.
    
    ?GetQ@Class1@@QAEPAHXZ PROC NEAR    ; Class1::GetQ, COMDAT
      00000 8b 41 04         mov     eax, DWORD PTR [ecx+4]
      00003 c3               ret     0
    ?GetQ@Class1@@QAEPAHXZ ENDP         ; Class1::GetQ
    
    ?GetValue@Class2@@UAEHXZ PROC NEAR  ; Class2::GetValue, COMDAT
      00000 8b 41 04         mov     eax, DWORD PTR [ecx+4]
      00003 c3               ret     0
    ?GetValue@Class2@@UAEHXZ ENDP       ; Class2::GetValue
    
    Observe that at the object code level, the two functions are identical.   
    (Note that whether two functions are identical at the object code level is 
    highly dependent on which version of what compiler you're using, and with    
    which optimization flags. Identical code generation for different functions
     occurs with very high frequency when you use templates.) Therefore, the    
    linker says, "Well, what's the point of having two identical functions? I'll   
    just keep one copy and use it to stand for both Class1::GetQ and    
     Class2::GetValue."