高效强大的程序调试工具——gdb(基本命令用法详解)

一、GDB概论

      gdb是GNU debugger的缩写,是编程调试工具。
      UNIX及UNIX-like(Linux)下的调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果 你是在 UNIX平台下做软件,你会发现GDB这个调试工具相比于VC的优点是具有修复网络断点以及恢复链接等功能,比BCB的图 形化调试器有更强大的功能。所谓"尺有所短,寸有所长"就是这个道理。
      只有在编译程序时加了-g选项,才能用gdb工具进行调试。


二、错误分类

      (1)编译错误:编写程序的时候没有符合语言规范导致编译错误。比如:语法错误。编译报错会明确显示哪一行出现了什么错 误,这些错误的解决方案一般来说都是比较固定的,当你写的代码够多,遇到次数多了以后,你一眼就能知道为什么自己写的程 序编译通不过,这就是经验。
      (2)运行时错误:编译器检查不出这种错误,但在运行时候可能会导致程序崩溃。比如:内存地址非法访问。这个时候我们可 以借助调试工具来快速定位程序的问题,而不是一行一行去看代码,也不是在程序中加很多的printf语句查看信息。总而言之,在 实际开发过程中,这是你必需具备的能力。
      (3)逻辑错误:编译和运行都很顺利,但是程序没有按照我们期望来执行程序。这个时候我们也要定位问题,bug出现在什么 地方。


三、功能

一般来说,GDB主要帮助你完成下面五个方面的功能:
1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
3、当程序被停住时,可以检查此时你的程序中所发生的事 即挂载调试。
4、你可以改变你的程序,将一个BUG产生的影响修正从而测试其他BUG。
5、当程序产生核心段错误时,可以进行CORE文件调试,查找错误。


四、使用 启动调试(前提条件,编译代码时有 -g 选项)

      (1) 用gdb启动程序进行调试
             gdb a.out

      (2) 挂载调试
            ps aux | grep a.out       --找到进程pid
            sudo gdb a.out pid       --pid为进程具体的数字id

      (3)程序核心已转储(段错误)
            gdb a.out -c core
            在程序崩溃时,一般会生成一个文件叫core文件。core文件记录的是程序崩溃时的内存映像,并加入调试信息,core文件生 成过程叫做core dump(核心已转储)。系统默认不会生成该文件。只需要简单设置即可看到core文件。

            
            设置生成core文件
            ulimit -c:查看core-dump状态。
            ulimit -c xxxx:设置core文件的大小。
            ulimit -c unlimited:core文件无限制大小。

            配置corefile的参数:
            echo 2 > /proc/sys/fs/suid_dumpable [程序中切换用户,也要产生corefile]
            mkdir /tmp/corefiles
            chmod 777 /tmp/corefiles
            echo “/tmp/corefiles/core”>/proc/sys/kernel/core_pattern //配置core文件产生的目录 为/tmp/corefiles
            echo “1” > /proc/sys/kernel/core_uses_pid

            注意:
                a.确保配置的目录有足够的磁盘空间,否则产生core文件可能不完整。
                b.对于mysqld而言,要保证正确产生core-file,需要加上–core-file,默认这个参数是不打开的。 c.kill -9 pid 是不能产生core文件的,因为SIGKILL信号不能被捕获。

            附:
          gdb 直接启动gdb,之后用file program加载程序
          gdb program 普通调试
          gdb program -c core 调试core
          sudo gdb program pid 挂载调试 程序正在运行 得用sudo权限
          sudo gdb attach pid dump已经运行进程的状态信息
          如: gdb attach pid
          (gdb) generate-core-file 调试完毕后,通过detach命令退出。
          另外,通过gcore pid命令也可以dump core文件,生成在当前目录下


五、命令

1、运行程序
      run(r)运行程序,如果要加参数,则是run arg1 arg2 …

2、查看源代码
      list(l):查看最近十行源码
      list fun:查看fun函数源代码
      list file:fun:查看flie文件中的fun函数源代码

3、设置断点与观察断点
      break 行号/fun设置断点。
      break file:行号/fun设置断点。
      break if:条件成立时程序停住。
      info break(缩写:i b):查看断点。
      watch expr:一旦expr值发生改变,程序停住。
      delete n:删除断点。

4、单步调试
      continue(c):运行至下一个断点。
      step(s):单步跟踪,进入函数,类似于VC中的step in。
      next(n):单步跟踪,不进入函数,类似于VC中的step out。
      finish:运行程序,知道当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息。
      until:当厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序知道退出循环体。

5、查看运行时数据
      print(p):查看运行时的变量以及表达式。
      ptype:查看类型。
      print array:打印数组所有元素。
      print *array@len:查看动态内存。len是查看数组array的元素个数。
      print x=5:改变运行时数据。


命令命令缩写命令说明
listl

显示多行源代码 list lineNum

在lineNum的前后源代码显示

list +列出当前行的后面代码行

list -列出当前行的前面代码行

list function 显示函数代码

set listsize count 设置显示代码的行数

show listsize    显示打印代码的行数

list first,last    显示从first到last行的源代码

breakb

设置断点,程序运行到断点的位置会停下来

break[linespec] thread [threadno] [if condition]

break [filename:]line-number 使程序恰好在执行给定行之前停止

break [filename:]function-name 使程序恰好在进入指定函数之前停止

break [filename:]line-or-function if condition 如果条件成立在指定行或者函数之前停止

break [filename:]routine-name 在指定例程的入口处设置断点

断点管理:

1.显示断点信息       info break

2.删除指定断点       delete breakpoint number         不指定编号将全部删除

3.禁用断点       disable breakpoint number

4.恢复断点       enable breakpoint number

5.清除行上断点       clear number

infoi

描述程序的状态

info locals       打印出当前函数中所有局部变量及其值

info args       打印出当前函数的参数名及其值

info threads       打印出当前进程的线程号及其信息

thread

info threads 查看线程
thread thread trhead_no
切换到线程thread_no thread apply all command 所有线程都执行命令打印栈桢

(1)线程锁
show scheduler-locking
set scheduler-locking on
set scheduler-locking off 默认是off,当程序继续运行的时候如果有断点,那么就把所有的线程都停下来,直到你指定某个线程 继续执行
thread trhead_no apply continue
但是如果直接在当前线程执行continue的话,默认是会启动所有线程,这种模式有一种副作用,如果 多个线程都数断在同一个函数,这时候调用会出问题。这个时候需要打开线程锁,但打开线程锁,意 味着其它线程不能运行了。

(2)non-stop模式(7.0以后的版本支持)
set target-async 1
set pagination off
set non-stop on
gdb启动了不停模式,除了断点有关的线程会被停下来,其它线程会执行

runr

开始运行程序

displaydisp

跟踪查看某个变量,每次停下来都显示它的值

自动打印变量的值

undisplay 取消自动打印

steps

执行下一条语句,如果该语句为函数调用,则进入函数执行其中的第一条语句

nextn

执行下一条语句,如果该语句为函数调用,不会进入函数内部执行(即不会一步步地调试函数内部语句)

printp

打印内部变量值

p num(打印单个变量的值)

p func(1,0) 调用函数,打印其返回值

p *table 打印结构体、类、容器等数据类型和对象的数据

base@length 构造数组,显示内存块数据

如:显示在h后面的10个元素,可以使用 h@10

print h@10

p variable = value 赋值 显示

可以通过添加参数来调协输出格式:

/x   /d   /u    /o    /t(二进制格式) /a   /c    /f

continuec

设置

set vaiable = value     设置变量的值

set print elements N   指定打印的长度,对长字符串特别有用

set print elements 0   输出完整的字符串

set print pretty           设置GDB打印结构的时候,每行一个成员,并且有相应的缩进,缺省是关闭 的

startst

开始执行程序,在main函数的第一条语句前面停下来

filest

装入需要调试的程序

直接启动gdb

file a.out 加载a.out程序

killst

开始执行程序,在main函数的第一条语句前面停下来

watchk

监视变量值的变化

watch + [变量][表达式]           当变量或表达式值发生改变,程序停住

rwatch + [变量][表达式]           当变量或表达式被读时,程序停住

awatch +[变量][表达式]           当变量或表达式被读或被写时,程序停住

catch

catch + event       当event发生时,程序停住
event可以是以下内容:

1. throw 一个C++抛出的异常   (throw为关键字)

2. throw 一个C++捕捉到的异常   (catch为关键字)

3. exec 调用系统调用exec时。(exec为关键字,目前此功能只在HP-UX下有用)

4. fork 调用系统调用fork时。(fork为关键字,目前此功能只在HP-UX下有用)

5. vfork 调用系统调用vfork时。(vfork为关键字,目前此功能只在HP-UX下有用)

6. load 或 load 载入共享库(动态链接库)时。(load为关键字,目前此功能只在HP-UX下有用)

7. unload 或 unload 卸载共享库(动态链接库)时。(unload为关键字,目前此功能只在HP-UX下 有用

handlest

handle + [argu] + signals

signals:是Linux/Unix定义的信号,SIGINT表示中断字符信号,也就是Ctrl+C的信号,SIGBUS表示硬 件故障的信号;SIGCHLD表示子进程状态改变信号; SIGKILL表示终止程序运行的信号,等等。

argu:
1. nostop 当被调试的程序收到信号时,GDB不会停住程序的运行,但会打出消息告诉你收到这种信 号。
2.stop 当被调试的程序收到信号时,GDB会停住你的程序。
3.print 当被调试的程序收到信号时,GDB会显示出一条信息。
4.noprint 当被调试的程序收到信号时,GDB不会告诉你收到信号的信息。
5.pass or noignore 当被调试的程序收到信号时,GDB不处理信号。这表示,GDB会把这个信号交给被调试程序会处理。
6.nopass or ignore 当被调试的程序收到信号时,GDB不会让被调试程序来处理这个信号。

backtracebt

产看函数调用信息(堆栈)

framef

查看栈帧

quitq

退出GDB环境

whatis

显示变量的类型

ptype

比whatis功能更强,可以提供一个结构的定义

examine

examine /n f u + 内存地址 (指针变量)

n表示显示内存长度

f表示输出格式

u表示字节数制定(b 单字节 h双字节 w四字节(默认) g八字节)

call

调用函数

call func(1,2)

finish结束执行当前函数,显示其返回值(如果有)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值