gpt4 book ai didi

c++ - 为什么即使在调试版本中,VS 和 Windbg 也会将 "this"指针打印为 "0xcccccccc"?

转载 作者:IT老高 更新时间:2023-10-28 21:49:59 25 4
gpt4 key购买 nike

我尝试在进入成员函数时使用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;
}

(1) I compiled it with VC2015 debug version(32bit)

(2) I set the break point in "DoIt" function.

(3) When hit Base->FuncOne(), I pressed "F11" to enter the function of 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

但是“dv”命令给出了意想不到的结果

0:000> dv
this = 0xcccccccc

这是为什么?该程序运行良好,调试版本没有优化任何东西,似乎一切都很好。但是为什么“this”指针是无效的呢?

我用VC自带的IDE调试,同样的观察。但为什么呢?

最佳答案

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

是您的编码风格导致了这个问题。由于您将函数体与函数定义写在同一行,因此断点设置在函数的开头,而不是函数体的开头。此时函数的序言还没有执行。设置堆栈帧并检索函数参数的代码。隐藏的 this 参数就是其中之一,它作为函数的第一个参数传递。

您只能在序言代码执行后观察 this 具有正确的值。这需要使用 Debug > Windows > Disassembly 这样您就可以跳过序言代码,一直到 mov dword ptr [this],ecx 之后的指令。很尴尬。

这样写就不会有这个问题了:

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

或任何您喜欢的大括号样式。现在设置断点确保函数的序言被执行并且 this 具有预期的值。

或者通过知道单步执行函数并不有趣来解决它,因为它没有做任何值得调试的事情。你这样写的基本原因。请改用“调试”>“跳过”。如果您不小心进入了这样的功能,请使用 Debug > Step Out 快速返回您真正想要调试的代码。

关于c++ - 为什么即使在调试版本中,VS 和 Windbg 也会将 "this"指针打印为 "0xcccccccc"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39326892/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com