GDB

GDB 常用命令#

GDB 中有许多常用命令,以下是一些常见的命令:

1. 启动调试#

  • 启动 GDB

    gdb <可执行文件>
    
  • 附加到运行中的进程
    如果程序已经在运行中,你可以用以下命令来附加到某个正在运行的进程:

    gdb <可执行文件> <进程ID>
    

2. 设置断点#

  • 设置断点
    在指定的函数名或行号上设置断点,程序执行到该点时会暂停。

    break <函数名>           # 在函数处设置断点
    break <文件名>:<行号>    # 在文件的某行设置断点
    
  • 条件断点
    你可以为断点添加条件,只有在满足条件时才会暂停。

    break <文件名>:<行号> if <条件>  # 满足条件时中断
    
  • 删除断点
    删除某个断点。

    delete <断点编号>
    
  • 列出所有断点
    查看当前设置的所有断点。

    info breakpoints
    

3. 运行程序#

  • 运行程序
    使用 GDB 启动调试的可执行程序,运行时可以传入参数。

    run <参数>
    
  • 重新启动程序
    重新启动调试程序,重新执行。

    run
    

4. 单步执行#

  • 单步执行(step)
    执行当前行的代码,如果当前行有函数调用,则进入该函数。

    step
    
  • 逐行执行(next)
    执行当前行的代码,但不会进入函数调用内部。

    next
    
  • 继续执行(continue)
    继续执行程序,直到下一个断点或异常处停止。

    continue
    
  • 返回上一层函数(finish)
    运行当前函数直到返回。

    finish
    
  • 跳过代码执行(jump)
    改变程序的执行流程,将代码跳转到指定行。

    jump <行号>
    

5. 查看程序状态#

  • 查看当前代码行
    显示当前代码位置。

    list
    
  • 查看局部变量
    查看当前函数中定义的局部变量的值。

    info locals
    
  • 查看变量值
    显示某个变量的值。

    print <变量名>
    
  • 查看调用栈
    打印当前的函数调用栈。

    backtrace
    
  • 查看寄存器值
    显示 CPU 寄存器的值。

    info registers
    

6. 修改程序状态#

  • 设置变量值
    在调试过程中,你可以修改变量的值来影响程序的执行。

    set var <变量名> = <新值>
    
  • 调用函数
    调用调试中的程序的函数,通常用于输出或设置状态。

    call <函数名>(<参数>)
    

7. 调试信息和退出#

  • 查看调试信息
    查看当前调试的目标文件信息,例如加载的库。

    info files
    
  • 退出 GDB
    退出 GDB。

    quit
    

如何通过 GDB 定位编译报错的位置?#

当你编译 C++ 或 C 程序时,通常编译器会输出具体的错误信息出错行号,你可以根据编译器的错误提示来定位错误。如果编译成功,但运行时程序崩溃或出现段错误(segmentation fault),可以通过 GDB 进行以下步骤来定位错误位置:

1. 开启调试信息编译#

为了让 GDB 更好地帮助你调试,建议在编译时加上 -g 参数,生成调试符号信息。

g++ -g -o my_program my_program.cpp

2. 运行程序并定位崩溃#

通过 GDB 运行你的程序:

gdb ./my_program

如果程序在运行过程中崩溃,例如遇到段错误(segmentation fault),GDB 会捕获错误并告诉你具体的代码行数。

run <参数>  # 运行程序

当程序崩溃时,GDB 会停在崩溃的地方,输入以下命令查看出错位置:

backtrace  # 查看函数调用栈,找到出错的代码行

backtrace 会打印出调用栈中的每一帧(frame),你可以看到程序执行路径,快速找到出错的位置。

GDB 多线程调试#

GDB 支持多线程调试,你可以调试程序中每个线程的执行情况。以下是一些关于多线程调试的常用命令:

1. 查看线程信息#

  • 查看所有线程
    通过 info threads 命令可以查看当前进程中的所有线程及其状态。

    info threads
    

    输出类似以下内容:

    Id   Target Id         Frame 
    1    Thread 0x7ffff7fb9740 (LWP 3381) "program" 0x00007ffff7a3aaf0 in __GI___libc_read (fd=3, buf=0x7fffffffeff0, count=8192) at ../sysdeps/unix/sysv/linux/read.c:27
    2    Thread 0x7ffff6fb0740 (LWP 3382) "program" 0x00007ffff7a3b114 in __GI___poll (fds=0x7fffffffe0d0, nfds=1, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
    

    每个线程都有唯一的 ID,可以看到它们各自的状态(如阻塞、执行等)。

2. 切换到指定线程#

  • 切换到指定线程
    使用 thread 命令来切换到特定的线程上下文。

    thread <线程ID>
    

    例如,要切换到线程 2,可以输入:

    thread 2
    

    切换到特定线程后,你可以使用其他调试命令(如 printbacktrace 等)来检查该线程的状态。

3. 调试所有线程#

  • 继续运行所有线程
    使用 continue 命令可以恢复所有线程的运行,直到下一个断点或异常触发。

    continue
    
  • 单步调试特定线程
    切换到特定线程后,可以使用 stepnext 命令对该线程进行单步调试,而其他线程会保持不变。

4. 在线程中设置断点#

你可以在线程特定的代码部分设置断点,或者在线程启动后动态设置断点。

  • 设置线程特定的断点
    你可以指定断点只在某个线程中触发。

    break <行号> thread <线程ID>
    

    例如:

    break 42 thread 2
    

    这样断点只会在线程 2 执行到第 42 行时触发,而不会影响其他线程。

5. 杀死线程#

如果你需要终止某个线程的执行,可以使用以下命令:

thread apply <线程ID> kill

这会终止指定的线程。

6. 查看线程局部变量#

在多线程环境中,每个线程都有其自己的局部变量和栈。使用 info locals 可以查看当前线程的局部变量:

info locals

如果要查看其他线程的局部变量,首先切换到该线程,再使用 info locals

总结#

  1. **GDB 常用

命令**:包括设置断点、运行程序、单步调试、查看变量、查看调用栈等,可以帮助你逐步检查和定位问题。

  1. 编译时定位错误:如果程序崩溃,可以使用 GDB 的 runbacktrace 命令来定位具体的崩溃位置,并使用调试信息(如局部变量和调用栈)进一步分析问题。

  2. 多线程调试:GDB 支持多线程调试,提供了 info threadsthreadthread apply 等命令,帮助你查看每个线程的状态,并切换线程调试每个线程的执行过程。

通过这些命令和调试技巧,你可以更有效地分析和解决多线程程序中的问题。

posted @   xiazichengxi  阅读(121)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
历史上的今天:
2023-09-18 230. 二叉搜索树中第K小的元素
2023-09-18 543. 二叉树的直径
点击右上角即可分享
微信分享提示
主题色彩