跳至主要內容

gdb调试出错的程序

张威大约 5 分钟linux编译工具

程序出错了,怎么办???

利用黑匣子(当程序异常终止时,操作系统保存程序执行时的内存映像的文件)

  1. ulimit -c unlimited 命令在 Linux 系统中用于设置 core 文件的大小限制为无限制
image-20240310141538480
image-20240310141538480

具体来说,ulimit -c unlimited 命令的作用如下:

  1. 取消大小限制默认情况下,Linux 系统可能不生成 core 文件,或者对 core 文件的大小有限制。使用 ulimit -c unlimited 可以确保当程序崩溃时,系统不会因文件大小限制而截断 core 文件,从而可以保存完整的内存映像。

    image-20240310141436371
    image-20240310141436371
  2. 便于调试:完整的 core 文件对于程序员和系统管理员来说是非常有价值的,因为它可以帮助他们了解程序崩溃时的状态,包括变量的值、内存布局等,从而更容易地定位问题所在。

  3. 注意安全性:需要注意的是,。此外,core 文件可能包含敏感信息,因此需要注意文件的安全性和隐私保护。

  1. -g编译代码
  2. 执行代码,生成core
  3. gdb a.out core
  4. bt 查看堆栈

gdb 设置命令行参数

image-20240310142108995
image-20240310142108995

gdb 基本命令

  1. set args:设置程序运行时的参数。
  2. show args:查看设置好的运行参数。
  3. bt(或backtrace):查看当前调用栈的信息。
  4. break(或b):设置断点。例如,break functionname 会在函数functionname的入口处设置断点;break filename:linenum 会在filename文件的linenum行设置断点。
  5. info break(或i b):查看当前所有断点的信息。
  6. delete break(或d):删除断点。例如,delete num 会删除编号为num的断点。
  7. ignore :想要临时跳过某个断点几次时ignore breakpoint-number count
  8. run(或r):开始执行程序,直到遇到断点或程序结束。
  9. continue(或c):从当前位置开始连续执行程序,直到遇到下一个断点或程序结束。
  10. next(或n):执行下一行代码,跳过函数调用。
  11. step(或s):执行下一行代码,进入函数调用。
  12. finish:执行当前函数,直到返回,然后停下来等待命令。
  13. set var:修改变量的值。例如,set var variable=value 会将variable的值设置为value
  14. print(或p):打印变量或表达式的值。例如,print variable 会打印variable的值。
  15. list(或l):列出源代码。例如,list functionname 会列出functionname函数的源代码;list linenum 会列出从linenum开始的源代码。
  16. quit(或q):退出GDB。

监视功能display

display expression 是GDB(GNU Debugger)中的一个命令,用于在每次程序停止时自动显示一个或多个表达式的值。这对于监视变量或内存地址在程序执行过程中的变化非常有用。

使用 display 命令时,GDB会为每个显示的表达式分配一个编号。你可以使用 undisplay 命令加上这个编号来删除特定的自动显示表达式。例如,如果 display 命令为某个表达式分配了编号1,你可以使用 undisplay 1 来删除它。

监视变量值

(gdb) display count

每次程序停止时(例如,在断点处),GDB都会自动显示 count 变量的当前值。

监视指针指向的内容

(gdb) display *ptr

监视内存地址的内容

(gdb) display *(int*)0x12345678

这个命令将显示内存地址 0x12345678 处作为整数(int)解释的值。每次程序停止时,这个值都会被更新

监视表达式的结果

(gdb) display a + b * c

这里,abc 是程序中的变量。每次程序停止时,GDB都会计算并显示 a + b * c 这个表达式的值。

监视结构体成员

(gdb) display myStruct.member

myStruct 是一个结构体变量,member 是该结构体中的一个成员。每次程序停止时,GDB都会显示 myStruct.member 的当前值。

x命令来查看指定地址的内存值

x命令来查看指定地址的内存值,以及按照不同的格式(如字节、字、双字、浮点数等)来解析这些内存值

x/格式 地址
  • 格式:指定如何解析和显示内存内容。常用的格式有:
    • b字节(一个字节)
    • h半字(两个字节)
    • w字(,32位)
    • g:巨字(八个字节,64位)
    • i机器指令(以汇编指令格式显示
    • f浮点数(按照浮点数的格式显示)
    • s字符串(以ASCII字符串格式显示)
    • c字符(以ASCII字符格式显示)
    • u无符号十进制整数
    • t二进制整数
    • o:八进制整数
    • xd十六进制或十进制整数(默认是十六进制)
  • 地址:要检查的内存地址。

示例

  1. 查看从地址0x12345678开始的4个字节,并以十六进制显示:
(gdb) x/4xb 0x12345678
  1. 以二进制格式查看内存内容
(gdb) x/tb 0x401000
  1. 查看从地址0x12345678开始的指令,并以汇编指令格式显示:
(gdb) x/i 0x12345678
  1. 查看从地址0x12345678开始的字符串(直到遇到空字符'\0'为止):
(gdb) x/s 0x12345678
  1. 查看从当前程序计数器(PC)开始的指令:
(gdb) x/i $pc