我通过
定义断点b foo:124 if strcmp(bar::foo::getName(), "abc")==0
但是 gdb 失败并出现以下错误
[Thread 0x7fffe8ef9700 (LWP 25817) exited]
[Switching to Thread 0x7fffdfc2f700 (LWP 25972)]
Error in testing breakpoint condition:
Couldn't get registers: No such process.
An error occurred while in a function called from GDB.
Evaluation of the expression containing the function
(bar::foo::getName() const) will be abandoned.
When the function is done executing, GDB will silently stop.
Selected thread is running.
b foo:124 if strcmp(bar::foo::getName(), "abc")==0
这种情况是非常糟糕的想法(TM),原因有两个:
getName
取消引用内存,它可能会崩溃,从而产生您所观察到的令人困惑的输出。"abc"
,它必须在正在调试的程序“内部”合成这些字节。它通过合成对 strdup
的调用来实现这一点,并泄漏生成的内存。这也可以终止正在调试的程序。更新:
我发现我的程序为名称为“abc”的元素生成了错误的结果。有数百万个元素。所以我想使用 gdb 在元素名称为“abc”时停止在某些代码处。
您可以使用的技巧很少。
最简单的方法是将此代码插入到您的程序中:
const char *const name = getName();
if (strcmp(name, "abc") == 0) {
if (0) printf("here\n"); // set a breakpoint here
}
这里的优点是:程序评估条件的速度比 GDB 快得多。并且不必让 GDB 在生成结果的例程的每次调用上停止,而是仅在“有趣”的调用上停止(也更快)。
缺点是你必须重建程序,有时这会使错误隐藏起来。
另一种可能的技术是检查
getName
直接返回的数据(而不是调用 getName()
)——GDB 可以访问私有数据。如果 getName
看起来像这样:
const char *getName() { return name_; }
然后你可以像这样重新表述你的条件:
b foo.cc:124 if (name_[0] == 'a' && name_[1] == 'b' && name_[3] == 'c' && name_[4] == '\0')
这消除了您最初方法的两个问题,但有点冗长。
不要找原因,而是使用声明
b foo:124 if $_streq(bar::foo::getName(), "abc")
解决我的问题。
在我的例子中,只需再
continue
一次即可达到所需的断点条件。