当然,函数范围的静态变量instance
不通过cl.exe /Fm
产生.map
文件显示,它不会显示出来,当我在WinDbg中使用x programname!*MyClass*
,使错位的名称似乎不包含MyClass
。
选项1:拆下MyClass::getInstance
这种做法似乎更容易:
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
由此我们可以告诉编译器调用的对象$S1
。当然,这个名字将取决于你的程序有多少个函数范围的静态变量。
选项2:搜寻记忆的对象
要在@ gbjbaanb的建议扩大,如果MyClass
有虚函数,你也许可以找到它的位置艰辛的道路:
- 制作该进程的完整内存转储。
- 将完整的内存转储装入WinDbg。
- 使用
x
命令查找MyClass的的虚函数表的地址:
0:000> x programname!MyClass::`vftable'
00425c64 programname!MyClass::`vftable' =
- 使用
s
命令搜索进程的虚拟地址空间(在这个例子中,0-2GB)为指向MyClass的的虚函数表:
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.............
- 使用
dt
命令查找类的vtable偏移量,并从搜索返回的地址中减去该偏移量。这些是该对象的可能地址。
0:000> dt programname!MyClass
+0x000 __VFN_table : Ptr32
+0x008 x : Int4B
+0x010 y : Float
- 使用
dt programname!MyClass 0042b360
检查对象的成员变量,检验假设,即目标位于0042b360(或其他地址)。你可能会得到一些误报,就像我上面做的那样,但通过检查成员变量,你可能能够找出哪一个是你的单身人士。
这是一种用于查找C++对象的常规技术,当您可以反汇编MyClass::getInstance
时有点矫枉过正。
为什么不去做班级成员?本地静态变量不是调试的最佳选择 – 2008-11-13 21:08:08
什么类的成员? – Owen 2008-11-13 21:08:59
class MyClass { MyClass * instance; MyClass * getInstance(){ return instance; } } – 2008-11-13 21:15:10