最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
C语言中GDB进行程序调试笔记
时间:2022-06-25 04:48:32 编辑:袖梨 来源:一聚教程网
使用 GDB 调试程序
打开 C 程序的调试功能
编译程序, 我们可以使用 gcc -S main.c 这样来打开调试并且这样也能见到二进制的汇编. 编译程序时使用 -g 更加方便不但有二进制汇编,还有代码本身 (注, 这时我们想看二进制结构,可以使用 objdump 加 -dS 参数).
测试样例代码
#include
int add_range(int low, int high) {
int i, sum;
for (i = low; i <= high; i++) {
sum = sum + i;
}
return sum;
}
int main(void) {
int result[100];
result[0] = add_range(1, 10);
result[1] = add_range(1, 100);
printf("result[0]=%dn result[1]=%dn", result[0], result[1]);
return 0;
}
常用 GDB 的调试命令
计算机在分配变量的时候, 局部变量是存储在栈中, 全局变量是存储在全局量段。进入函数时, 变量会放到栈顶,退出时会从栈顶拿掉。它是从存储器顶部开始向下增长的。
启动 GDB 的时候, 一定要保证加了 -g 来增加代码到二进制文件中来. 代码是在指定路径,所以代码文件不存在并不行。
启动调试:
# gcc 11.c -g -o 11
# gdb main
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-64.el6_5.2)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
Reading symbols from /root/fukai/c/11...done.
帮助和显示
gdb 提供了一个类似 shell 一样的命令行环境, 可以在这个提示符下输入 help 命令来查看可用的命令类别。我们可以进一步查看看 help 显示的内容类别下有哪些类别, 比如 files 只需要输入 help files 就可以了。
(gdb) help files
Specifying and examining files.
List of commands:
add-symbol-file -- Load symbols from FILE
add-symbol-file-from-memory -- Load the symbols out of memory from a dynamically loaded object file
cd -- Set working directory to DIR for debugger and program being debugged
core-file -- Use FILE as core dump for examining memory and registers
directory -- Add directory DIR to beginning of search path for source files
edit -- Edit specified file or function
exec-file -- Use FILE as program for getting contents of pure memory
file -- Use FILE as program to be debugged
forward-search -- Search for regular expression (see regex(3)) from last line listed
generate-core-file -- Save a core file with the current state of the debugged process
list -- List specified function or line
load -- Dynamically load FILE into the running program
nosharedlibrary -- Unload all shared object library symbols
path -- Add directory DIR(s) to beginning of search path for object files
pwd -- Print working directory
进入后,就可以使用 list 1 来列出源代码。一次只列出 10 行。如果要在显示第 11 行开始, 需要在次输入 list, 也可以什么都不输入直接回车。
列出指定函数代码: l 函数名
GDB 基本命令
进入后, 输入 start 来启动程序. 启动后我们可以使用 next (简写为 n) 来控制代码一条一条执行, 注意 n 并不会进入函数内部. 这时如果执行到一个指定的函数上, 想进入,可以使用 s ,然后就会进入这个函数的内部。
(gdb) start
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Temporary breakpoint 2 at 0x4004f8: file 11.c, line 13.
Starting program: /root/fukai/c/11
Temporary breakpoint 2, main () at 11.c:13
13 result[0] = add_range(1, 10);
(gdb) s
add_range (low=1, high=10) at 11.c:5
5 for (i = low; i <= high; i++) {
进入函数后状态的查看
上面讲到使用 step 进入当前的函数后, 下面是怎么样来查看看函数内部的内容。
命令 backtrace (简写 bt)命令可以查看函数调用的栈帧
(gdb) bt
#0 add_range (low=1, high=10) at 11.c:5
#1 0x0000000000400507 in main () at 11.c:13
这时可以见到 main 函数的栈帧是 1 , add_range 的栈帧是 0,我们可以使用 info 命令来查看函数内部的局部变量的值。
(gdb) i locals
i = 0
sum = 0
这时想查看 main 函数内的局部变量也可以需要使用 fram 1(简写 f) 来转到 1 号栈帧。接下来基本上都是使用 p 来显示变量的内容
(gdb) p sum
$5 = 6
(gdb) finish
Run till exit from #0 add_range (low=1, high=10) at 11.c:6
0x0000000000400507 in main () at 11.c:13
13 result[0] = add_range(1, 10);
Value returned is $6 = 55
如果要退出当前函数,就象上面一样,执行 finish 就可以退出当前函数来执行其它的了。
在使用过程中想修改变量的话,可以象下面这样操作
(gdb) set var sum=0
(gdb) p sum
$8 = 0
(gdb) finish
Run till exit from #0 add_range (low=1, high=100) at 11.c:6
0x000000000040051c in main () at 11.c:14
14 result[1] = add_range(1, 100);
Value returned is $9 = 5050
gdb 基本命令
brcktrace 或 bt 查看各级函数调用和参数
finish 连续运行到当前函数结束,然后等待下一个命令。
frame 或 f 帧编号 选择指定栈帧
info 或 locals 查看当前栈帧局部变量
list 或 l 列出上次位置以下的 10 行源码
list 行号 列出第几行开始的 10 行源码
list 函数名 列出指定函数源码
next 或 n 执行下一语句
print 或 p 打印表达式, 通过表达式可以修改变量值或者调用函数
quit 或 q 退出 gdb 环境
set var 修改变量值
start 开始执行到 main 函数第一行语句
step 或 s 执行下一语句, 如果有函数就进入
高级调试
如果我们想每次查看指定的变量的变化, 我们不需要每次都使用 printf 来打印, 我们只需要使用 display 就行。
(gdb) display sum
1: sum = 1634469985
(gdb) n
9 sum = sum*10 + input[1] - Ɔ'
1: sum = 1634469985
(gdb) n
8 for (i = 0; input[i] != '