我想在 C++ 构造函数、析构函数或方法上设置断点,并查看调用 this 的对象的正确“this”指针。
不幸的是,当断点命中时,GDB 声明的“this”信息不是预期的信息。如果构造函数、析构函数或方法至少包含一行,并且在命中断点后使用了一次单步执行,则“this”信息似乎发生了变化,然后显示了预期值。
然而
简单示例代码MyClass.cpp:
#include <iostream>
class MyClass
{
public:
MyClass() {
std::cout << "MyClass() constructor, this = " << this << std::endl;
}
void someMethod() {
std::cout << "someMethod(), this = " << this << std::endl;
}
~MyClass() {
std::cout << "MyClass() destructor, this = " << this << std::endl;
}
};
int
main(int argc, char **argv)
{
MyClass *myClass = new MyClass();
std::cout << "MyClass located at = " << myClass << std::endl;
myClass->someMethod();
delete myClass;
}
编译完成
g++ -std=c++14 -g -o MyClass MyClass.cpp
使用 GDB 执行:
$ gdb ./MyClass
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
...
Reading symbols from ./MyClass...
(gdb) b MyClass::MyClass
Breakpoint 1 at 0x1352: file MyClass.cpp, line 6.
(gdb) b MyClass::~MyClass
Breakpoint 2 at 0x13ee: file MyClass.cpp, line 14.
(gdb) b MyClass::someMethod
Breakpoint 3 at 0x13a0: file MyClass.cpp, line 10.
(gdb) b 11
Breakpoint 4 at 0x13b0: file MyClass.cpp, line 11.
(gdb) r
Starting program: /home/ostkamp/src/cpp_examples/MyClass
Breakpoint 1, MyClass::MyClass (this=0x7ffff7e7bb39 <operator new(unsigned long)+25>) at MyClass.cpp:6
6 MyClass() {
(gdb) c
Continuing.
MyClass() constructor, this = 0x55555556aeb0
MyClass located at = 0x55555556aeb0
Breakpoint 3, MyClass::someMethod (this=0x7ffff7f037a3 <std::ostream::flush()+35>) at MyClass.cpp:10
10 void someMethod() {
(gdb) c
Continuing.
Breakpoint 4, MyClass::someMethod (this=0x55555556aeb0) at MyClass.cpp:11
11 std::cout << "someMethod(), this = " << this << std::endl;
(gdb) c
Continuing.
someMethod(), this = 0x55555556aeb0
Breakpoint 2, MyClass::~MyClass (this=0x55555556aeb0, __in_chrg=<optimized out>) at MyClass.cpp:14
14 ~MyClass() {
(gdb) c
Continuing.
MyClass() destructor, this = 0x55555556aeb0
[Inferior 1 (process 9105) exited normally]
(gdb)
可以看出构造函数的断点(第 6 行),someMethod(第 10 行)显示无效的“this”信息。 someMethod 内的断点(第 11 行)显示正确的“this”。有时这也适用于析构函数(第 14 行)。
有没有办法得到正确的“这个”信息?
有没有办法设置条件断点,例如对于 someMethod() 调用,仅当对具有已知地址的对象执行时才会命中,例如这里 0x55555556aeb0 没有在方法内部使用一行?