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
.