gdb详解【Linux知识贩卖机】

gdb详解【Linux知识贩卖机】_第1张图片
你背朝太阳,就只能看到自己的影子。 --纪伯伦语录

文章目录

  • 简介
  • 准备
  • 常用命令
    • 查看代码(list)
    • 运行(run)
    • 打断点(break)
    • 逐语句(step)
    • 逐过程(next)
    • 完成当前函数(finish)
    • 打印变量值(print)
    • 设置变量(set)
    • 跳到下一断点(continue)
    • 删除断点(delete)
    • 禁用断点(disable)
    • 启用断点(enable)
    • 循环打印(display)
    • 取消循环打印(undisplay)
    • 运行到指定行(until)
    • 查看调用栈(backtrace)
    • 设置观察点
    • 退出(quit)
  • 总结


简介

gdb详解【Linux知识贩卖机】_第2张图片

gdb 是 GNU Debugger 的缩写,是一款由 GNU 项目开发的、用于调试程序的强大工具。它允许开发者在程序执行过程中观察程序的行为,检查变量的值,跟踪函数调用,定位程序崩溃的原因等。gdb 支持多种编程语言,包括 C、C++、Fortran 等。

主要特点和功能包括:

  1. 断点设置: 允许在程序中的特定位置暂停执行,以便进行调试。

  2. 变量查看: 可以查看程序运行时的变量值,包括局部变量和全局变量。

  3. 函数调用跟踪: 可以跟踪程序的函数调用链,了解程序的执行流程。

  4. 内存查看: 允许查看和修改程序运行时的内存内容。

  5. 寄存器查看: 提供对计算机寄存器状态的访问,可用于了解程序的底层执行情况。

  6. 多线程调试: 支持多线程程序的调试。

  7. 远程调试: 可以通过网络连接调试运行在远程机器上的程序。

  8. 脚本支持: 允许使用脚本语言编写调试脚本,以自动执行调试任务。

gdb 在开发者社区中广泛使用,是许多开发环境中集成的调试工具之一。它为开发者提供了强大的调试能力,有助于快速诊断和解决程序中的问题。掌握gdb调试是一名成熟的程序员必不可少的技能。

准备

在开发过程中,通常会有两种构建模式:Debug 模式和 Release 模式。在 Debug 模式下,编译器会生成包含调试信息的可执行文件。调试信息包括源代码的行号、变量名称等,这使得在调试器中能够更容易地跟踪和调试程序。编译时通常会使用 -g 选项,以包含调试信息。这样的二进制文件较大,但对于开发和调试来说非常有用。在 Release 模式下,编译器会进行优化以提高程序的性能,并且通常不包含调试信息。生成的二进制文件更加紧凑,适合用于最终部署和生产环境。

在使用 gdb 进行调试时,确保在编译源代码时使用了 -g 选项,以便生成包含调试信息的可执行文件。例如,在使用 gcc 编译 C 代码时,可以这样:

gcc -g -o my_program my_program.c

其中,-g 选项告诉编译器生成调试信息,而 -o 选项用于指定输出文件的名称。这样生成的 my_program 文件就包含了调试信息,可以在 gdb 中进行调试。

之后就可以进行调试了,使用gdb命令加生成的可执行文件,例如gdb my_program

gdb详解【Linux知识贩卖机】_第3张图片

常用命令

查看代码(list)

gdb 中,list 命令用于显示源代码。当没有参数时,它将显示当前执行位置周围的源代码,也可以简写为l。下面是一些 list 命令的常用形式:

  1. 显示当前位置周围的源代码:

    list
    
  2. 显示特定行附近的源代码:

    list line_number
    

    gdb详解【Linux知识贩卖机】_第4张图片

  3. 显示指定文件的源代码:

    list file_name:line_number
    
  4. 显示函数的源代码:

    list function_name
    

    gdb详解【Linux知识贩卖机】_第5张图片

  5. 显示指定范围内的源代码:

    list start_line, end_line
    

gdb详解【Linux知识贩卖机】_第6张图片

在使用 list 命令时,可以根据需要指定不同的参数,以便在调试过程中更好地查看和理解源代码,对于定位问题、设置断点和了解程序的执行流程非常有用。

运行(run)

run 命令用于启动被调试的程序。当你在 gdb 中加载了可执行文件后,可以使用 run 命令来开始执行该程序,也可以使用简写r。如果程序需要输入参数,你也可以在 run 命令后面添加参数。

使用 run 命令的基本语法如下:

run [arguments]

例如,如果你的程序需要两个整数参数,你可以这样运行:

run 10 20

这将启动程序,并将参数 1020 传递给它。

在执行 run 命令后,程序将开始运行,直到遇到断点、程序结束或者由用户中断。在这个过程中,你可以使用 gdb 提供的其他命令进行调试,如查看变量、设置断点、单步执行等。

gdb详解【Linux知识贩卖机】_第7张图片

打断点(break)

break 命令用于设置断点,即在程序的某一行或某个函数内设置一个停止点,使得程序在执行到该处时会暂停,以便进行调试。也可以使用简写b。如果想要查看已设置的断点,可以使用 info breakpoints 命令。

break 命令的基本语法如下:

break [location]

其中 location 可以是行号、函数名、文件名、或者其他标识位置的方式。

一些常见的用法示例:

  1. 在当前文件的某一行设置断点:
    break line_number
    

gdb详解【Linux知识贩卖机】_第8张图片
在这里插入图片描述

  1. 在指定文件的某一行设置断点:

    break file_name:line_number
    
  2. 在函数内设置断点:

    break function_name
    

gdb详解【Linux知识贩卖机】_第9张图片

gdb详解【Linux知识贩卖机】_第10张图片

  1. 在地址处设置断点:

    break *address
    
  2. 在条件满足时设置断点:

    break line_number if condition
    

设置断点后,当程序执行到断点处时,gdb 会暂停执行,允许你查看变量、执行单步调试等操作。你可以在多个地方设置断点,以便在不同的地方进行调试。

逐语句(step)

step 命令用于单步执行程序,即按照程序的执行流程逐行执行代码。当遇到函数调用时,step 会进入函数内部执行,允许你逐步跟踪程序的执行过程。

step 命令的基本语法如下:

step

或者可以使用简写形式:

s

当你执行 step 命令时,gdb 将执行当前行并停在下一行。如果当前行是一个函数调用,gdb 会进入该函数并停在函数内的第一行。

gdb详解【Linux知识贩卖机】_第11张图片

gdb详解【Linux知识贩卖机】_第12张图片

逐过程(next)

next 命令用于执行程序的下一行代码,但不会进入到函数内部。如果当前行是一个函数调用,next 将执行整个函数并在函数返回后停止。

next 命令的基本语法如下:

next

或者可以使用简写形式:

n

当你执行 next 命令时,gdb 将执行当前行并停在下一行。如果当前行是一个函数调用,gdb 将执行整个函数并在函数返回后停止。这与 step 命令的区别在于,step 会进入函数内部执行。

gdb详解【Linux知识贩卖机】_第13张图片

gdb详解【Linux知识贩卖机】_第14张图片

next 命令适用于当你不希望进入函数内部,而只是想执行当前行的下一行代码。这在你对函数内部的细节不感兴趣,而只关注主程序流程时很有用。

完成当前函数(finish)

finish 命令用于执行程序直到当前函数返回为止,然后停止。在你进入了一个函数内部,但你想要跳过函数的执行,直到函数返回到调用点可以使用该命令。

finish 命令的基本语法如下:

finish

或者可以使用简写形式:

fin

当你执行 finish 命令时,gdb 将继续执行程序,直到当前函数返回到调用点。在这之后,程序会暂停执行,允许你进行下一步调试操作。finish 命令对于在进入函数后快速返回到调用点而不关心函数内部细节的情况非常有用。
gdb详解【Linux知识贩卖机】_第15张图片

gdb详解【Linux知识贩卖机】_第16张图片

打印变量值(print)

print 命令用于查看变量的值,表达式的值或内存位置的内容。这在调试中经常用到,可以帮助在调试过程中了解程序的状态。

print 命令的基本语法如下:

print expression

或者可以使用简写形式:

p expression

其中,expression 是你想要评估的变量、表达式或内存位置。

以下是一些示例:

  1. 查看变量的值:

    print variable_name
    

    p variable_name
    
  2. 查看表达式的值:

    print x + y
    

    p x + y
    
  3. 查看内存位置的内容:

    print *address
    

    p *address
    
  4. 查看数组的一部分:

    print array_name[start_index:end_index]
    

    p array_name[start_index:end_index]
    

    gdb详解【Linux知识贩卖机】_第17张图片

gdb详解【Linux知识贩卖机】_第18张图片

设置变量(set)

set 命令用于设置各种调试环境的参数和选项。这包括设置变量的值、更改显示选项、配置断言处理等。set 命令的基本语法如下:

set parameter value

以下是一些 set 命令的示例:

  1. 设置变量的值:

    set variable_name = new_value
    
  2. 更改显示格式:

    set print pretty on
    
  3. 设置断言处理方式:

    set assert-style fail
    
  4. 设置自动加载的源文件:

    set auto-load safe-path /
    
  5. 设置显示堆栈帧的深度:

    set backtrace limit 10
    
  6. 设置显示行号:

    set list source-lines 5
    

set 命令提供了一种动态配置调试环境的方式,使得你可以根据需要调整 gdb 的行为。你可以使用 show 命令来查看当前的设置。

gdb详解【Linux知识贩卖机】_第19张图片

gdb详解【Linux知识贩卖机】_第20张图片

跳到下一断点(continue)

continue 命令用于继续执行程序,直到程序结束或者遇到下一个断点。当你在调试过程中想让程序一直运行到下一个断点或程序结束时,可以使用 continue 命令。

continue 命令的基本语法如下:

continue

或者可以使用简写形式:

c

执行 continue 命令后,gdb 将继续执行程序,直到遇到断点、程序结束,或者由用户中断。在这个过程中,你的程序将在不同的点上暂停执行,以允许你进行调试操作。

gdb详解【Linux知识贩卖机】_第21张图片

gdb详解【Linux知识贩卖机】_第22张图片

删除断点(delete)

delete 命令用于删除设置的断点,可以通过断点编号或者断点地址来删除断点。delete 命令的基本语法如下:

delete breakpoint_number

或者可以使用简写形式:

d breakpoint_number

示例:

  1. 通过断点编号删除断点:

    delete 1
    
  2. 通过断点地址删除断点:

    delete *0x0804842a
    
  3. 删除所有断点:

    delete
    

在这里,breakpoint_number 是你想要删除的断点的编号。如果没有提供断点编号,则 delete 命令将删除所有断点。

gdb详解【Linux知识贩卖机】_第23张图片

禁用断点(disable)

disable 命令用于禁用设置的断点、观察点或自动显示点,禁用后,这些断点将不再生效,程序运行时将不会在这些位置停止。

disable 命令的基本语法如下:

disable breakpoint_number

或者可以使用简写形式:

dis breakpoint_number

示例:

  1. 通过断点编号禁用断点:

    disable 1
    
  2. 禁用所有断点:

    disable
    

在这里,breakpoint_number 是你想要禁用的断点的编号。如果没有提供断点编号,则 disable 命令将禁用所有当前设置的断点。

请注意,禁用断点并不会删除它们,而是暂时阻止它们生效。你可以使用 enable 命令来重新启用断点。

gdb详解【Linux知识贩卖机】_第24张图片

启用断点(enable)

enable 命令用于启用之前禁用的断点、观察点或自动显示点。一旦断点被启用,程序运行时将在这些位置停止,与之前的设置一致。

enable 命令的基本语法如下:

enable breakpoint_number

或者可以使用简写形式:

en breakpoint_number

示例:

  1. 通过断点编号启用断点:

    enable 1
    
  2. 启用所有断点:

    enable
    

在这里,breakpoint_number 是你想要启用的断点的编号。如果没有提供断点编号,则 enable 命令将启用所有之前禁用的断点。

请注意,启用断点后,程序运行时将在这些位置停止。你可以使用 disable 命令来禁用断点,以暂时阻止它们生效。

gdb详解【Linux知识贩卖机】_第25张图片

循环打印(display)

display 命令用于设置显示表达式,以便在每次程序停止时都自动显示其值,简写形式为disp。可以避免每次都使用print来打印的麻烦。display 命令的基本语法如下:

display expression

示例:

  1. 显示变量的值:

    display variable_name
    
  2. 显示表达式的值:

    display x + y
    
  3. 显示内存位置的内容:

    display *address
    
  4. 显示数组的一部分:

    display array_name[start_index:end_index]
    

gdb详解【Linux知识贩卖机】_第26张图片

gdb详解【Linux知识贩卖机】_第27张图片

取消循环打印(undisplay)

undisplay 命令用于取消之前使用 display 命令设置的表达式的显示。这意味着在每次程序停止时不再显示取消的表达式的值。undisplay 命令的基本语法如下:

undisplay display_number

或者可以使用简写形式:

und display_number

display_number 是你要取消显示的表达式的编号。

gdb详解【Linux知识贩卖机】_第28张图片

运行到指定行(until)

until 命令用于执行程序直到达到或超过指定的行号,然后停止执行。这个命令通常用于跳过循环或一系列代码,直到达到感兴趣的位置。

until 命令的基本语法如下:

until line_number

或者可以使用简写形式:

u line_number

在这里,line_number 是你希望程序执行直到达到或超过的行号。

gdb详解【Linux知识贩卖机】_第29张图片

查看调用栈(backtrace)

backtracegdb 中一个用于显示函数调用栈的命令。它展示了程序当前执行的位置及其在调用栈中的调用路径。这对于理解程序的执行流程和查找问题的来源非常有用。

基本语法如下:

backtrace

或者使用简写形式:

bt

执行这个命令会显示调用栈的内容,其中每个帧都表示一个函数调用。

示例:

(gdb) backtrace
#0  main () at example.c:10
#1  0x0000555555555149 in _start ()

backtrace 显示了两个帧。第一个帧显示当前执行的 main 函数,第二个帧显示程序的入口点 _start。你还可以使用 info frame 命令来查看有关特定帧的更多信息:

(gdb) info frame 0

这将显示当前帧(帧编号为 0)的详细信息,包括寄存器状态、局部变量等。

gdb详解【Linux知识贩卖机】_第30张图片

设置观察点

gdb 中,watch 命令用于设置观察点,以便在变量的值发生更改时暂停程序的执行。这对于跟踪特定变量的变化并找出引起问题的地方非常有用。

watch 命令的基本语法如下:

watch variable_name

或者可以使用简写形式:

w variable_name

以下是一个示例:

(gdb) watch counter

或者使用简写形式:

(gdb) w counter

这将在变量 counter 的值发生变化时暂停程序的执行。

gdb详解【Linux知识贩卖机】_第31张图片

你还可以使用条件观察点,只有当满足特定条件时才暂停程序。例如:

(gdb) watch x > 10

这将在变量 x 的值大于 10 时暂停程序。

gdb详解【Linux知识贩卖机】_第32张图片

使用 info watch 命令可以查看当前设置的观察点。

(gdb) info watch
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004005f2 in main at example.c:10
        watchpoint already hit 1 time

gdb详解【Linux知识贩卖机】_第33张图片

退出(quit)

quit 命令用于退出 gdb 调试器,结束调试会话。执行这个命令将终止正在调试的程序并关闭 gdb

quit 命令的基本语法如下:

quit

或者可以使用简写形式:

q

执行这个命令将退出 gdb,并返回到命令行终端。

请注意,退出 gdb 时,正在调试的程序也将被终止。确保在退出之前保存任何重要的调试信息或程序状态。

gdb详解【Linux知识贩卖机】_第34张图片

总结

gdb调试的重要性不言而喻,本篇文章介绍了使用gdb调试经常会用到的一些命令,希望文章对你有所帮助!

gdb详解【Linux知识贩卖机】_第35张图片

你可能感兴趣的:(Linux,linux)