Tro*_*yvs 20 c++ pointers windbg this break
我尝试使用windbg在输入成员函数时打印"this"指针,如下所示.
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;
}
Run Code Online (Sandbox Code Playgroud)
(1)我用VC2015调试版(32bit)编译了它
(2)我在"DoIt"函数中设置了断点.
(3)当按下Base-> FuncOne()时,我按下"F11"进入DerivedOne的功能.
现在我可以看到调用堆栈是这样的:
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
Run Code Online (Sandbox Code Playgroud)
但是"dv"命令给出了意想不到的结果
0:000> dv
this = 0xcccccccc
Run Code Online (Sandbox Code Playgroud)
为什么是这样?程序运行良好,调试版本没有优化任何东西,似乎一切都很好.但为什么"这个"指针无效?
我使用VC自己的IDE进行调试,同样的观察.但为什么?
Han*_*ant 41
virtual int FuncOne(void) { return 1; };//set break point here.
Run Code Online (Sandbox Code Playgroud)
这是您的编码风格导致此问题.由于您在与函数定义相同的行中编写了函数体,因此断点设置在函数的开头,而不是函数体的开头.此时,该功能的序言尚未执行.设置堆栈帧并检索函数参数的代码.隐藏的这个参数就是其中之一,它作为函数的第一个参数传递.
在执行序言代码之后,您只能观察到具有正确值的此值.这需要使用Debug> Windows> Disassembly,这样您就可以跳过序言代码,一直到指令之后mov dword ptr [this],ecx.很尴尬.
写这样的时候你不会遇到这个问题:
virtual int FuncOne(void)
{ return 1; };//set break point here.
Run Code Online (Sandbox Code Playgroud)
或者你喜欢的任何支撑样式.现在设置断点确保函数的序幕被执行,这有预期值.
或者通过了解踩踏函数并不感兴趣来解决它,因为它不会做任何值得调试的事情.你写这个的基本原因.请改用Debug> Step Over.如果你不小心进入了这样一个函数,那么使用Debug> Step Out快速返回你想要调试的代码.
| 归档时间: |
|
| 查看次数: |
1214 次 |
| 最近记录: |