gpt4 book ai didi

c++ - Visual Studio 无法在 Release模式下显示 'this' 的值(带有调试信息)

转载 作者:IT老高 更新时间:2023-10-28 23:03:23 29 4
gpt4 key购买 nike

原问题:

为什么在 VS c++ 发布版本中 this 指针为 0?

在使用/Zi(编译器:调试信息格式 - 程序数据库)和/DEBUG(链接器:生成调试信息,是)选项中断 Visual Studio 2008 SP1 版本构建时,为什么“this”指针始终为 0x00000000 ?

编辑:改写问题:

我最初的问题很不清楚,很抱歉。当使用 Visual Studio 2008 调试器单步调试程序时,我可以看到所有变量,但本地对象的成员变量除外。这可能是调试器从this指针导出这些,而VS总是说是0x00000000,所以无法导出当前对象的成员变量(它不知道对象的内存位置)

当加载一个巨型转储(类似于 Windows 小型转储,但包含进程的整个内存空间)时,我可以查看我的所有局部变量(在函数中定义)和堆上的整个树结构,即使我有指针到。

例如:在Release模式下闯入A::foo()时

'this' 的值为 0x00000000
'f_' 会显示垃圾

不知何故,此信息需要可用于流程。这是VS2008中缺少的功能吗?任何其他能正确处理这个问题的调试器?

class A
{
void foo() { /*break here*/ }
int f_;
};

最佳答案

正如其他人所提到的,在 Release 模式下编译会进行某些优化(尤其是消除使用 ebp/rbp 作为帧指针),从而打破调试器依赖于找出局部变量的假设。然而,知道它发生的原因对于调试你的程序并不是很有帮助!

您可以通过以下方法解决它:在方法调用的最开始(在函数的第一行中断,而不是左大括号),总是会找到 this 指针在特定的寄存器中(32 位系统上的 ecx 或 64 位系统上的 rcx)。调试器知道这一点,因此您应该能够在方法调用开始时看到 this 的值。然后,您可以从 Value 列中复制地址并专门查看(如 (MyObject *)0x003f00f0 或其他),这将允许您稍后查看 this方法。

如果这还不够好(例如,因为您只想在出现错误时停止,这只是调用给定方法的时间的一小部分),您可以尝试更高级(并且更少可靠)把戏。通常,this 指针在函数调用的早期就从 ecx/rcx 中取出,因为这是一个“调用者保存”寄存器,这意味着它的值可能会被函数调用破坏而不是恢复您的方法使(某些指令也需要它使用该寄存器作为其操作数,如 REP* 和一些移位指令)。但是,如果你的方法经常使用 this 指针(包括隐式使用引用成员变量或调用虚拟成员函数),编译器可能会将 this 保存在另一个寄存器,一个“被调用者保存”寄存器(意味着任何破坏它的函数都必须在返回之前恢复它)。

这样做的实际结果是,在您的监 window 口中,您可以尝试查看 (MyObject *) ebp(MyObject *) esi 等与其他寄存器一起,直到您发现您正在查看的指针可能是正确的指针(因为成员变量与您在断点时对 this 内容的期望一致) .在 x86 上,调用保存的寄存器是 ebp、esi、edi 和 ebx。在 x86-64 上,它们是 rbp、rsi、rdi、rbx、r12、r13、r14 和 r15。如果您不想搜索所有这些,您可以随时尝试查看函数序言的反汇编,以查看正在复制的 ecx(或 rcx)。

关于c++ - Visual Studio 无法在 Release模式下显示 'this' 的值(带有调试信息),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4657188/

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