gdb 调试学习

  gdb 是unix/linux 系统下的程序调试工具,和IDE(如VS, Eclipse等)的图形化调试工具相比,gdb在断点,跟踪显示方面有着不足,但是它在某些方面比图形化调试工具更加丰富的功能。

gdb 调试前提

  如果希望程序能够被gdb调试,则需要在编译程序时候,指定 -g 选项。 gdb 的调试和程序的release 优化一样,也存在着级别,可以手动设置。默认的gdb级别为2, 当把gdb的调试级别设置为3的时候,可以在gdb调试过程中 macro expand/exp  对程序中的宏定义进行展开。

gdb 调试的图形化工具

  gdb本身不带图形化界面,这样在调试中难以方便的知道程序当前的上下文。为了克服这一弱点,gdb也增加了一些图形化的工具集,如 gdb -tui。使用 $ gdb -tui 程序名 可以进入gdb的图形化调试状态。或者执行 $ gdb 程序名   进入命令行调试,然后执行 ctrl + x + A 开启 tui 模式,ctrl + x + A 关闭tui模式。

gdb 调试的常用指令

调试前的准备

1. 设置运行参数

set args 可设置运行时参数, set args -ip "192.168.0.1" -port 6555

show args 可以显示运行时参数

2. 运行环境

path 可设定程序的运行路径

show paths 显示程序的运行路径

set environment varname = value 可以设置环境变量

show environment varname 可以显示环境变量

3.工作目录

cd 相当于shell的cd

pwd 显示当前所在的目录

4. 程序的输入输出

info terminal  显示程序用到的终端的模式

使用重定向控制程序的输出,如 r (run) > outfile

常用命令

GDB常用命令 格式 含义 简写
list List [开始,结束] 列出文件的代码清单 l
prit Print 变量名 打印变量内容 p
break Break [行号或函数名] 设置断点 b
continue Continue [开始,结束] 继续运行 c
finish finish 继续运行直到程序结束  
info Info 变量名 列出信息 i
next Next 下一行 n
step Step 进入函数(步入) s
until until 行号 运行到指定的行 u
display Display 变量名/ 表达式 显示参数或者表达式的值  
file File 文件名(可以是绝对路径和相对路径) 加载文件  
run Run args 运行程序 r
enable enable b (num) / display (num) 使 断点/显示 有效  
disable disable b (num)/ display (num) 使断点/显示 无效  
clear clearn filename:linenumber(filename为空表示当前文件) 删除设置在特定源文件、特定行上的断点。  
backtrace bt 查看函数调用的栈帧 bt
回车   重复上一条命令  

info break 显示当前断点清单,包括到达断点处的次数等。
info files 显示被调试文件的详细信息。
info func 显示所有的函数名称。
info local 显示当函数中的局部变量信息。
info prog 显示被调试程序的执行状态。
info var 显示所有的全局和静态变量名称。
kill 终止正被调试的程序。

l(list)  filename: line_number 用来显示指定文件的行

断点

b (break) 行号 在指定行添加断点

b(break) 函数名 在制定函数前添加断点

b(break) filename:行号  在指定文件的指定行之前添加断点

b(break) filename:函数名  在指定文件的指定函数前添加断点

b(break) *address 在程序运行到指定的内存地址处停止

b(break) ...  if  ...  条件断点, 如 break  337 if i == 0

info b 列出所有的断点信息

d  删除所有的断点, d number 删除number号断点

condition break-num conds 当在conds条件满足时,break-num被触发。可以用来设置或者修改断点的条件。

condition break-num 使break-num的断点无条件。

观察点

watch 一旦表达式值有变化,马上停止程序

rwatch 当表达式/变量被读时,停止程序

awatch 当表达式/变量 被读或写时,停止程序

info watchpoints 列出所有的观察点

观察点删除,使用 d 观察点的序号(info b 可以列出所有断点 + 观察点 + 的情况)

为停止点设置运行命令(实用功能)

commands [break-num]

 ...command list....

end

为断点 break-num 指定一个命令列表,当在停止点处停止时,gdb依次执行列表中的命令

调试子进程

1. set-follow-fork-mode

gdb 中 可以设置对使用fork/vfork的方式产生子进程的程序进行多进程调试。

set-follow-fork-mode  parent  在fork/vfork之后继续对父进程进行调试

set-follow-fork-mode child 在fork/vfork之后继续对子进程进行调试

(gdb) set follow-fork-mode child
(gdb) break 子进程行号

2. attach (gdb在调试一个进程的时候,使用attach 另一个进程的PID, 调试另一个进程,调试完之后,detach 释放另一个进程,继续调试本进程)

attach 命令可以绑定一个外部程序进行调试,attach  进程的PID

假设要调试进程 proc1  的子进程,使用 ps -ef |grep proc1 找出子进程的PID, 然后 (gdb) attach 子进程PID 即可。

调试完之后,使用detach PID释放子进程,继续对父进程进行调试。

自定义调试节奏

gdb 可以自定义命令来简化方便调试过程,命令定义在文件 .gdbinit 文件中,格式为:

define <command>
<code>
end
document <command>
<help text>
end

查看宏定义

首先在编译时加入参数 ‘-gdwarf-2’ ‘-g3’ :
$ gcc -gdwarf-2 -g3 sample.c -o sample

用于通知gcc编译器在编译时加入扩展信息.
* info macro <macro name> : 显示宏的信息
* macro expand expression : 展开表达式expression. 但是不会显示表达式结果.
假设有定义 #define ADD(x,y) (x)+(y) 那么
(gdb) macro expand ADD(7,8)
expands to: (7)+(8)

gdb tui 模式的常用选项

执行gdb -tui 程序名,自动进入tui模式的 layout src 模式,即 窗口上方显示程序源码,下方为命令窗口。

layout src  默认模式,上方为程序源码,下方为命令窗口

layout asm 上方显示程序的汇编代码,下方为命令窗口

layout split  三个窗口,上方为src, 中间为 asm,下方为cmd

layout reg  在最上方(src 的上方或asm的上方)显示寄存器窗口

tui reg general  显示通用寄存器

tui reg float 显示浮点寄存器

tui reg system 显示系统寄存器

tui reg next 显示寄存器的下一页

focus  src/asm/cmd/reg  将光标切换到指定窗口

refresh 刷新所有窗口

update 更新源代码窗口和当前执行点

winheight name +/- line 调整name窗口的高度

gdb 调试core dump

  程序可能会出现随机性的运行时崩溃,这种崩溃一般很难重现。可以使用core dump文件来调试这种问题。core dump文件是程序在发生崩溃的时候系统所产生的记录文件。

ulimit -c 查看系统设置的core 文件大小限制,ulimit -c size 设置系统设置的core 文件的大小,如 ulimit -c unlimited 设置大小无限制 // 设置只对当前shell有效

  debug版的程序在运行时出错,生成core文件后。使用gdb 对core文件进行调试,可以调试随机性的错误。

$ gdb 程序名  core文件

启动之后,就和正常gdb一样调试。

时间: 2024-10-12 21:11:24

gdb 调试学习的相关文章

GDB调试总结__1

该博客旨在分享IT技术心得和实际工作中遇到问题的解决方法,下面是新浪博客地址http://blog.sina.com.cn/qianyumolu,则为分享经济.行业趋势.心灵文章等,有兴趣的朋友能够踩踩,讨论分享    也欢迎来群里一起学习交流http://url.cn/LJhxoQ -----------------------------------------------------------------------------------------------------------

linux学习之四---gdb调试

在Linux应用程序开发中,最常用的调试器是gdb. 一.启动和退出gdb gdb调试的对象是可执行文件,而不是程序的源代码.如果要使一个可执行文件可以被gdb调试,那么使用编译器gcc编译时需要加入-g选项,-g选项告诉gcc在编译时加入调试信息,这样gdb才可以调试这个被编译的程序. 1.编译test.c源程序 gcc -g test.c -o test ./test test.c中的源码为: #include<stdio.h> int get_sum(int n) { int sum=0

gdb调试命令

本篇摘自互联网,纯属自己学习笔记,然分享给看到我的博客的人们. 用GDB调试程序 GDB是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形成执行序列,形成脚本.UNIX下的软件全是命令行的,这给程序开发提代供了极大的便利,命令行软件的优势在于,它们可以非常容易的集成在一起,使用几个简单的已有工具的命令,就可以做出一个非常强大的功能. 于是UNIX下的软件比Windows下的软件更能有机地结合,各自发挥各自的长处,组合成更为强劲的功能.而Windows下的图形软件基本上是各自为营,

GDB调试汇编分析

GDB调试汇编分析 代码 本次实践我参照了许多先做了的同学的博客,有卢肖明,高其,张梓靖同学.代码借用的是卢肖明同学的代码进行调试运行. GCC编译 使用gcc -g gdbtest.c -o gdbtest -m32命令在64位的机器上产生32位汇编代码 在使用gdb进行调试运行时,有cgdb和gdb两种工具,我建议大家使用张梓靖同学使用的cgdb工具,因为使用时可以随时看到自己的源代码,看到我们的断点在哪里,每一步返回值到了哪行,更加直观. 分析过程 使用b main指令在main函数处设置

[转]GDB调试基础

一.gdb常用命令: 命令 描述 backtrace(或bt) 查看各级函数调用及参数 finish 连续运行到当前函数返回为止,然后停下来等待命令 frame(或f) 帧编号 选择栈帧 info(或i) locals 查看当前栈帧局部变量的值 list(或l) 列出源代码,接着上次的位置往下列,每次列10行 list 行号 列出从第几行开始的源代码 list 函数名 列出某个函数的源代码 next(或n) 执行下一行语句 print(或p) 打印表达式的值,通过表达式可以修改变量的值或者调用函

使用 gdb 调试运行中的 Python 进程

本文和大家分享的是使用 gdb 调试运行中的 Python 进程相关内容,一起来看看吧,希望对大家学习python有所帮助. 准备工作 安装 gdb 和 python2.7-dbg: $ sudo apt-get install gdb python2.7-dbg 设置 /proc/sys/kernel/yama/ptrace_scope: $ sudo su# echo 0 > /proc/sys/kernel/yama/ptrace_scope 运行 test.py: $ python te

gdb调试运行时的程序小技巧

使用gdb调试运行时的程序小技巧 标签: 未分类 gdb pstack | 发表时间:2012-10-15 04:32 | 作者:士豪 分享到: 出处:http://rdc.taobao.com/blog/cs 原创文章,欢迎转载.转载请注明:转载自淘宝核心系统团队博客,谢谢! 原文链接地址: 使用gdb调试运行时的程序小技巧 下面介绍我调试时经常遇到的三种问题,如果大家也有类似的问题交流一下解决方法: 情景1:在不中止程序服务的情况下,怎么调试正在运行时的程序 情景2:需要同时看几个变量的值或

linux平台学x86汇编(五):使用gdb调试汇编程序

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 正如C语言一样,编写所有语言程序一样会出现一些一些错误,发生错误时,我们可以使用调试器一步一步运行程序以监视数据是如何被处理的.本节使用GNU调试器检查上一节hello程序,监视处理过程中寄存器和内存的值的变化.要调试汇编语言程序,在编译时,需要使用-gstabs参数重新汇编源代码,使用了该参数编译出来的可执行文件要比之前稍大一些,因为添加了附加信息.上一节程序不使用-gst

GDB调试汇编堆栈过程分析

首先我自己编译个代码,无非就是调用函数吗. 在这里我先大致手绘了一张整个程序在存储空间的汇编代码(根据P239上的汇编代码) 然后对其进行汇编.进入gdb,获得main的汇编代码. 给 sum 设置断点 获取sum的汇编代码 首先我分析一下该汇编代码: 按照书上P238所讲的,首先会初始化&esp和%ebp,这里并没有看到,我猜测是因为我们所设置的断电是给main函数的,所以只显示执行main时的汇编代码. 初始化栈指针和帧指针之后,就执行call main,然后%ebp入栈,%ebp保存%es