关于条件断点的奇怪 gdb 行为(a && b 不等于 b && a)

Posted

技术标签:

【中文标题】关于条件断点的奇怪 gdb 行为(a && b 不等于 b && a)【英文标题】:Weird gdb behavior regarding conditional breakpoint(a && b not equal to b && a) 【发布时间】:2016-07-21 08:49:12 【问题描述】:

我有一个小的 C++ 程序:

// test.cpp
#include <vector>
#include <iostream>
using namespace std;

template class vector<int>;
int main()

   vector<int> v;
   for (size_t i = 0; i < 10; ++i)
      
      if (!v.empty())
         cout << v[0] << endl;   //<== Add a cond breakpoint here later

      v.clear();
      for (size_t j = 0; j < i; ++j)
         v.push_back(i);
      

   return 0;

这个程序是在 Ubuntu 14.04.3 LTS 和 gcc 4.8.4 中编译的。

g++ -g -O0 -o test test.cpp

用gdb启动程序,在第13行添加条件断点,条件为"v.size() == 3 && v[0] == 3",如下图.但是,这种情况并没有按预期工作。不满足条件时停止。

(gdb) b 13 if v.size() == 3 && v[0] == 3
Breakpoint 1 at 0x400ca1: file test.cpp, line 13.
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000400ca1 in main() at test.cpp:13
        stop only if v.size() == 3 && v[0] == 3

运行程序,报错:

...
Error in testing breakpoint condition:
Cannot access memory at address 0x0

Breakpoint 1, main () at test.cpp:13
13           cout << v[0] << endl;

并且打印v.size() 显示它是1,这显然不是断点应该停止的条件。

(gdb) p v.size()
$1 = 1

但是如果我用 "v[0] == 3 && v.size() == 3" 替换条件断点,一切都很好。

(gdb) p v.size()
$2 = 3

第一个条件有什么问题?

[更新]

我在 Ubuntu 14.04 上将 gcc 和 gdb 分别升级到了 6.1.0 和 7.10(都是从源代码构建的),但是这个问题仍然存在。

$g++ -v

使用内置规范。 COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/6.1.0/lto-wrapper 目标:x86_64-pc-linux-gnu 配置:../gcc-6.1.0/configure --prefix=/usr --enable-languages=c,c++ --disable-multilib --disable-bootstrap --with-system-zlib 线程模型:posix gcc version 6.1.0 (GCC)

$gdb -v

GNU gdb (GDB) 7.10

【问题讨论】:

无法使用 GDB 7.11.1 重现。你用的是什么版本? 在我的系统上一切正常。 gcc 6.1.0,gdb 7.10.1。 我相信它在 Ubuntu 14.04.3 上默认是 7.7。刚才我从http://ftp.gnu.org/gnu/gdb/这个位置升级到了7.10。重建gdb。不幸的是,我可以观察到同样的问题。 有趣。我更新到 gdb 7.10 和 gcc 6.1.0。我仍然可以看到这个问题。 【参考方案1】:

我将 gdb 升级到 7.11.1(通过切换到 Ubuntu 16.04.1 LTE),这个问题就消失了。

而且对于这个 gdb 版本,自然支持打印std::vector,这很好。

(gdb) print v
$3 = std::vector of length 3, capacity 4 = 3, 3, 3

【讨论】:

以上是关于关于条件断点的奇怪 gdb 行为(a && b 不等于 b && a)的主要内容,如果未能解决你的问题,请参考以下文章

GDB使用小记

默认复制/移动构造函数时 GDB 中的奇怪行为

c++ builder6 断点失效

GDB

GDB 在函数结束处中断而不是指定断点

工具篇之GDB调试器用法