Bueno, la función de ámbito estática instance
variable no aparece en un archivo generado por .map
cl.exe /Fm
, y no aparece cuando se utiliza x programname!*MyClass*
en WinDbg, por lo que no parece que el nombre revuelto para contener MyClass
en absoluto.
Opción 1: Desmontar MyClass::getInstance
Este enfoque parece más fácil:
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
De esto podemos decir que el compilador llama el objeto $S1
. Por supuesto, este nombre dependerá de la cantidad de variables estáticas con función de función que tenga su programa.
Opción 2: Memoria de búsqueda del objeto
Para ampliar la sugerencia de @ gbjbaanb, si MyClass
tiene funciones virtuales, es posible que pueda encontrar su ubicación de la manera difícil:
- Hacer un volcado de memoria completo del proceso.
- Cargar la memoria completa volcado en WinDbg.
- utilizar el comando
x
para encontrar la dirección de vtable de MiClase:
0:000> x programname!MyClass::`vftable'
00425c64 programname!MyClass::`vftable' =
- utilizar el comando
s
para buscar espacio de direcciones virtual del proceso (en este ejemplo, 0-2GB) para los punteros a de MiClase 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.............
- Utilice la
dt
comando para encontrar el desplazamiento vtable de la clase, y reste eso de las direcciones devueltas desde la búsqueda. Estas son direcciones posibles para el objeto.
0:000> dt programname!MyClass
+0x000 __VFN_table : Ptr32
+0x008 x : Int4B
+0x010 y : Float
- Uso
dt programname!MyClass 0042b360
para examinar las variables miembro del objeto, poniendo a prueba la hipótesis de que el objeto se encuentra en 0042b360 (o alguna otra dirección). Es probable que obtenga algunos resultados positivos falsos, como hice anteriormente, pero al inspeccionar las variables de los miembros puede averiguar cuál es su singleton.
Esta es una técnica general para encontrar objetos C++, y es un poco exagerado cuando podrías desensamblar MyClass::getInstance
.
¿Por qué simplemente no lo hace el miembro de la clase? Las variables estáticas locales no son lo mejor para depurar –
¿Qué clase de miembro? – Owen
clase MyClass { instancia de MyClass *; MyClass * getInstance() { instancia de devolución; } } –