c++ pointers this windbg break

c++ - ¿Por qué VS y Windbg imprimen el puntero “this” como “0xccccccccc” incluso en la versión de depuración?



pointers break (1)

Intenté usar windbg para imprimir el puntero de "este" al ingresar una función miembro, como a continuación.

class IBase { int m_i; public: IBase() :m_i(23) {} virtual int FuncOne(void) = 0; virtual int FuncTwo(void) = 0; }; class DerivedOne : public IBase { public: virtual int FuncOne(void) { return 1; };//set break point here. virtual int FuncTwo(void) { return 2; }; }; class DerivedTwo : public IBase { public: virtual int FuncOne(void) { return 101; }; virtual int FuncTwo(void) { return 102; }; }; void DoIt(IBase* Base) { int i=Base->FuncOne();//break point here } int main(int argc, char *argv[]) { DerivedOne d1; DerivedTwo d2; DoIt(&d1); DoIt(&d2); return 0; }

(1) Lo compilé con la versión de depuración VC2015 (32 bits)

(2) Establecí el punto de interrupción en la función "DoIt".

(3) Cuando presioné Base-> FuncOne (), presioné "F11" para ingresar a la función de DerivedOne.

Ahora puedo ver que la pila de llamadas es así:

0:000> k # ChildEBP RetAddr 00 0041f654 0022157c ConsoleApplication1!DerivedOne::FuncOne [d:/documents/visual studio 2013/projects/consoleapplication1/consoleapplication1.cpp @ 13] 01 0041f734 0022173c ConsoleApplication1!DoIt+0x2c [d:/documents/visual studio 2013/projects/consoleapplication1/consoleapplication1.cpp @ 23] 02 0041f850 00221dc9 ConsoleApplication1!main+0x7c [d:/documents/visual studio 2013/projects/consoleapplication1/consoleapplication1.cpp @ 36] 03 0041f8a0 00221fbd ConsoleApplication1!__tmainCRTStartup+0x199 [f:/dd/vctools/crt/crtw32/dllstuff/crtexe.c @ 626] 04 0041f8a8 75b9338a ConsoleApplication1!mainCRTStartup+0xd [f:/dd/vctools/crt/crtw32/dllstuff/crtexe.c @ 466] 05 0041f8b4 77529902 kernel32!BaseThreadInitThunk+0xe 06 0041f8f4 775298d5 ntdll!__RtlUserThreadStart+0x70 07 0041f90c 00000000 ntdll!_RtlUserThreadStart+0x1b

Pero el comando "dv" dio resultado inesperado

0:000> dv this = 0xcccccccc

¿Por qué es esto? El programa funciona bien, la versión de depuración no optimiza nada, parece que todo está bien. Pero ¿por qué "este" puntero no es válido?

Usé el propio IDE de VC para depurar, la misma observación. ¿Pero por qué?


virtual int FuncOne(void) { return 1; };//set break point here.

Es su estilo de codificación que causa este problema. Dado que escribió el cuerpo de la función en la misma línea que la definición de la función, el punto de interrupción se establece al inicio de la función, no al inicio del cuerpo de la función. En ese momento el prólogo de la función no se ha ejecutado todavía. El código que configura el marco de pila y recupera los argumentos de la función. El argumento oculto es uno de ellos, se pasa como el primer argumento de la función.

Solo puede observar esto teniendo el valor adecuado después de que se haya ejecutado el código del prólogo. Lo que requiere el uso de Debug> Windows> Disassembly para que pueda pasar el código del prólogo hasta las instrucciones después de mov dword ptr [this],ecx . Muy incomodo.

No tendrás este problema cuando lo escribas así:

virtual int FuncOne(void) { return 1; };//set break point here.

O cualquier estilo de corsé que prefieras. Ahora, establecer el punto de interrupción garantiza que el prólogo de la función se ejecutó y esto tiene el valor esperado.

O abordarlo sabiendo que el paso a través de la función no es interesante, ya que no hace nada que valga la pena depurar. La razón básica por la que lo escribiste así. Use Debug> Step Over en su lugar. Si accedió accidentalmente a una función de este tipo, utilice Debug> Step Out para volver rápidamente al código que realmente desea depurar.