使用gdb检查标准容器(std :: map)内容

Pao*_*sco 83 c++ gdb stl map

假设有这样的事情:

#include <map>
int main(){
    std::map<int,int> m;
    m[1] = 2;
    m[2] = 4;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我希望能够从gdb检查运行该程序的地图的内容.
如果我尝试使用下标运算符,我得到:

(gdb) p m[1]
Attempt to take address of value not located in memory.
Run Code Online (Sandbox Code Playgroud)

使用find方法不会产生更好的结果:

(gdb) p m.find(1)
Cannot evaluate function -- may be inlined
Run Code Online (Sandbox Code Playgroud)

有没有办法实现这个目标?

Jon*_*ely 84

现有的这个问题的答案是非常不合时宜的.由于GDB 7.x中内置的Python支持以及GCC附带的libstdc ++漂亮打印机,最近的GCC和GDB it Just Works TM.

对于OP的例子,我得到:

(gdb) print m
$1 = std::map with 2 elements = {[1] = 2, [2] = 4}
Run Code Online (Sandbox Code Playgroud)

如果它不能自动运行,请在GDB wiki 的STL支持页面上看到第一个项目符号点.

您也可以为自己的类型编写Python漂亮的打印机,请参阅GDB手册中的Pretty Printing.

  • 不幸的是,它并没有在所有的发行版中"正常工作".它在Ubuntu 13.10中默认不安装,并且[尝试手动安装时出现问题](http://askubuntu.com/questions/403143/setting-up-gdb-pretty-printing-in-ubuntu- 13-10) (11认同)
  • 是的,在GDB 7.2和icpc编译器中,我收到错误`找不到运算符[]`. (5认同)
  • 是的,但其他问题正在关闭,因此我希望它有最新的信息. (2认同)

jpa*_*cek 32

我认为没有,至少没有,如果您的源是优化等.但是,有一些gdb的宏可以为您检查STL容器:

http://sourceware.org/ml/gdb/2008-02/msg00064.html

但是,我不使用这个,所以YMMV

  • 我还没有尝试过,但是如果这与 GDB 的其余部分一样,那么应该用单引号将带有标点符号的名称括起来。 (2认同)
  • 注意:这些脚本中的 std::map 功能假定为 32 位指针类型。对于 64 位机器,将文件中的“+ 4”替换为“+ 8”。 (2认同)

Mr.*_*Ree 22

总是显而易见的:定义自己的测试函数...从gdb调用它.例如:

#define SHOW(X) cout << # X " = " << (X) << endl

void testPrint( map<int,int> & m, int i )
{
  SHOW( m[i] );
  SHOW( m.find(i)->first );
}

int
main()
{
    std::map<int,int> m;
    m[1] = 2;
    m[2] = 4;
    return 0;  // Line 15.
}
Run Code Online (Sandbox Code Playgroud)

和:

....
Breakpoint 1 at 0x400e08: file foo.C, line 15.
(gdb) run
Starting program: /tmp/z/qD 

Breakpoint 1, main () at qD.C:15
(gdb) call testPrint( m, 2)
m[i] = 4
(*m.find(i)).first = 2
(gdb) 
Run Code Online (Sandbox Code Playgroud)

  • 只要进程正在运行.对核心转储不太有用. (14认同)
  • 这通常是调试GDB的有用建议,而不仅仅是STL.我为许多难以检索的数据保留了一整套gdb辅助函数,例如write_cuda_array_as_image().请注意,一些编译器将删除任何未调用的函数,因此我在main的"return 0;"之后调用每个辅助函数.同样用extern"C"声明它们使得从gdb中调用它们更容易. (2认同)
  • @KyleSimek gcc 还支持 ` __attribute__((used))` 因此,如果未使用,链接器不会丢弃该符号 (2认同)

Emp*_*ian 20

stl-views.gdb曾经是最好的答案出现了,但现在不是了.

这还没有集成到主线中GDB,但是你可以使用'archer-tromey-python' 分支:

(gdb) list
1   #include <map>
2   int main(){
3       std::map<int,int> m;
4       m[1] = 2;
5       m[2] = 4;
6       return 0;
7   }
(gdb) break 6
Breakpoint 1 at 0x8048274: file map.cc, line 6.
(gdb) run

Breakpoint 1, main () at map.cc:6
6       return 0;
(gdb) print m
$1 = std::map with 2 elements = {
  [1] = 2,
  [2] = 4
}
(gdb) quit
Run Code Online (Sandbox Code Playgroud)


ana*_*and 12

尝试取消引用STL容器:在此页面上:http://www.yolinux.com/TUTORIALS/GDB-Commands.html