使用GDB调试RB-tree的几个问题(更正)

来源:互联网 发布:linux exec命令 编辑:程序博客网 时间:2024/06/09 21:51
本博客http://blog.csdn.net/livelylittlefish 贴出作者(三二一@小鱼)相关研究、学习内容所做的笔记,欢迎广大朋友指正!

Content

1. at后面的一堆字符串代表什么?

2. 为什么没有单步进入(step in)_Rb_tree_insert_and_rebalance函数?

3. 如何通过目标文件.o或者可执行文件得知是否有debugging information

4. 如何单步调试没有debugging information的函数?


0. 引子

 

笔者在前一篇文章使用GDB调试RB-tree的几个问题讨论了几个问题,但关于at后面字符串的讨论是错误,特在此进行更正,希望不要误导读者。并向已经读过该文并被误导或有疑惑的读者致以诚挚的歉意,同时也谢谢这些读者对本blog的支持。

 

一点心得:虽然笔者讨论的问题并不是什么科学,只是简单的技术问题,但也应该本着实事求是的精神,改正自己的错误,对读者负责,实际上也是对自己负责。看来,“科学是严谨的”在技术问题上也是适用的,技术也应该严谨,也应该认真。

 

言归正传,首先更正这个错误。

 

1. at后面的一堆字符串代表什么?

 

at后面的一堆字符串是一个整体,并没有什么前半部分和后半部分。这个整体代表的是一个绝对路径。例如,

/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/new

 

其中的..表示当前目录的父目录。

因此,

/usr/lib/gcc/i386-redhat-linux/4.1.2/..表示/usr/lib/gcc/i386-redhat-linux

/usr/lib/gcc/i386-redhat-linux/4.1.2/../..表示/usr/lib/gcc

/usr/lib/gcc/i386-redhat-linux/4.1.2/../../..表示/usr/lib

/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../..表示/usr

 

因此,

/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/new

就是/usr/include/c++/4.1.2/new,是一个绝对路径。

 

其中,/usr/lib/gcc/i386-redhat-linux/4.1.2是在gcc-4.1.2安装时就确定的。

 

如果同时安装了多个版本的gcc,如下所示。

 

# ls /usr/lib/gcc/i486-linux-gnu

4.4  4.4.0  4.4.1

 

# ls /usr/include/c++

4.4  4.4.0  4.4.1

 

/usr/lib/gcc/i486-linux-gnu/4.4/../../../../include/c++/4.4/new

/usr/lib/gcc/i486-linux-gnu/4.4.0/../../../../include/c++/4.4.0/new

/usr/lib/gcc/i486-linux-gnu/4.4.1/../../../../include/c++/4.4.1/new

 

2. 为什么没有单步进入(step in)_Rb_tree_insert_and_rebalance函数?

 

要回答这个问题,我们可以参考gdb的官方文档,如下。

 

Warning: If you use the step command while control is within a function that was compiled without debugging information, execution proceeds until control reaches a function that does have debugging information. Likewise, it will not step into a function which is compiled without debugging information. To step through functions without debugging information, use the stepi command, described below. (http://www.delorie.com/gnu/docs/gdb/gdb_38.html)

 

前半部分说明,如果在一个没有debugging information的函数中是用step命令,程序会一直运行到某个有debugging information的函数才停止。

 

另外,划线句子说明,如果某个函数没有debugging information,在使用step命令时不能进入该函数内部;那么这个命题的逆反命题也一定是成立的。即如果能step进入某个函数,则该函数一定有debugging information

 

实际上,这也解释了使用GDB调试RB-tree的几个问题中的问题,即本标题的问题。

函数std::_Rb_tree, std::less, std::allocator >::_M_insert()stl_tree.h中,有debugging information,而函数_Rb_tree_insert_and_rebalance所在的文件tree.cc在编译时被编译成tree.o并链接到动态库libstdc++.so

 

3. 如何通过目标文件.o或者可执行文件得知是否有debugging information

 

可通过如下命令查看debugguing information

objdump -g filename

objdump -h filename(查看有无debug section)

nm -l filename

 

重新编译gcc-4.1.2的源文件tree.cc,观看结果。

 

# cd /mnt/hgfs/edisk/opensource/gcc-4.1.2/libstdc++-v3/src

# g++ -o tree.o -c tree.cc  //without debugging information

# objdump -h tree.o

 

tree.o:     file format elf32-i386

 

Sections:

Idx Name          Size      VMA       LMA       File off  Algn

  0 .group        00000008  00000000  00000000  00000034  2**2

                  CONTENTS, READONLY, EXCLUDE, GROUP, LINK_ONCE_DISCARD

  1 .group        00000008  00000000  00000000  0000003c  2**2

                  CONTENTS, READONLY, EXCLUDE, GROUP, LINK_ONCE_DISCARD

  2 .group        00000008  00000000  00000000  00000044  2**2

                  CONTENTS, READONLY, EXCLUDE, GROUP, LINK_ONCE_DISCARD

  3 .text         00000952  00000000  00000000  0000004c  2**2

                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE

  4 .data         00000000  00000000  00000000  000009a0  2**2

                  CONTENTS, ALLOC, LOAD, DATA

  5 .bss          00000000  00000000  00000000  000009a0  2**2

                  ALLOC

  6 .text._ZNSt18_Rb_tree_node_base10_S_minimumEPS_ 00000022  00000000  00000000  000009a0  2**0

                  CONTENTS, ALLOC, LOAD, READONLY, CODE

  7 .text._ZNSt18_Rb_tree_node_base10_S_maximumEPS_ 00000022  00000000  00000000  000009c2  2**0

                  CONTENTS, ALLOC, LOAD, READONLY, CODE

  8 .text._ZSt4swapISt14_Rb_tree_colorEvRT_S2_ 00000022  00000000  00000000  000009e4  2**0

                  CONTENTS, ALLOC, LOAD, READONLY, CODE

  9 .comment      00000024  00000000  00000000  00000a06  2**0

                  CONTENTS, READONLY

10 .note.GNU-stack 00000000  00000000  00000000  00000a2a  2**0

                  CONTENTS, READONLY

11 .eh_frame     0000016c  00000000  00000000  00000a2c  2**2

                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

# cd /mnt/hgfs/edisk/opensource/gcc-4.1.2/libstdc++-v3/src

# g++ -g -o tree.d.o -c tree.cc  //with debugging information

# objdump -h tree.d.o

 

tree.d.o:     file format elf32-i386

 

Sections:

Idx Name          Size      VMA       LMA       File off  Algn

  0 .group        00000008  00000000  00000000  00000034  2**2

                  CONTENTS, READONLY, EXCLUDE, GROUP, LINK_ONCE_DISCARD

  1 .group        00000008  00000000  00000000  0000003c  2**2

                  CONTENTS, READONLY, EXCLUDE, GROUP, LINK_ONCE_DISCARD

  2 .group        00000008  00000000  00000000  00000044  2**2

                  CONTENTS, READONLY, EXCLUDE, GROUP, LINK_ONCE_DISCARD

  3 .text         00000952  00000000  00000000  0000004c  2**2

                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE

  4 .data         00000000  00000000  00000000  000009a0  2**2

                  CONTENTS, ALLOC, LOAD, DATA

  5 .bss          00000000  00000000  00000000  000009a0  2**2

                  ALLOC

  6 .debug_abbrev 000001d0  00000000  00000000  000009a0  2**0

                  CONTENTS, READONLY, DEBUGGING

  7 .debug_info   000006fd  00000000  00000000  00000b70  2**0

                  CONTENTS, RELOC, READONLY, DEBUGGING

  8 .debug_line   00000258  00000000  00000000  0000126d  2**0

                  CONTENTS, RELOC, READONLY, DEBUGGING

  9 .text._ZNSt18_Rb_tree_node_base10_S_minimumEPS_ 00000022  00000000  00000000  000014c5  2**0

                  CONTENTS, ALLOC, LOAD, READONLY, CODE

10 .text._ZNSt18_Rb_tree_node_base10_S_maximumEPS_ 00000022  00000000  00000000  000014e7  2**0

                  CONTENTS, ALLOC, LOAD, READONLY, CODE

11 .text._ZSt4swapISt14_Rb_tree_colorEvRT_S2_ 00000022  00000000  00000000  00001509  2**0

                  CONTENTS, ALLOC, LOAD, READONLY, CODE

12 .debug_loc    00000210  00000000  00000000  0000152b  2**0

                  CONTENTS, RELOC, READONLY, DEBUGGING

13 .debug_pubnames 0000019d  00000000  00000000  0000173b  2**0

                  CONTENTS, RELOC, READONLY, DEBUGGING

14 .debug_aranges 00000038  00000000  00000000  000018d8  2**0

                  CONTENTS, RELOC, READONLY, DEBUGGING

15 .debug_ranges 00000070  00000000  00000000  00001910  2**0

                  CONTENTS, RELOC, READONLY, DEBUGGING

16 .debug_str    00000533  00000000  00000000  00001980  2**0

                  CONTENTS, READONLY, DEBUGGING

17 .comment      00000024  00000000  00000000  00001eb3  2**0

                  CONTENTS, READONLY

18 .note.GNU-stack 00000000  00000000  00000000  00001ed7  2**0

                  CONTENTS, READONLY

19 .eh_frame     0000016c  00000000  00000000  00001ed8  2**2

                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

以下是nm命令的结果。

  -l, --line-numbers     Use debugging information to find a filename and

                           line number for each symbol

# cd /mnt/hgfs/edisk/opensource/gcc-4.1.2/libstdc++-v3/src

# nm -l tree.o

00000000 W _ZNSt18_Rb_tree_node_base10_S_maximumEPS_

00000000 W _ZNSt18_Rb_tree_node_base10_S_minimumEPS_

0000011a T _ZSt18_Rb_tree_decrementPKSt18_Rb_tree_node_base

00000088 T _ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base

00000075 T _ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base

00000000 T _ZSt18_Rb_tree_incrementPSt18_Rb_tree_node_base

00000910 T _ZSt20_Rb_tree_black_countPKSt18_Rb_tree_node_baseS1_

0000012d T _ZSt20_Rb_tree_rotate_leftPSt18_Rb_tree_node_baseRS0_

000001ba T _ZSt21_Rb_tree_rotate_rightPSt18_Rb_tree_node_baseRS0_

0000046f T _ZSt28_Rb_tree_rebalance_for_erasePSt18_Rb_tree_node_baseRS_

00000247 T _ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_

00000000 W _ZSt4swapISt14_Rb_tree_colorEvRT_S2_

         U __gxx_personality_v0

# cd /mnt/hgfs/edisk/opensource/gcc-4.1.2/libstdc++-v3/src

# nm -l tree.d.o  //tree.d.odebugging information

00000000 W _ZNSt18_Rb_tree_node_base10_S_maximumEPS_    /usr/include/c++/4.4/bits/stl_tree.h:112

00000000 W _ZNSt18_Rb_tree_node_base10_S_minimumEPS_    /usr/include/c++/4.4/bits/stl_tree.h:98

0000011a T _ZSt18_Rb_tree_decrementPKSt18_Rb_tree_node_base     /mnt/hgfs/edisk/opensource/gcc-4.1.2/libstdc++-v3/src/tree.cc:119

00000088 T _ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base      /mnt/hgfs/edisk/opensource/gcc-4.1.2/libstdc++-v3/src/tree.cc:93

00000075 T _ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base     /mnt/hgfs/edisk/opensource/gcc-4.1.2/libstdc++-v3/src/tree.cc:87

00000000 T _ZSt18_Rb_tree_incrementPSt18_Rb_tree_node_base      /mnt/hgfs/edisk/opensource/gcc-4.1.2/libstdc++-v3/src/tree.cc:64

00000910 T _ZSt20_Rb_tree_black_countPKSt18_Rb_tree_node_baseS1_        /mnt/hgfs/edisk/opensource/gcc-4.1.2/libstdc++-v3/src/tree.cc:416

0000012d T _ZSt20_Rb_tree_rotate_leftPSt18_Rb_tree_node_baseRS0_        /mnt/hgfs/edisk/opensource/gcc-4.1.2/libstdc++-v3/src/tree.cc:126

000001ba T _ZSt21_Rb_tree_rotate_rightPSt18_Rb_tree_node_baseRS0_       /mnt/hgfs/edisk/opensource/gcc-4.1.2/libstdc++-v3/src/tree.cc:147

0000046f T _ZSt28_Rb_tree_rebalance_for_erasePSt18_Rb_tree_node_baseRS_ /mnt/hgfs/edisk/opensource/gcc-4.1.2/libstdc++-v3/src/tree.cc:259

00000247 T _ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_    /mnt/hgfs/edisk/opensource/gcc-4.1.2/libstdc++-v3/src/tree.cc:170

00000000 W _ZSt4swapISt14_Rb_tree_colorEvRT_S2_ /usr/include/c++/4.4/bits/move.h:76

 

# c++filt _ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_

std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&)

 

从以上结果可以看出,在tree.d.o中,每个函数都有对应的调试信息,例如在源文件(tree.cc)中的行号。

 

4. 如何单步调试没有debugging information的函数?

 

由第2个问题,可知,可以通过stepi命令直接调试汇编代码。如使用GDB调试RB-tree的几个问题一文2.(4)所示。

 

stepi

stepi arg

si

Execute one machine instruction, then stop and return to the debugger.

It is often useful to do `display/i $pc' when stepping by machine instructions. This makes GDB automatically display the next instruction to be executed, each time your program stops. See section Automatic display.

An argument is a repeat count, as in step. (http://www.delorie.com/gnu/docs/gdb/gdb_38.html)

 

 

Reference

http://www.delorie.com/gnu/docs/gdb/gdb_38.html

objdumpmanual

nmmanual


Technorati 标签: STL, RB-tree, 红黑树, GDB

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 怀孕才两个月肚子就大了怎么办 腰椎间盘突出腿疼厉害怎么办 打了促排卵针不排卵怎么办 孕34周隐血1十是怎么办 窦性心动过缓伴不齐怎么办 09年买的万科b怎么办 苹果5s手机打不开机怎么办 剖腹产后一年半后意外怀孕怎么办 考驾照挂了5次了怎么办 怀孕咳嗽一个月了好不了怎么办 孕妇餐后2小时血糖高怎么办 我想开网店但我不懂该怎么办 新开的淘宝店没生意怎么办 做肝胆b超喝了水怎么办 红米1s刷机失败怎么办 红米3x手机太卡怎么办 红米2a线刷失败怎么办 红米2用不了4g怎么办 小米红米3s卡顿怎么办 魅蓝4g网速很慢怎么办 lol装到c盘了会怎么办 急用钱又借不到怎么办小额信贷 花呗分期买手机额度不够怎么办 2个月婴儿脸皴了怎么办 掉头发怎么办怎样能让头发变多 11个月的宝宝大便干燥怎么办 1岁宝宝又拉又吐怎么办 怀孕八个月了不想要了怎么办 奶水不够宝宝又不喝奶粉怎么办 手机恢复出厂设置密码忘了怎么办 5s锁屏密码忘了怎么办 深圳房子卖了户口没地方迁怎么办 宝马1系130i烧机怎么办 小孩流清鼻涕怎么办最简单方法 孕3个月胎盘低置怎么办 孩子判逆不听家长的话该怎么办 香港购物超5000被海关扣怎么办 浅色衣服被深色衣服染色了怎么办 金立手机微信不能发语音怎么办 吃鸡买的账号密码邮箱忘记了怎么办 氩弧焊枪管带里进水了怎么办