检查断点处的条件时gdb失败

时间:2017-05-04 02:20:02

标签: c++ c 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.

1 个答案:

答案 0 :(得分:1)

  

b foo:124 if strcmp(bar::foo::getName(), "abc")==0

这样的条件是Really Bad Idea(TM)有两个原因:

  1. 如果应用程序状态已损坏(甚至暂时)并且getName取消引用内存,则可能会崩溃,从而产生您观察到的令人困惑的输出。
  2. 为了让GDB评估"abc",它必须在被调试的程序“内部”合成这些字节。它通过合成对strdup的调用来完成此操作,并泄漏生成的内存。这也可以终止正在调试的程序。
  3. <强>更新

      

    我发现我的程序为名为“abc”的元素生成了错误的结果。有数百万个元素。因此,当元素名称为“abc”时,我想使用gdb来停止某些代码。

    您可以使用的技术很少。

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

    const char *const name = getName();
    if (strcmp(name, "abc") == 0) {
      if (0) printf("here\n");  // set a breakpoint here 
    }
    

    这里的优点是:程序评估条件要比GDB快得多。并且不是让每次调用生成结果的例程都停止GDB,而是停止“有趣”的调用(也快得多)。

    缺点是你必须重建程序,有时会使bug隐藏。

    另一种可能的技术是检查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')
    

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