notice:coredump章节、汇编章节还需要完善

预备知识:

1、注意使用gdb时,最好带上-g参数编译可执行文件。否则出现(No debugging symbols found in a.out)

gcc -g main.c -o a.out

2、查看命令行可带参数帮助

gdb --help

3、查看命令行可使用命令及详情

(gdb) help all       //查看所有命令
(gdb) help break  //查看break 使用,其他命令也可单独help

4、gdb 长选项 -和--都可以 

gdb --help 和 gdb -help 都可以

5、gdb 使用的命令不必完整,只需命令的前面几个字母即可(只要无歧义),可以tab补全

6、回车会重复执行上一次命令

7、查看gdb版本

(gdb) show version
或者gdb -v

 

1、gdb 命令行可带参数

 

参数

作用

示例

相关命令

--args或-args

向可执行文件传递参数

gdb --args a.out xxx 111

向a.out可执行文件传递参数 xxx和111

set args xxx 111

show args

-p或--pid

attach

指定attach进程

gdb -p 进程PID

gdb attach 进程PID

 

-c或-c=

--core或者--core=

指定coredump文件

gdb a.out core.27503

gdb a.out --core core.27503

gdb a.out --core=core.27503

 

-e

指定可执行文件名

 

 

-d

指定目录加入到源文件搜索路径

 

 

--cd

指定目录作为路径运行gdb

 

 

-s

指定文件读取符号表

 

 

-q

gdb 启动时,关掉提示或者打印信息

gdb  -q a.out

 

 

2、gdb 调试可使用命令及参数

2.1 断点

命令

含义

示例

相关命令

break

或b

设置断点

break local-break

break local-break if if-command

local-break格式为:

  函数名(function-name)

  文件名:行号(b  main.c:5)

  文件名:函数名(b  main.c:main)

  函数A:A调用的函数B(b main:test_b)

  +offset-number 以当前程序暂停位置为准,向后+ offset-number 行设置break 点

  -offset-number 以当前程序暂停位置为准,向前- offset-number 行设置break 点

  beadk  *address

if-command格式为:

  shell 脚本 (例如 break main if argc == 5 断到main时都判断 argc == 5 ,为真才停住)

print 函数名 得到函数地址

ignore break-number count-number

info break或i b

查看所有断点

 

 

delete或 d

删除断点

delete break-number-xxx

或者 d break-number-xxx

 

tbreak或tb

设置断点,但只生效一次

 

 

save breakpoints  file-name

保存断点到file-name

 

 

source file-name

加载保存的gdb断点

 

 

ignore break-number count-number

设置断点,但是忽略断点多少次,接下来count-number次编号的断点触发都不会让程序中断,只有count-number+1次触发的中断才会让程序中断

 

 

command

当运行到某断点时,执行某指定的脚本或程序

command command-number

当运行到断点时,执行的命令(commands 即可输入gdb命令等,end表示退出输入)

 

//在程序入口处打断点
readlef -h a.out 中  ertry point addrss   //获取程序入口
gdb 查看 info  files  中  entry point        //获取程序入口

b *程序起始地址
然后  run

2.2 运行/调试/退出程序

命令

含义

示例

相关命令

step

(区别:step会进入有符号表的下一行函数内部,next不会进入)

 

 

next

 单步执行

 

 

run或r

从头运行可执行文件

run para_1 para_2 para_3

run可以直接携带参数

 

start

直接运行程序

调试没有调试信息程序,直接运行是无效的。找不到main入口。

调试没有调试信息的可参考:调试无调试信息程序

 

 

continue或c

继续运行可执行程序

 

 

quit或q

 退出gdb

 

 

finish

执行完当前函数

 

 

return

函数不会继续执行,直接按照指定的返回值xxx返回

return 返回值xxx

 

call  或 print

直接调用函数执行

call  xxxx_func()

 

set args

设置可执行文件运行参数

set args xxx 111

(参数会保留,直接清空则使用set args  )

 

show args

查看可执行文件携带参数

 

 

set

改变变量的值

set main::string_test="xxxxx" 改变main函数中字符串string_test

或通过内存地址改变变量(字符串)

p &p1 查看p1类型变量 (char (*)[4]) 0x80477a4

set {char [4]}0x80477a4 = "xxxxx"

设置变量的值 set var var_param = 3 或者

set{para_type}para_address=para_number

修改寄存器的值 set var $eax = 3

 

jump

跳转到指定地址执行(PC寄存器保存程序下一条要执行的指令,通过修改这个寄存器的值,可以修改程序执行的流程)

 

 

2.3 函数/堆栈/帧

命令

含义

示例

相关命令

backtrace或bt

打印此时的堆栈情况

 backtrace full(显示所以局部变量值)

 

info frame

显示函数堆栈帧

 

 

frame

切到第几个栈帧上

frame  number。切到第几个栈帧上,

frame   address 切到指定栈地址上

(bt可以查看到内层的函数在第几个栈帧上)

info frame

up 

向上切换栈帧。默认up 1,可以指定up n

 

 

down

向下切换栈帧,默认 down 1,可以指定 down n

 

 


up-silently

安静向上切换栈帧,不打印

 

 

down-silently

安静向下切换栈帧,不打印

 

 

debug entry-values

可以输出正常堆栈,以及尾调用关系

(尾调用会被优化)

 

 

P func2:pointer

打印某函数内部的变量(打印某栈帧中变量)

或先切换到该栈帧(函数)中,然后打印

 

 

2.4 打印/查看命令

 

//gdb中直接显示的打印静态变量,可能不一定是正确的,(全局变量和局部变量重名情况)可以直接指定文件 p xxx.c::xxx_para

 

 

 

命令

含义

示例(打印变量a)

相关命令

print

或者p

变量

(可强转变量类型)

直接打印变量

默认10进制

 

 

/x

十六进程打印

 

 

/o

8进程打印

 

 

/u

无符号打印(10进制)

 

 

/d

有符号打印(10进制)

 

 

/t

二进制打印

 

 

/c

字符打印

 

 

/s

字符串打印

 

 

/f

浮点打印

 

 

/a

16进制打印

 

 

array@length

打印array数组的前length个变量的值

 

 

p array[index]@number或p *array@number

打印数组中任意元素连续元素的值

 

 

func2:pointer

打印某函数内部的变量(打印某栈帧中变量)

 

 

 

命令

含义

示例

相关命令

x/nfu

n

按照u类型为单位,输出指定地址n个

 

 

f

输出格式进制:x(16)、o(8)、d(10)、h(2)、s(字符)

 

 

u

单个单元长度:b(一个byte)、h(两个byte)、

w(四个byte)、g(8个byte)

 

 

$_

保存着x命令最后检测的内存地址(很多命令都会调用x命令检查内存)

 

 

$__

保存着x命令最后检测的内存地址的值

 

 

 

命令

含义

示例

相关命令

set print pretty on/off

每行打印一个结构体成员

 

 

set print array on/off

设置数组打印

 

 

set print array-indexes on/off

设置数组下标

(数组默认不打印索引下标)

 

 

set print union on/off

设置打印联合体

 

 

set print elements number-of-elements

设置数组最大限制数

(缺省最多打印200个元素)

set print elements 0

(设置为0,等效于不设置限制)

 

set print elements unlimited

不设置限制

 

 

set print object on

如果缺省按照派生类打印

 

 

set pagination off

设置gdb不提示,直接输出全部内容

(当单次输出内容较多时,gdb会打印部分内容,并提示是否输出后面内容)

 

 

 

命令

含义

示例

相关命令

list或l

打印代码

(list 可以带行号、函数、指定行号范围(1、10)、向前向后打印(-、+))

 

 

where

显示当前行号以及所处函数

 

 

 

命令

含义 

示例 

相关命令 

backtrace full

打印函数的局部变量

 

 

backtrace full n

从内向外显示n个栈帧

 

 

backtrace full -n

从外向内显示n个栈帧

 

 

info locals

打印当前函数局部变量

 

 

 

命令

含义

示例

相关命令

whatis xxx_para

查看某一个变量类型

 

 

ptype xxx_para

查看更详细的信息类型

 

 

info variables xxx_para

查看定义变量的文件

info variables ^xxx_para$

(可以通配查找)

 

mallocinfo

打印程序动态分配的内存

 

 

 

2.5 coredump文件

命令

含义 

示例 

相关命令 

 generate-core-file 或 gcore

被调试进程主动产生core dump文件

 

 

 core

 在gdb中指定coredump文件

(一般前面先file 可执行文件)

 

 

gdb 可执行文件 coredump的文件

解析coredump文件

 

 

2.6 进程/线程

//gdb调试多进程时候默认追踪父进程,子进程独立运行
//info threads 
//显示信息:
//第一项ID:gdb标识每个线程的唯一ID,
//第二项 Target id:linux 对每一个线程的标识ID
//第三项 Frame :显示的是线程执行到哪个函数,理解为GDB。前面带*表示的是current thread,及gdb attach进程时,默认attach的线程。

 

命令

含义

示例

相关命令

info thread

列出当前进程的线程

 info threads

或info threads th-pid

 

 thread 

 切换到指定线程

thread 线程-PID  

 

info proc mappings

查看进程的内存映射信息  

 

 

info files或info target

查看进程的内存映射信息以及库情况

 

 

attach

跟踪进程

 

 

detach

脱离进程

 

 

set follow-fork-mode child 

调试子进程

 

 

set detach-on-fork off 

同时调试父子进程(默认detach-on-fork 是on的状态)在调试一个进程时,另外一个进程处于挂起

 

 

info inferiors 

查看进程情况 ,显示*表示正在调试进程

 

 

inferiors info-number 

切换到调试进程去

 

 

set schedule-multiplen on 

父子进程同时运行,默认 schdule-multiple 是off的

 

 

set print thread-events off

线程产生和退出时的打印提示信息

 

 

set scheduler-locking on

gdb调试多线程程序时,只允许一个调试线程运行,其他处于暂停状态(默认是off状态)

 

 

$_thread

用来保存当前正在调试的线程号(gdb 7.2引入)

 

 

add-inferior [ -copies n ] [ -exec executable ]

gdb 同时调试多个程序,加载可执行文件 ,n 默认是1

 

 

maint info program-spaces 

打印当前所有被调试的进程信息(调试多个进程)

 

 

$_exitcode

记录调试程序正常退出的exit code

 

 

 

2.7 观察点/异常捕获

//观察点有软件和硬件两种,软件实现的观察点会导致程序运行较慢。
//如果支持硬件观察点,则设置观察点时会打印Hardware watchpoint 2: i
//系统调用和编号的映射关系为 include/asm/unisted.h

 

命令

含义

示例

相关命令

watch

当一个变量的值发生变化时,程序会停止下来

watch para_a

 

set can-use-hw-watchpoint

不使用硬件观察点

 

 

info watchpoint

罗列当前所有的观察点

 

 

disable

去使能观察点

disable para_a

 

enable

使能观察点

 

 

delete

删除观察点

 

 

watch 观察表达式 thread thread-number 

设置观察点,只有特定线程才生效(这种只能使用硬件观察)

 

 

rwatch或rw

设置读观察点,当发生读时,会暂停住(这种只能使用硬件观察)

 

 

awatch 或aw

设置写观察点(这种只能使用硬件观察)

 

 

catchpoint或catch

异常捕获

catch syscall [name | number] 系统调用的名字或者

系统调用编号

catch 函数名

catch signal signal-number

catch syscall :为所有的系统调用设置catchpoint

其他可以help catch

 

tcatch

设置 catchpoint 只生效一次

 

 

 

2.8 日志相关

//gdb中,默认是不保存历史命令的,可以通过如下命令设置成保存历史命令。

命令

含义

示例

相关命令

set history filename file_name

设置历史命令保存在文件file_name中

(默认保存在.gdb_history)

 

 

set history save on 

设置保存历史命令

 

 

set logging on

执行gdb的过程记录下来

(默认的日志文件是gdb.txt)

 

 

set logging file file-name

改变日志记录文件为file-name

 

 

set logging overwrite on

让输出覆盖之前的日志文件

 

 

set logging redirect on

gdb的日志不会打印在终端

 

 

2.9 汇编/寄存器

 

//若需预处理器宏信息,需要带 -g3编译 p NAME
//gdb默认显示汇编指令格式为AT&T格式
//break 不会把端点设置在汇编指令层次函数的开头,会停留在第三条汇编指令(汇编调用函数会先push 栈,再移动栈指针,再call)
//如果要把断点设置在汇编指令层次函数的开头,则使用b *func

 

 

命令

含义

示例

相关命令

info registers

列出寄存器

 打印单个寄存器的值: info registers reg-name 或者 p $eax

 

info all-registers

可以看到包括浮点寄存器和向量寄存器的内容

 

 

display

 查看汇编指令

display /3i $pc 显示当程序停止时,将要执行的汇编指令(一次看几条)

 

disassemble main

查看main函数的汇编

 

 

set disassembly-flavor

设置汇编指令格式

set disassembly-flavor intel 改为intel 格式

set disassembly-flavor att 改为AT&T

 

set disassemble-next-line

设置反汇编后续代码

set disassemble-next-line on (任意情况都反汇编)

set disassemble-net-line auto 在没有源码的情况下才反汇编

set disassemble-net-line off

 

disassemble

反汇编代码

disassemble /m func函数  将函数代码和汇编指令映射起来(每一条c语句都对应了汇编)

disassemble 代码开始地址,代码结束地址。可以查看指定起始地址的代码的汇编代码(查看某一行对应的地址范围info line 13)

 

 

2.10 信号

命令(对收到的信号处理)

 

含义

示例

相关命令

handle signal_xxx

stop/nostop

设置信号发生时,是否暂停程序

设置stop,默认print。设置noprint ,默认nostop

 

 

print/noprint

设置信号发生时,是否打印

 

 

pass/nopass

设置信号发生时,是否把信号丢给程序处理

nopass表示不给程序。三种选项可一同设置

 

 

info signals 
Signal        Stop      Print   Pass to program Description
SIGHUP        Yes       Yes     Yes             Hangup

//Signal:表示信号量
//stop:表示被调试程序有信号(SIGHUP)发生时,gdb是否会暂停程序
//Print:表示被调试程序有信号(SIGHUP)发生时,gdb是否会打印相关信息
//Pass to program: gdb是否会把这个信号发送给被调试程序

 

命令(主动触发信号处理) 

含义

示例

相关命令

signal signal_xxxx 

发送信号signal_xxxx给进程

signal 0

可以使程序从新运行,但不发信号给进程

 

$_siginfo

在gdb把信号丢给程序之前,

可以通过$_siginfo 变量读取一些额外信号信息

 

 

2.11 脚本/GDB配置文件

 gdb 启动时读取home目录和当前目录下的配置文件,执行里面的命令(.gdbinit文件)

# 常见列入 .gdbinit文件的配置,可自行配置
# 保存历史命令
set history filename ~/.gdb_history
set history save on

# 退出时不显示提示信息
set confirm off

# 按照派生类型打印对象
set print object on

# 打印数组的索引下标
set print array-indexes on

# 每行打印一个结构体成员
set print pretty on

 

//gdb 支持的脚本文件:一种为gdb自身命令的脚本,.gdbinit gdb启动时会执行里面的命令;第二种gdb还支持其他语言的脚本

命令

含义

示例

相关命令

shell 或 !ls 或 ,ls

执行shell脚本

shell cat 1.txt

 

set script-extension

off

所有的脚本文件都解析成gdb的命令脚本

 

 

soft

根据脚本文件扩展名决定如何解析脚本。

如果gdb支持解析这种脚本语言(比如python),就按这种语言解析,否则就按命令脚本解析;

 

 

strict

根据脚本文件扩展名决定如何解析脚本。

如果gdb支持解析这种脚本语言(比如python),就按这种语言解析,否则不解析;

 

 

show script-extension

查看GDB解析脚本文件格式

 

 

 

2.12 lib库/源文件

带*的表示库缺少调试信息

命令

含义

示例

相关命令

info files

列出当前文件

 

 

info share

或info sharedlibrary regex

显示程序加载的共享链接库信息

regex为正则表达式

 

 

directory

gdb不能找到源文件位置,可以使用directory命令设置源文件的路径

directory 源文件

 

set substitute-path

当源文件路径改变时,设置新的源文件路径

set substitute-path 旧的路径 新的路径

 

 

2.13 其他

命令

含义

示例

相关命令

make CFLAGS="-g -O0"

gdb里面可直接make编译程序

 

 

 cd

切换工作目录(路径)

 

 

pwd

查看当前工作目录(路径)

directory 源文件

 

set prompt

设置命令提示符(debug调试前面显示设置的字符),区分多个gdb。格

set prompt (main gdb) 

结尾有空

 

set env

 设置被调试程序的环境变量

 set env LD_PRELOAD=/lib/libpthread.so.0

 

show version

查看gdb版本信息

 

 

show copying

查看gdb版权信息

 

 

show warranty

查看gdb版权信息

 

 

set confirm off 

把退出时提示信息(Quit anyway?(y or n))关掉

 

 

tty

为程序指定单独终端

(gdb默认输出输入为同一个终端。)

gdb -tty /dev/pts/2 ./a.out 
或者tty /dev/pts/2

 

 

3、附件:

1、调试无调试信息程序

在程序入口处打断点

获取程序入口地址:

readlef -h a.out 中 ertry point addrss

或者 gdb 中 info files 中 entry point 可获取

直接 b *程序起始地址,然后 run

 2、尾调用(tail call)

一个函数的最后一条指令是调用另外一个函数时,开启编译优化后,编译器尝尝将最后一个被调用的函数返回值直接作为调用者的返回值。

 3、gdb 打印不全

---Type <return> to continue, or q <return> to quit---

set pagination off