VC++ 如何处理局部静态变量名? [英] How does VC++ mangle local static variable names?

查看:50
本文介绍了VC++ 如何处理局部静态变量名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的一些代码:

MyClass* MyClass::getInstance(){静态 MyClass 实例;返回和实例;}

我想查看这个单身人士的当前值.但是我目前在执行过程中暂停了三个小时,我暂停的原因是我的内存不足.所以我不能在这个方法中放置断点来查看值是什么.

我的问题是如何从全局范围引用这个 instance 变量.我试过将其称为 MyClass::getInstance::instance 但这不起作用.我猜 getInstance 必须以某种方式装饰.有人知道怎么做吗?

这是在 Visual Studio 2008 中.

解决方案

好吧,函数作用域的静态 instance 变量没有出现在 .map 文件中由 cl.exe/Fm 生成,当我在 WinDbg 中使用 x programname!*MyClass* 时它不会显示,因此损坏的名称似乎没有完全包含 MyClass.

选项 1:反汇编 MyClass::getInstance

这种方法似乎更容易:

<前>0:000> uf 程序名!MyClass::getInstanceprogramname!MyClass::getInstance [programname.cpp @ 14]:14 00401050 55 推 ebp14 00401051 8bec mov ebp,esp15 00401053 a160b34200 mov eax,dword ptr [程序名!$S1 (0042b360)]15 00401058 83e001 和 eax,115 0040105b 7526 jne funcstat!MyClass::getInstance+0x33 (00401083)programname!MyClass::getInstance+0xd [programname.cpp @ 15]:15 0040105d 8b0d60b34200 mov ecx,dword ptr [程序名!$S1 (0042b360)]15 00401063 83c901 或 ecx,115 00401066 890d60b34200 mov dword ptr [程序名!$S1 (0042b360)],ecx15 0040106c b9b0be4200 mov ecx,偏移程序名!实例(0042beb0)15 00401071 e88ffffffff 调用程序名!ILT+0(??0MyClassQAEXZ) (00401005)15 00401076 68e03e4200 推送偏移程序名!`MyClass::getInstance'::`2'::`'instance'' 的动态 atexit 析构函数(00423ee0)15 0040107b e8f3010000 调用程序名!atexit (00401273)15 00401080 83c404 添加 esp,4programname!MyClass::getInstance+0x33 [programname.cpp @ 16]:16 00401083 b8b0be4200 mov eax,偏移程序名!实例(0042beb0)17 00401088 5d 流行音乐 ebp17 00401089 c3 ret

由此我们可以看出编译器调用了对象$S1.当然,这个名字将取决于你的程序有多少函数作用域的静态变量.

选项 2:在内存中搜索对象

为了扩展@gbjbaanb 的建议,如果 MyClass 有虚函数,你可能很难找到它的位置:

  • 对进程进行完整的内存转储.
  • 将完整的内存转储加载到 WinDbg.
  • 使用x命令查找MyClass的vtable地址:
<前>0:000> x 程序名!MyClass::`vftable'00425c64 程序名!MyClass::`vftable' =

  • 使用 s 命令搜索进程的虚拟地址空间(在本例中为 0-2GB)以查找指向 MyClass 的 vtable 的指针:
<前>0:000> s -d 0 L?7ffffffff 00425c64004010dc 00425c64 c35de58b cccccccc cccccccc d\B...]........0040113c 00425c64 8bfc458b ccc35de5 cccccccc d\B..E...]......0042b360 00425c64 00000000 00000000 00000000 d\B .....................

  • 使用 dt 命令查找类的 vtable 偏移量,并从搜索返回的地址中减去该偏移量.这些是对象的可能地址.
<前>0:000> dt 程序名!MyClass+0x000 __VFN_table : Ptr32+0x008 x : Int4B+0x010 y : 浮动

  • 使用 dt programname!MyClass 0042b360 检查对象的成员变量,检验对象位于 0042b360(或其他地址)的假设.您可能会得到一些误报,正如我在上面所做的那样,但通过检查成员变量,您可以确定哪个是您的单身人士.

这是一种用于查找 C++ 对象的通用技术,当您可以反汇编 MyClass::getInstance 时,这有点过头了.

Here's some code I have:

MyClass* MyClass::getInstance()
{
   static MyClass instance;
   return &instance;
}

I want to look into this singleton's current values. But I'm currently paused three hours into execution, and the reason I'm paused is that I'm out of memory. So I can't put a breakpoint in this method there to see what the value is.

My question then is how to refer to this instance variable from a global scope. I've tried referring to it as MyClass::getInstance::instance but that doesn't work. I'm guessing getInstance has to be decorated somehow. Anyone know how?

This is in Visual Studio 2008.

解决方案

Well, the function-scoped static instance variable doesn't show up in a .map file generated by cl.exe /Fm, and it doesn't show up when I use x programname!*MyClass* in WinDbg, so the mangled name doesn't seem to contain MyClass at all.

Option 1: Disassemble MyClass::getInstance

This approach seems easier:

0:000> uf programname!MyClass::getInstance
programname!MyClass::getInstance [programname.cpp @ 14]:
   14 00401050 55              push    ebp
   14 00401051 8bec            mov     ebp,esp
   15 00401053 a160b34200      mov     eax,dword ptr [programname!$S1 (0042b360)]
   15 00401058 83e001          and     eax,1
   15 0040105b 7526            jne     funcstat!MyClass::getInstance+0x33 (00401083)

programname!MyClass::getInstance+0xd [programname.cpp @ 15]:
   15 0040105d 8b0d60b34200    mov     ecx,dword ptr [programname!$S1 (0042b360)]
   15 00401063 83c901          or      ecx,1
   15 00401066 890d60b34200    mov     dword ptr [programname!$S1 (0042b360)],ecx
   15 0040106c b9b0be4200      mov     ecx,offset programname!instance (0042beb0)
   15 00401071 e88fffffff      call    programname!ILT+0(??0MyClassQAEXZ) (00401005)
   15 00401076 68e03e4200      push    offset programname!`MyClass::getInstance'::`2'::`dynamic atexit destructor for 'instance'' (00423ee0)
   15 0040107b e8f3010000      call    programname!atexit (00401273)
   15 00401080 83c404          add     esp,4

programname!MyClass::getInstance+0x33 [programname.cpp @ 16]:
   16 00401083 b8b0be4200      mov     eax,offset programname!instance (0042beb0)
   17 00401088 5d              pop     ebp
   17 00401089 c3              ret

From this we can tell that the compiler called the object $S1. Of course, this name will depend on how many function-scoped static variables your program has.

Option 2: Search memory for the object

To expand on @gbjbaanb's suggestion, if MyClass has virtual functions, you might be able to find its location the hard way:

  • Make a full memory dump of the process.
  • Load the full memory dump into WinDbg.
  • Use the x command to find the address of MyClass's vtable:

    0:000> x programname!MyClass::`vftable'
    00425c64 programname!MyClass::`vftable' = 

  • Use the s command to search the process's virtual address space (in this example, 0-2GB) for pointers to MyClass's vtable:

    0:000> s -d 0 L?7fffffff 00425c64
    004010dc  00425c64 c35de58b cccccccc cccccccc  d\B...].........
    0040113c  00425c64 8bfc458b ccc35de5 cccccccc  d\B..E...]......
    0042b360  00425c64 00000000 00000000 00000000  d\B.............

  • Use the dt command to find the class's vtable offset, and subtract that from the addresses returned from the search. These are possible addresses for the object.

    0:000> dt programname!MyClass
       +0x000 __VFN_table      : Ptr32 
       +0x008 x                : Int4B
       +0x010 y                : Float

  • Use dt programname!MyClass 0042b360 to examine the object's member variables, testing the hypothesis that the object is located at 0042b360 (or some other address). You will probably get some false positives, as I did above, but by inspecting the member variables you may be able to figure out which one is your singleton.

This is a general technique for finding C++ objects, and is kind of overkill when you could just disassemble MyClass::getInstance.

这篇关于VC++ 如何处理局部静态变量名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆