VC++ 如何处理局部静态变量名? [英] How does VC++ mangle local static variable names?
问题描述
这是我的一些代码:
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地址:
- 使用
s
命令搜索进程的虚拟地址空间(在本例中为 0-2GB)以查找指向 MyClass 的 vtable 的指针:
- 使用
dt
命令查找类的 vtable 偏移量,并从搜索返回的地址中减去该偏移量.这些是对象的可能地址.
- 使用
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屋!