GDB在断点检查条件时失败



我通过

定义了断点
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(,原因有两个:

  1. 如果应用程序状态被损坏(甚至暂时(和getName表示内存,则可能会崩溃,从而完全产生您观察到的混乱输出。
  2. 为了使GDB评估"abc",它必须综合这些字节"内部"的程序。它通过合成对strdup的调用并泄漏结果内存来做到这一点。这也可以终止正在调试的程序。

更新:

我发现我的程序用名称为" ABC"的元素生成了错误的结果。有数百万个要素。因此,当元素名称为" ABC"时,我想使用GDB停止一些代码。

您几乎没有技术可以使用。

最简单的是将此代码插入您的程序:

const char *const name = getName();
if (strcmp(name, "abc") == 0) {
  if (0) printf("heren");  // 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] == '')

这消除了您的初始方法的两个问题,但有点冗长。

在我的情况下,只需再一次 continue即可击中所需的断点条件。

最新更新