gdb 调试
一、gdb 调试-源代码关联
在调试程序的过程中,可以自由地查看相关的源代码(如果有源代码的话)是一项最基本的特性。gdb 当然也提供了这项特性,虽然不如IDE直观,但在一定程度上要比IDE更加灵活和快捷。
gdb之所以能够知道对应的源代码,是因为调试版的可执行程序中记录了源代码的位置;因为源代码的位置在编译之后可能会移动到其它地方,所以gdb还会在当前目录中查找源代码,另外gdb也允许明确指定源代码的搜索位置。
在一个调试会话中,gdb维护了一个源代码查找目录列表,默认值是编译目录和当前工作目录。当gdb需要一个源文件的时候,它依次在这些目录中查找,直到找到一个或者抛出错误。
gdb还维护了一个路径替换规则,将要搜索的原始路径按照找到的第一个规则做前缀替换,然后再在源码搜索目录中查找文件。
因此,源代码关联默认情况下搜索路径如下:
- gdb在编译时目录中搜索 ($cdir : compilation directory)
- 当前目录中搜索 ($cwd : current working directory)
- 源代码搜索目录列表 (substitute-path)
除了默认搜索路径,还可以通过如下方式来设置源代码搜索位置和替换规则
- 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提供了两种能力:
- 显示源代码位置与指令地址之间的映射;
- 显示指定位置的汇编代码。
- 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 调试的更多相关文章
- GDB调试命令小结
1.启动调试 前置条件:编译生成执行码时带上 -g,如果使用Makefile,通过给CFLAGS指定-g选项,否则调试时没有符号信息.gdb program //最常用的用gdb启动程序,开始调试的方 ...
- GDB调试汇编堆栈过程分析
GDB调试汇编堆栈过程分析 分析过程 这是我的C源文件:click here 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb ...
- gdb调试器的使用
想要使用gdb调试程序的话,首先需要gcc -g main.c -o test 然后运行gdb test对程序进行调试 l (小写的l,是list的首字母),用以列出程序 回车 是运行上一个命令 ...
- 20145212——GDB调试汇编堆栈过程分析
GDB调试汇编堆栈过程分析 测试代码 #include <stdio.h> short val = 1; int vv = 2; int g(int xxx) { return xxx + ...
- gdb调试PHP扩展错误
有时候,使用PHP的第三方扩展之后,可能会发生一些错误,这个时候,可能就需要更底层的方式追踪调试程序发生错误的地方和原因,熟悉linux下C编程的肯定不陌生gdb 首先,使用ulimit -c命令,查 ...
- gdb调试汇编堆栈过程的学习
gdb调试汇编堆栈过程的学习 以下为C源文件 使用gcc - g code.c -o code -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 进入之 ...
- gdb调试
·代码(实验楼中的代码,改了部分数值)命名为test.c int g(int x) { return x + 7; } int f(int x) { return g(x); } int main(v ...
- 20145223《信息安全系统设计基础》 GDB调试汇编堆栈过程分析
20145223<信息安全系统设计基础> GDB调试汇编堆栈过程分析 分析的c语言源码 生成汇编代码--命令:gcc -g example.c -o example -m32 进入gdb调 ...
- GDB调试汇编堆栈
GDB调试汇编堆栈 分析过程 C语言源代码 int g(int x) { return x+6; } int f(int x) { return g(x+1); } int main(void) { ...
- 赵文豪 GDB调试汇编堆栈过程分析
GDB调试汇编堆栈过程分析 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 使用gdb调 ...
随机推荐
- React组件性能优化
转自:https://segmentfault.com/a/1190000006100489 React: 一个用于构建用户界面的JAVASCRIPT库. React仅仅专注于UI层:它使用虚拟DOM ...
- c++宏使用总结【转】
C/C++中宏总结C程序的源代码中可包括各种编译指令,这些指令称为预处理命令.虽然它们实际上不是C语言的一部分,但却扩展了C程序设计的环境. ANSI标准定义的C语言预处理程序包括下列命令: #de ...
- Python + Selenium 实现登录Office 365
最近捡起之前用的Python + Selenium实现工作中需要的登录Office 365功能.(吐槽:国内网络真是卡,登录Office 365实属不易.另外Selenium这样的网站都要墙,无法理解 ...
- 查看死锁 的存储过程 ,工具存储过程 sp_who_lock
http://blog.sina.com.cn/s/blog_95b5eb8c010162jp.html if exists (select * from dbo.sysobjects where i ...
- JavaScript中的arguments,callee,caller
在提到上述的概念之前,首先想说说javascript中函数的隐含参数: arguments: arguments 该对象代表正在执行的函数和调用它的函数的参数. [function.]argument ...
- SQL 事务隔离学习
select --* request_session_id as spid, resource_type as restype, resource_database_id as dbid, DB_NA ...
- Mybatis与Hibernate的区别
首先简单介绍下两者的概念: Hibernate :Hibernate 是当前最流行的ORM框架,对数据库结构提供了较为完整的封装. Mybatis:Mybatis同样也是非常流行的ORM框架,主要着力 ...
- xampp出现 Access forbidden! 问题解决
解决 XAMPP 出现 A今天安装了XAMPP 试了下,增加虚拟主机时出现没权限,apache配置文件httpd.conf的allow属性,把下图中的文字注释掉: 然后公开于外网出现以下错误,也很容易 ...
- Realitymining 数据集简单介绍与使用
数据集的官网 http://realitycommons.media.mit.edu/index.html(可能需要FQ) ,下面是数据集的简要介绍(摘自官方网站) The goal of this ...
- 【学】React的学习之旅5-组件的嵌套
复习 [array].map(function(item,index){})方法,传参里的函数需要有return值,一般用map()后都要用一个变量接一下,这个返回的还是一个数组,只是把每次遍历到的数 ...