我想在一个C++构造函数、析构函数或方法上设置断点,并查看调用它的对象的正确的“this”指针。
不幸的是,当断点命中时,GDB声明的“this”信息不是预期的信息。如果构造函数、析构函数或方法至少包含一行,并且在命中断点后使用单步执行一次,则“this”信息似乎发生了变化,然后显示预期值。
然而
- 构造函数、析构函数或方法也可以为空(或在前两种情况下设置为默认值),因此单步执行可能不可行。
- 也不可能开箱即用地配置要在命中执行单步的断点时执行的命令,然后继续正常执行,因为“单步”或“下一个”命令会中断所提供的命令序列的进一步执行,从而阻止“继续”语句的执行
- 我还相信,由于“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行)。
有没有办法得到正确的“这个”信息?
有没有办法设置一个条件断点,例如:for someMethod()调用,仅当执行具有已知地址的对象时才命中,例如这里的0x55555556aeb0不使用内部的一行方法?
1条答案
按热度按时间whlutmcx1#
不幸的是,当断点命中时,GDB声明的“this”信息不是预期的信息。
你有一个bug的GCC或GDB。
以下是我所看到的:
这是使用
gcc (Debian 12.2.0-14) 12.2.0
和相应的GDB。this GDB bug可能是导致问题的原因。this answer。
如果您的
x/4i 0x13ee
以endbr64
开头,那么几乎可以肯定这就是问题所在。好消息是,构建和使用更新的GDB非常容易:只需获取一个新版本,然后运行
./configure && make && make install
。