代码之家  ›  专栏  ›  技术社区  ›  Dominique

如何解释Windbg“x/2”结果中的双条目?

  •  0
  • Dominique  · 技术社区  · 7 年前

    我正在调试一个转储文件(内存转储,而不是崩溃转储),它似乎包含的对象数量是预期的两倍。在研究相应的符号时,我注意到以下几点:

    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'
    

    请参考以下条目 Current_Object Current_ObjectID 代码中存在,没有问题。

    我不明白的是,每个符号似乎有两个条目,它们的内存地址彼此非常接近。

    有人知道我怎么解释这个吗?

    1 回复  |  直到 7 年前
        1
  •  1
  •   blabb    7 年前

    这可能是由于各种原因,优化和冗余代码消除在链接时是一个原因(pdb通常在编译时进行) see this link by raymond chen 有关概述

    引用链接中的相关段落

     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." 
    
    推荐文章