使用GDB调试RB-tree的问题总汇

操作方法

  • 01

    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  www.ghost580.com 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.o有debugging 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)中的行号。

(0)

相关推荐

  • Linux系统中的gdb程序调试工具的命令知识介绍

    在Linux系统中有许多的命令程序来辅助系统的正常和方便运行,那么其中在系统中有着一个叫做gdb命令的程序,那么我们今天就来了解下关于gdb命令的知识吧! 一、常规调试 gdb是Linux下常用的程序 ...

  • 关于在Linux系统中的gdb命令知识

    在Linux系统中有许多的命令程序来辅助系统的正常和方便运行,那么其中在系统中有着一个叫做gdb命令的程序,那么我们今天就来了解下关于gdb命令的知识吧! 一、常规调试 gdb是Linux下常用的程序 ...

  • Linux 系统内核的调试详解

    调试是软件开发过程中一个必不可少的环节,在 Linux 内核开发的过程中也不可避免地会面对如何调试内核的问题.但是,Linux 系统的开发者出于保证内核代码正确性的考虑,不愿意在 Linux 内核源代 ...

  • c语言不能调试怎么办(c语言为什么调试不了)

    相信大家在嵌入式C开发中,或多或少都会遇到段错误(segmentation fault ).相比总线错误,段错误是一种更为常见的错误.那么,段错误是怎么产生的呢?简单来说,段错误是因为访问不可访问的内 ...

  • 新手如何学习Linux

    新手如何学习Linux

  • emacs常用快捷键 emacs快捷键大全

    Emacs这个东东听说功能很强大。不过感觉有些难学,还好网络上的资源还是比较丰富的。目前基于最基本的文本编辑来学习。而且它的快捷键很多,所以要在使用过程中学习会比较容易记住。这个是从网上搜索来的,总结 ...

  • WINDOWS下givm安装使用方法(编译程序)

    上大学后,你是不是也开始学习C语言了?特别是计算机学院的孩子,应当有更高的追求。 C语言开课一段时间了,你是不是开始嫌弃IDE恶心的界面了? 是不是跟我一样,嫌弃IDE打开速度太慢? VS2010需要 ...

  • CentOS虚拟机下的相关操作详解

    在VM虚拟机中安装完Redhat系统之后 如果需要用secureCRT连接linux系统的话 操作步骤如下: 1.进入linux系统,在终端输入ifconfig(注意,不是windows的ipconf ...

  • CentOS进程资源占用高原因分析命令详解

    CentOS进程资源占用高原因分析命令详解