一、gdb 调试-源代码关联

  在调试程序的过程中,可以自由地查看相关的源代码(如果有源代码的话)是一项最基本的特性。gdb 当然也提供了这项特性,虽然不如IDE直观,但在一定程度上要比IDE更加灵活和快捷。
gdb之所以能够知道对应的源代码,是因为调试版的可执行程序中记录了源代码的位置;因为源代码的位置在编译之后可能会移动到其它地方,所以gdb还会在当前目录中查找源代码,另外gdb也允许明确指定源代码的搜索位置。
  在一个调试会话中,gdb维护了一个源代码查找目录列表,默认值是编译目录和当前工作目录。当gdb需要一个源文件的时候,它依次在这些目录中查找,直到找到一个或者抛出错误。
gdb还维护了一个路径替换规则,将要搜索的原始路径按照找到的第一个规则做前缀替换,然后再在源码搜索目录中查找文件。

因此,源代码关联默认情况下搜索路径如下:

  1. gdb在编译时目录中搜索 ($cdir : compilation directory)
  2. 当前目录中搜索 ($cwd : current working directory)
  3. 源代码搜索目录列表 (substitute-path)

 除了默认搜索路径,还可以通过如下方式来设置源代码搜索位置和替换规则 

  1. gdb允许明确指定源代码位置,以应付源代码位置迁移的情况。

    • directory path-list:将一个或者多个源代码搜索目录加入到当前源码搜索目录列表的前面,目录之间使用空格间隔。
    • directory:不带参数的directory将源码搜索目录恢复为默认值。
    • set directories path-list:将源码目录设置为path-list,但是会补上默认目录(同 directory path-list)。
    • show directories:显示源码搜索目录列表。

  2. gdb允许设置路径替换规则,以应付源代码位置迁移的情况。

    • set substitute-path from to   :设置目录替换规则,放置在规则列表的末端。
    • unset substitute-path [path] :删除path对应的替换规则,或者删除所有的替换规则。
      show substitute-path [path] :显示path对应的替换规则,或者显示所有的替换规则。

二、gdb 动态库搜索路径

  当gdb无法显示so动态库的信息或者显示信息有误时,通常是由于库搜索路径错误导致的,可使用set sysroot、set solib-absolute-prefix、set solib-search-path来指定库搜索路径。

  1. set sysroot 与 set solib-absolute-prefix 是同一条命令,实际上,set sysroot是set solib-absolute-prefix 的别名。

  2. set solib-search-path设置动态库的搜索路径,该命令可设置多个搜索路径,路径之间使用“:”隔开(在linux中为冒号,DOS和Win32中为分号)。

  3. set solib-absolute-prefix 与 set solib-search-path 的区别:

  总体上来说solib-absolute-prefix设置库的绝对路径前缀,只对绝对路径有效;而solib-search-path设置库的搜索路径,对绝对路径和相对路径均起作用。

  (编译器自动链接的so库多采用绝对路径)。

  在载入动态库信息时Coredump会碰到两种路径:绝对路径和相对路径。编译时链接的库通常是绝对路径,例如"/lib/libc.so.6"、"/lib/libdl.so.2"等,

  此时在Coredump文件中也同样保存为绝对路径;而程序用dlopen函数载入的so库可能使用相对路径,例如"./libddd.so",此时Coredump文件原封不动地保存相同的路径。

  为便于表述,用A表示set solib-absolute-prefix设置的路径,R(A)表示A去掉根前缀后的路径(即去掉前缀“/”符号),用Bn表示set solib-search-path设置的每一条路径,

  用X表示Coredump中保存的库路径,即待搜索的库文件路径,F(X)表示X中去掉目录后的文件名(路径最后“/”符号后的字符串)。

  • 绝对路径,搜索顺序

1) A / X                          ; 先添加solib-absolute-prefix前缀进行搜索,成功则不再继续,否则继续2)

2) R(A) / X                     ; 再把1)的根前缀去掉后进行搜索,成功则不再继续,否则继续3)

3) Bn / R(A) / X               ; 再在2)的基础上逐一添加solib-search-path中的每条路径进行搜索,成功则不再继续,否则继续4)

4) Bn / F(X)                    ; 再只使用2)中的文件名(去掉目录段),并逐一添加solib-search-path中的每条路径进行搜索,成功则不再继续,否则继续5)

5) $PATH / R(A) / X                        ; 在2)的基础上使用环境变量$PATH中的每条路径进行搜索,成功则不再继续,否则继续6)

6) $LD_LIBRARY_PATH / R(A) / X     ;在2)的基础上使用环境变量$LD_LIBRARY_PATH中的每条路径进行搜索,成功则不再继续,否则继续7)

    7) 返回失败

  • 相对路径,搜索顺序

    1) X              ; 直接使用原始路径进行搜索,成功则不再继续,否则继续2)

    2) Bn / X             ; 再逐一添加solib-search-path中的每条路径进行搜索,成功则不再继续,否则继续3)

    3) Bn / F(X)                         ; 再只使用文件名(去掉目录段),并逐一添加solib-search-path中的每条路径进行搜索,成功则不再继续,否则继续4)

    4) $PATH / X                        ; 再使用环境变量$PATH中的每条路径进行搜索,成功则不再继续,否则继续5)

    5) $LD_LIBRARY_PATH / X    ; 再使用环境变量$LD_LIBRARY_PATH中的每条路径进行搜索,成功则不再继续,否则继续6)

    6) 返回失败

    GDB动态库搜索路径: http://blog.csdn.net/_xiao/article/details/23289971

三、gdb 调试-查看机器码

  在一些必要的时候,我们需要查看汇编代码来诊断问题。gdb 提供了这种可能。

  gdb提供了两种能力:

    • 显示源代码位置与指令地址之间的映射;
    • 显示指定位置的汇编代码。
  1. info line xx
    • info line linespec:显示源代码linespec处对应的汇编地址范围。linespec 可以是函数名
    • info line *addr:显示地址addr处对应的源代码位置。

   2.  disassemble,disassemble /m  [/m表示混合输出源代码和汇编代码],disassemble /r [/r表示混合输出二进制和汇编代码]

      显示指定地址范围内的汇编代码,有4种使用形式: [参数可以是16进制的地址,也可以是函数名]

    • 第一种不带参数,显示当前正在执行的函数的汇编代码;
    • 第二 种是一个参数,显示该地址所在函数的汇编代码;
    • 第三种是两个参数的disassemble start,end,显示地址[start,end)内的汇编代码;
    • 第四种是两个参数的 disassemble start,+length,显示地址[start,start+length)内的汇编代码。

    set disassembly-flavor instruction-set:设置显示汇编代码时使用的风格,目前只针对intel x86系列,可取的值为att和intel,默认是att。

    show disassembly-flavor:显示disassembly-flavor设置

    set disassemble-next-line on|off|auto:当程序停止下来的时候,是否显示下一行源代码的汇编代码,默认为off。

    show disassemble-next-line:显示disassemble-next-line设置。

默认情况时,gdb和gcc输出的汇编都是AT&T格式的,但是它们都有方式来转换为Intel格式。
  gcc -S -masm=intel test.c
gdb则是设置环境变量
  set disassembly-flavor intel
  gas事实上也支持Intel格式,只是用得比较少。

四、 gdb + gdbsever 联合调试

参考:

[1]. 使用GDB进行调试:  http://www.cnblogs.com/frydsh/p/3367015.html

  [2]. 使用GDB的源代码查看功能: http://www.cnblogs.com/frydsh/p/3388828.html

gdb 调试的更多相关文章

  1. GDB调试命令小结

    1.启动调试 前置条件:编译生成执行码时带上 -g,如果使用Makefile,通过给CFLAGS指定-g选项,否则调试时没有符号信息.gdb program //最常用的用gdb启动程序,开始调试的方 ...

  2. GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 分析过程 这是我的C源文件:click here 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb ...

  3. gdb调试器的使用

    想要使用gdb调试程序的话,首先需要gcc -g main.c -o test 然后运行gdb test对程序进行调试 l (小写的l,是list的首字母),用以列出程序 回车    是运行上一个命令 ...

  4. 20145212——GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 测试代码 #include <stdio.h> short val = 1; int vv = 2; int g(int xxx) { return xxx + ...

  5. gdb调试PHP扩展错误

    有时候,使用PHP的第三方扩展之后,可能会发生一些错误,这个时候,可能就需要更底层的方式追踪调试程序发生错误的地方和原因,熟悉linux下C编程的肯定不陌生gdb 首先,使用ulimit -c命令,查 ...

  6. gdb调试汇编堆栈过程的学习

    gdb调试汇编堆栈过程的学习 以下为C源文件 使用gcc - g code.c -o code -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 进入之 ...

  7. gdb调试

    ·代码(实验楼中的代码,改了部分数值)命名为test.c int g(int x) { return x + 7; } int f(int x) { return g(x); } int main(v ...

  8. 20145223《信息安全系统设计基础》 GDB调试汇编堆栈过程分析

    20145223<信息安全系统设计基础> GDB调试汇编堆栈过程分析 分析的c语言源码 生成汇编代码--命令:gcc -g example.c -o example -m32 进入gdb调 ...

  9. GDB调试汇编堆栈

    GDB调试汇编堆栈 分析过程 C语言源代码 int g(int x) { return x+6; } int f(int x) { return g(x+1); } int main(void) { ...

  10. 赵文豪 GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 使用gdb调 ...

随机推荐

  1. JAVA hashmap知识整理

    HashMap和Hashtable的比较是Java面试中的常见问题,用来考验程序员是否能够正确使用集合类以及是否可以随机应变使用多种思路解决问题.HashMap的工作原理.ArrayList与Vect ...

  2. 数组map()方法和filter()方法及字符串startsWith(anotherString)和endsWith(anotherString)方法

    map方法的作用不难理解,"映射"嘛,也就是原数组被"映射"成对应新数组 var newArr = arr.map(function() {});例子: var ...

  3. OkHttp和Volley对比

    OkHttp 物理质量 使用OkHttp需要 okio.jar (80k), okhttp.jar(330k)这2个jar包,总大小差不多400k,加上自己的封装,差不多得410k. 功能介绍 Squ ...

  4. android NDK debug 遇到的问题与解决方法

    最近在研究android  NDK 的eclipse调试,遇到点问题,总结一下: 1.Unknown Application ABI :在application.mk里面添加APP_PLATFORM ...

  5. Web前端开发学习心得(一)

    说快也快,说慢也慢.自学前端一个月了,进步不算大,不过仔细想来,倒也收获不少.码几行字,一是总结经验,二是继往开来. 刚开始是跟慕课网学的HTML+CSS,慕课网的课程虽然好,但好多知识都是特别基础的 ...

  6. linux修改mysql密码

    以root为列. 查看文件安装路径whereis mysql   查询运行文件所在路径(文件夹地址) which mysql /usr/bin/mysqld_safe: line 178: 5930 ...

  7. php区分new static 和new self

    关键点在于一个是静态绑定,一个是延迟绑定 <?php class A{ public function __construct() { } public function createObjSt ...

  8. 领域驱动(DD)目录

    领域驱动(DD)目录 1.领域驱动概念 2.通用语言 3.限定上下文

  9. C++中vector的remove用法

      我将从remove的复习开始这个条款,因为remove是STL中最糊涂的算法.误解remove很容易,驱散所有关于remove行为的疑虑——为什么它这么做,它是怎么做的——是很重要的. 这是rem ...

  10. [zz]简单有效,在家就能锻炼!

    简单有效,在家就能锻炼!下面这套动作美腿.美臀.瘦腰,一步到位,是全身塑形的必备,不用多练,每组1分钟.只需一把椅子即可,献给没有时间.条件去健身房的健身爱好者们! http://weibo.com/ ...