gdb基础篇

但为了更深入全面的学习,有必要了解gdb这款强大的调试工具。

1. gdb调试前准备

gcc -g -o hello hello.c

使用gcc编译时,一定要加上参数-g,不然生成的可执行文件hello不能调试,使用(gdb) file hellogdb hello时,会报错:No symbol table is loaded. Use the "file" command.

(这个结论尚且不准确。)

2. gdb指令

指令可Tab键补全,可上下键翻阅。

示例源程序如下:

#include<stdio.h>

int fun(int a, int b) {
    int val = 0;
    if (a > b) {
        val = a + b;
    } else {
        val = a - b;
    }
    return val;
}

int main() {
    printf("hello gdb!\n");

    int i;
    for (i=0; i<10; i++) {
        printf("what is gdb? %d\n", i);
    }

    int a = 1, b=3;
    printf("%d\n", fun(a, b));

    return 0;
}

file

格式:

  • file <可执行文件名>,加载要调试的可执行文件。

示例:

(gdb) file hello1
Reading symbols from hello1...done.

list

格式:

  • list <linenum>,显示程序第linenum行周围的源程序
  • list <function> ,显示函数名为function的函数的源程序
  • list,显示当前行周围的源程序(10行),多次list,会自动向后显示源程序
  • list -,向前显示源程序

简写:l

示例:

(gdb) l
warning: Source file is more recent than executable.
1       #include<stdio.h>
2
3       int fun(int a, int b) {
4                       int val = 0;
5                       if (a > b) {
6                                       val = a + b;
7                       } else {
8                                       val = a - b;
9                       }
10                      return val;
(gdb) l
11      }
12
13      int main() {
14                      printf("hello gdb!\n");
15                      int i;
16                      for (i=0; i<10; i++) {
17                                      printf("what is gdb? %d\n", i);
18                      }
19                      return 0;
20      }
(gdb) l -
1       #include<stdio.h>
2
3       int fun(int a, int b) {
4                       int val = 0;
5                       if (a > b) {
6                                       val = a + b;
7                       } else {
8                                       val = a - b;
9                       }
10                      return val;

start

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

示例:

(gdb) start
Temporary breakpoint 1 at 0x617: file hello1.c, line 14.
Starting program: /home/dounine/gdb/hello1

Temporary breakpoint 1, main () at hello1.c:14
14                      printf("hello gdb!\n");

run

说明:运行加载的程序。在run前,需先设定一个或多个断点,不然程序会运行直到结束。

简写:r

break

格式:

  • break <function>,在指定的函数入口处设置断点
  • break <linenum>,在指定的行号处设置断点
  • break *<address>,在指定地址对应的代码处(指令处)设置断点
  • break +<offset> / break -<offset>,在当前行的下offset行/上offset行,设置断点

简写:b

(gdb) start
Temporary breakpoint 1 at 0x617: file hello1.c, line 14.
Starting program: /home/dounine/gdb/hello1

Temporary breakpoint 1, main () at hello1.c:14
warning: Source file is more recent than executable.
14                      printf("hello gdb!\n");
(gdb) l
9                       }
10                      return val;
11      }
12
13      int main() {
14                      printf("hello gdb!\n");
15
16                      int i;
17                      for (i=0; i<10; i++) {
18                                      printf("what is gdb? %d\n", i);
(gdb) break 17
Breakpoint 2 at 0x400629: file hello1.c, line 17.
(gdb) break fun
Breakpoint 3 at 0x4005d0: file hello1.c, line 4.
(gdb) break *0x400630
Breakpoint 4 at 0x400630: file hello1.c, line 17.
(gdb) break +2
Note: breakpoint 2 also set at pc 0x400629.
Breakpoint 5 at 0x400629: file hello1.c, line 16.

break *<address> 在了解并查看汇编位置后再下断点。
break +2 在第16行设置了断点,是因为当前行在第14行。

continue

格式:

  • continue,当程序被停住后,可以使用该命令恢复程序的运行直到程序结束,或到达下一个断点
  • continue <ignore-count>,忽略ignore-count个断点

简写:c

next

格式:

  • next,执行下一步/下一个语句,如果该语句为函数调用,不会进入函数内部执行(即不会一步步地调试函数内部语句)
  • next <count>,执行后面的count条语句(不进入函数),然后再停住

简写:n

示例:

(gdb) break 22
Breakpoint 2 at 0x40065f: file hello1.c, line 22.
(gdb) c
Continuing.
hello gdb!
what is gdb? 0
what is gdb? 1
what is gdb? 2
what is gdb? 3
what is gdb? 4
what is gdb? 5
what is gdb? 6
what is gdb? 7
what is gdb? 8
what is gdb? 9

Breakpoint 2, main () at hello1.c:22
22                      printf("%d\n", fun(a, b));
(gdb) n
-2
24                      return 0;
(gdb) n
25      }

step

格式:

  • step,执行下一步/下一条语句,然后停住。如果该语句为函数调用,则进入函数执行其中的第一条语句
  • step <count>,执行后面的count条语句,然后再停住

简写:s

示例:

(gdb) start
Temporary breakpoint 1 at 0x617: file hello1.c, line 14.
Starting program: /home/dounine/gdb/hello1

Temporary breakpoint 1, main () at hello1.c:14
warning: Source file is more recent than executable.
14                      printf("hello gdb!\n");
(gdb) b 22
Breakpoint 2 at 0x40065f: file hello1.c, line 22.
(gdb) c
Continuing.
hello gdb!
what is gdb? 0
what is gdb? 1
what is gdb? 2
what is gdb? 3
what is gdb? 4
what is gdb? 5
what is gdb? 6
what is gdb? 7
what is gdb? 8
what is gdb? 9

Breakpoint 2, main () at hello1.c:22
22                      printf("%d\n", fun(a, b));
(gdb) s
fun (a=1, b=3) at hello1.c:4
4                       int val = 0;
(gdb) n
5                       if (a > b) {

注意:使用step命令会进入函数调用,而使用next显然不会。但是,如果一直使用step,那将会进入一些如printf之类的函数。

print

  • print <expr>,打印指定表达式的值(表达式可以是变量,也可以是地址)
  • print /<f> <expr>,将指定表达式的值以f格式输出

f的格式包括:

  • x 按十六进制格式显示变量。
  • d 按十进制格式显示变量。
  • u 按十六进制格式显示无符号整型。
  • o 按八进制格式显示变量。
  • t 按二进制格式显示变量。
  • a 按十六进制格式显示变量。
  • c 按字符格式显示变量。
  • f 按浮点数格式显示变量。

示例:

(gdb) print &i
$1 = (int *) 0xbffff46c
(gdb) print i
$2 = 2
(gdb) print i+=1
$3 = 3
(gdb) print i
$4 = 3

 

(gdb) start
Temporary breakpoint 1 at 0x5ac: file hello2.c, line 5.
Starting program: /home/dounine/gdb/hello2

Temporary breakpoint 1, main () at hello2.c:5
5               char *c = "hello world";
(gdb) p c
$1 = 0x400601 <__libc_csu_init+33> "\215\203\354\376\377\377)\306\301\376\002\205\366t%1\377\215\266"
(gdb) p /s c
$2 = 0x400601 <__libc_csu_init+33> "\215\203\354\376\377\377)\306\301\376\002\205\366t%1\377\215\266"
(gdb) p (char*)c
$3 = 0x400601 <__libc_csu_init+33> "\215\203\354\376\377\377)\306\301\376\002\205\366t%1\377\215\266"
(gdb) p *((char*)c)='H'
$4 = 72 'H'
(gdb) p c
$5 = 0x400601 <__libc_csu_init+33> "H\203\354\376\377\377)\306\301\376\002\205\366t%1\377\215\266"

注意:可以在print <expr>的时候,通过表达式设定某个变量的值

简写:p

 

examine

说明:用于打印某个地址所指向的内存中的内容,十分有用!!!

格式:x /nfu <addr>xexamine的缩写。

  • n:表示要显示的内存单元个数。取值为:1 2 3...

  • f:表示显示方式, 可取如下值:

    • x 按十六进制格式显示变量。
    • d 按十进制格式显示变量。
    • u 按十进制格式显示无符号整型。
    • o 按八进制格式显示变量。
    • t 按二进制格式显示变量。
    • i 指令地址格式
    • c 按字符格式显示变量。
    • f 按浮点数格式显示变量。
  • u:表示一个地址单元的长度,与n一起表示显示的地址长度。取值如下:

    • b 表示单字节,
    • h 表示双字节,
    • w 表示四字节,
    • g 表示八字节

示例:

# 显示0x7fffffffd708(这是个地址)处1个(n=1)单字节(u=b)的内容,以十六进制(f=x)表示;
(gdb)x/1xb  0x7fffffffd708
0x7fffffffd708: 0x26

也可以省略n f u参数:

(gdb) x/ 0x402470
0x402470:       0x00400f7c

display

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

简写:disp

watch

  • watch,一般用来观察某个表达式(变量也是一种表达式)的值是否有变化。相当于,在每次该表达式值变化的地方,都设置一个断点。我们需要使用continue命令前进。

示例:

(gdb) start
Temporary breakpoint 1 at 0x617: file hello1.c, line 14.
Starting program: /home/dounine/gdb/hello1

Temporary breakpoint 1, main () at hello1.c:14
14                      printf("hello gdb!\n");
(gdb) watch i
Hardware watchpoint 2: i
(gdb) c
Continuing.
hello gdb!

Hardware watchpoint 2: i

Old value = 4196033
New value = 0
0x00400630 in main () at hello1.c:17
17                      for (i=0; i<10; i++) {
(gdb) c
Continuing.
what is gdb? 0

Hardware watchpoint 2: i

Old value = 0
New value = 1
0x0040064b in main () at hello1.c:17
17                      for (i=0; i<10; i++) {

info

说明:info命令可以在调试时用来查看寄存器、断点、观察点(watch)和信号等信息。

info可以查看的所有信息如下:

(gdb) info
"info" must be followed by the name of an info command.
List of info subcommands:

info address -- Describe where symbol SYM is stored
info all-registers -- List of all registers and their contents
info args -- Argument variables of current stack frame
info auto-load -- Print current status of auto-loaded files
info auxv -- Display the inferior's auxiliary vector
info bookmarks -- Status of user-settable bookmarks
info breakpoints -- Status of specified breakpoints (all user-settable breakpoints if no argument)
info checkpoints -- IDs of currently known checkpoints
info classes -- All Objective-C classes
info common -- Print out the values contained in a Fortran COMMON block
info copying -- Conditions for redistributing copies of GDB
info dcache -- Print information on the dcache performance
info display -- Expressions to display when program stops
info exceptions -- List all Ada exception names
info extensions -- All filename extensions associated with a source language
info files -- Names of targets and files being debugged
info float -- Print the status of the floating point unit
info frame -- All about selected stack frame
info frame-filter -- List all registered Python frame-filters
info functions -- All function names
info guile -- Prefix command for Guile info displays
info handle -- What debugger does when program gets various signals
info inferiors -- IDs of specified inferiors (all inferiors if no argument)
info line -- Core addresses of the code for a source line
info locals -- Local variables of current stack frame
info macro -- Show the definition of MACRO
info macros -- Show the definitions of all macros at LINESPEC
info mem -- Memory region attributes
info os -- Show OS data ARG
info pretty-printer -- GDB command to list all registered pretty-printers
info probes -- Show available static probes
info proc -- Show /proc process information about any running process
info program -- Execution status of the program
info record -- Info record options
info registers -- List of integer registers and their contents
info scope -- List the variables local to a scope
info selectors -- All Objective-C selectors
info set -- Show all GDB settings
info sharedlibrary -- Status of loaded shared object libraries
info signals -- What debugger does when program gets various signals
info skip -- Display the status of skips
info source -- Information about the current source file
info sources -- Source files in the program
info stack -- Backtrace of the stack
info static-tracepoint-markers -- List target static tracepoints markers
info symbol -- Describe what symbol is at location ADDR
info target -- Names of targets and files being debugged
info tasks -- Provide information about all known Ada tasks
info terminal -- Print inferior's saved terminal status
info threads -- Display currently known threads
info tracepoints -- Status of specified tracepoints (all tracepoints if no argument)
info tvariables -- Status of trace state variables and their values
info type-printers -- GDB command to list all registered type-printers
info types -- All type names
info unwinder -- GDB command to list unwinders
info variables -- All global and static variable names
info vector -- Print the status of the vector unit
info vtbl -- Show the virtual function table for a C++ object
info warranty -- Various kinds of warranty you do not have
info watchpoints -- Status of specified watchpoints (all watchpoints if no argument)
info win -- List of all displayed windows
info xmethod -- GDB command to list registered xmethod matchers

其中,常用的查看指令和作用如下:

  • info breakpoints,查看设置了所有断点的信息
  • info display,查看display命令监视的变量
  • info registers,查看寄存器中的值
  • info stack,查看栈(各函数栈帧)的信息
  • info watchpoints,查看watch命令监视的变量

delete

格式:

  • delete <breakpoints num>,删除断点编号所对应的断点,断点编号通过info breakpoints查看。
  • delete,删除所有断点。

示例:

 

(gdb) br 17
Breakpoint 2 at 0x400629: file hello1.c, line 17.
(gdb) info breakpoints
Num     Type           Disp Enb Address    What
2       breakpoint     keep y   0x00400629 in main at hello1.c:17
(gdb) delete 2
(gdb) info breakpoints
No breakpoints or watchpoints.
(gdb) br 16
Breakpoint 3 at 0x400629: file hello1.c, line 16.
(gdb) br 17
Note: breakpoint 3 also set at pc 0x400629.
Breakpoint 4 at 0x400629: file hello1.c, line 17.
(gdb) br 18
Breakpoint 5 at 0x400632: file hello1.c, line 18.
(gdb) info breakpoints
Num     Type           Disp Enb Address    What
3       breakpoint     keep y   0x00400629 in main at hello1.c:16
4       breakpoint     keep y   0x00400629 in main at hello1.c:17
5       breakpoint     keep y   0x00400632 in main at hello1.c:18
(gdb) delete
Delete all breakpoints? (y or n) y
(gdb) info breakpoints
No breakpoints or watchpoints.

backtrace

说明:查看栈(各函数栈帧)信息,与info stack一样。

简写:bt

disassemble

说明:查看当前函数的反汇编代码。

quit

说明:退出gdb

简写:q



作者:dounine
链接:https://www.jianshu.com/p/e51fc3608623
来源:简书

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值