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:
x
command to find the address of MyClass's vtable:0:000> x programname!MyClass::`vftable' 00425c64 programname!MyClass::`vftable' =
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.............
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
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With