Linux之GDB调试

Linux之GDB调试

@TOC

在这里插入图片描述
在这里插入图片描述

Linux GDB 调试

一、初识 GDB

GDB 是一个开源的、功能强大的调试工具,主要用于调试 C、C++ 等语言编写的程序。它支持多种操作系统和架构,能够帮助开发者在程序运行过程中暂停执行、查看变量值、修改程序状态等,从而快速定位和修复问题。

二、启动 GDB

1. 加载程序

如果你已经编译好了一个程序,可以直接通过以下命令启动 GDB 并加载程序:

gdb <program>

例如,如果你的程序名为 example,则可以输入:

gdb example 

GDB 会加载该程序,并进入调试模式。

2. 加载程序与参数

如果程序需要接收命令行参数,可以使用以下命令启动 GDB:

gdb <program> --args <args>

例如,程序需要接收一个文件路径作为参数,可以这样启动:

gdb example --args input.txt 

在 GDB 中,可以通过 run 命令启动程序,并传递参数。

3. 加载程序与核心转储文件

当程序崩溃并生成了核心转储文件时,可以通过以下命令启动 GDB,加载程序和核心转储文件进行调试:

gdb <program><core>

这可以帮助你分析程序崩溃的原因。

三、设置断点

断点是调试过程中非常重要的工具,它可以让程序在指定的位置暂停执行,方便我们查看程序状态。

1. 在函数处设置断点

如果你知道程序在某个函数中可能出现问题,可以使用以下命令在该函数处设置断点:

break<function>

例如,设置在 main 函数处的断点:

break main 

程序运行到 main 函数时会暂停。

2. 在文件的指定行设置断点

如果你已经大致知道问题可能出现在代码的哪一行,可以使用以下命令在指定文件的指定行设置断点:

break<filename>:<line>

例如,设置在 example.c 文件的第 10 行的断点:

break example.c:10 

程序运行到该行时会暂停。

3. 在指定内存地址处设置断点

在某些情况下,你可能需要在指定的内存地址处设置断点,可以使用以下命令:

break *<address>

例如,设置在内存地址 0x1000 处的断点:

break *0x1000 

程序运行到该地址时会暂停。

4. 设置条件断点

如果你希望断点只有在满足特定条件时才触发,可以使用以下命令设置条件断点:

break<location>if<condition>

例如,设置在 main 函数处的断点,只有当变量 x 的值大于 10 时才触发:

break main if x >10

这样可以更精准地定位问题。

四、运行和停止程序

1. 开始运行程序

在 GDB 中,可以通过以下命令开始运行程序:

run <args>

如果你在启动 GDB 时已经指定了程序参数,可以直接输入 run;如果没有指定参数,可以在 run 命令后添加参数。

例如:

run 

或者:

run input.txt 

程序会从头开始运行,直到遇到断点。

2. 从断点继续运行

当程序在断点处暂停后,可以通过以下命令从当前断点继续运行:

continue

程序会继续执行,直到遇到下一个断点。

3. 单步执行

在调试过程中,有时需要逐条语句查看程序的执行情况,可以使用以下命令:

  • next:执行下一条语句,但不会进入函数内部。如果当前语句是一个函数调用,它会直接跳过该函数,执行下一条语句。
next 
  • step:执行下一条语句,并进入函数内部。如果当前语句是一个函数调用,它会进入该函数,继续逐条语句执行。
step 

通过这两种方式,可以灵活地查看程序的执行流程。

4. 执行完当前函数

如果你当前处于一个函数内部,可以通过以下命令执行完当前函数并返回:

finish 

程序会继续执行,直到当前函数执行完毕并返回。

5. 终止程序运行

在调试过程中,如果需要终止程序的运行,可以使用以下命令:

kill

程序会被强制终止。

五、查看程序状态

1. 查看代码

在 GDB 中,可以通过以下命令查看当前代码位置附近的代码:

list 

默认情况下,它会显示当前代码位置附近的 10 行代码。如果需要查看其他部分的代码,可以在 list 命令后指定文件名和行号:

list <filename>:<line>

例如:

list example.c:20 

这可以帮助你快速定位代码位置。

2. 查看断点信息

可以通过以下命令查看所有设置的断点信息:

info breakpoints 

它会列出所有断点的编号、位置、条件等信息,方便你管理断点。

3. 查看函数参数和局部变量

当你处于某个函数的断点处时,可以通过以下命令查看当前函数的参数和局部变量:

  • info args:查看当前函数的参数。
info args 
  • info locals:查看当前函数的局部变量。
info locals 

这可以帮助你了解函数的输入和内部状态。

4. 查看寄存器内容

在某些情况下,你可能需要查看寄存器的内容,可以通过以下命令:

info registers 

它会列出所有寄存器的名称和当前值,这对于底层调试非常有帮助。

5. 查看调用栈

当程序出现异常时,查看调用栈可以帮助你了解程序的执行路径。可以通过以下命令查看调用栈:

backtrace 

或者简写为:

bt 

它会从当前栈帧开始,向上列出所有调用栈帧的信息,包括函数名、文件名、行号等。

6. 切换调用栈帧

如果你需要查看调用栈中某个特定栈帧的信息,可以通过以下命令切换到该栈帧:

frame <n>

其中 <n> 是栈帧的编号。例如,切换到编号为 2 的栈帧:

frame 2

然后可以使用 info argsinfo locals 等命令查看该栈帧的参数和局部变量。

六、变量和内存操作

1. 打印变量值

在调试过程中,可以通过以下命令打印变量的值:

print <variable>

例如,打印变量 x 的值:

print x 

GDB 会显示变量的当前值。

2. 打印内存内容

如果需要查看内存中的内容,可以通过以下命令:

x/<n><format><address>
  • <n> 表示要显示的内存单元数量。
  • <format> 表示显示格式,例如 x 表示十六进制,d 表示十进制,c 表示字符等。
  • <address> 表示内存地址。

例如,查看从地址 0x1000 开始的 10 个字节的十六进制内容:

x/10x 0x1000 

这可以帮助你查看内存的布局和数据。

3. 修改变量值

在某些情况下,你可能需要修改变量的值,可以通过以下命令:

set<variable>=<value>

例如,将变量 x 的值修改为 20:

setx=20

然后可以继续运行程序,观察程序行为的变化。

七、退出 GDB

完成调试后,可以通过以下命令退出 GDB:

quit 

或者:

exit

八、GBD基本命令汇总

  1. 启动 GDB
    gdb :启动 GDB 并加载要调试的程序。
    gdb :加载程序和核心转储文件进行调试。
    gdb --args :加载程序并传递参数。
  2. 设置断点
    break :在指定函数处设置断点。
    break ::在指定文件的指定行设置断点。
    break *:在指定内存地址处设置断点。
    break :设置条件断点,只有满足条件时才会触发。
  3. 运行和停止
    run :开始运行程序,并传递参数。
    continue:从当前断点继续运行程序。
    next:执行下一条语句(跳过函数调用)。
    step:进入函数内部执行。
    finish:执行完当前函数并返回。
    kill:终止正在运行的程序。
    disable breakpoints:指令用于禁用已设置的断点。
    enable breakpoints:指令用于重新启用之前被禁用的断点。
    display 变量名:跟踪查看一个变量,每次停下来都显示它的值
    undisplay:取消对先前设置的那些变量的跟踪
    delete breakpoints:删除所有断点
    set var:修改变量的值
    delete breakpoints n:删除序号为n的断点
  4. 查看程序状态
    list:显示当前代码位置附近的代码。
    info breakpoints:显示所有断点信息。
    info args:显示当前函数的参数。
    info locals:显示当前函数的局部变量。
    info registers:显示寄存器的内容。
    backtrace 或 bt:显示调用栈。
    frame :切换到指定的调用栈帧。
  5. 变量和内存操作
    print :打印变量的值。
    print *:打印指定地址的内容。
    set =:修改变量的值。
    x/:查看内存内容,例如 x/10gx 0x1000 查看 10 个 8 字节的内容。
  6. 信号处理
    handle stop:让 GDB 在接收到指定信号时暂停程序。
    handle nostop:让 GDB 不在接收到指定信号时暂停程序。
  7. 退出 GDB
    quit 或 exit:退出 GDB。

其他
help:显示帮助信息。
help :显示指定命令的帮助信息。

在这里插入图片描述

Read more

Ubuntu 25.04私有大模型部署实战:Ollama+DeepSeek+OpenWebUI完全指南

Ubuntu 25.04私有大模型部署实战:Ollama+DeepSeek+OpenWebUI完全指南

Ubuntu 25.04私有大模型部署实战:Ollama+DeepSeek+OpenWebUI完全指南 作为一名技术爱好者,我对本地部署大型语言模型充满热情。在Ubuntu 25.04上搭建完整的私有AI环境(Ollama + DeepSeek + OpenWebUI)让我收获颇丰,也踩过不少坑。本文将分享零基础搭建流程、性能调优技巧和实用问题解决方案,助你快速拥有专属AI助手。 前置环境准备 推荐使用Ubuntu 25.04 Server版(最小化安装),配置要求: * CPU:4核及以上(建议Intel i7+/Ryzen 5+) * 内存:32GB以上(运行32B模型需要) * 显卡:NVIDIA RTX 3060 12GB+(显存越大越好) * 存储:至少100GB SSD空间 系统优化建议: # 禁用自动更新降低系统中断几率sudosed-i's/Update-Package-Lists "

By Ne0inhk

Linux网络队列算法终极指南:FQ、Codel、PIE、CAKE对比解析

Linux网络队列算法终极指南:FQ、Codel、PIE、CAKE对比解析 【免费下载链接】one_click_scriptinstall latest or LTS linux kernel and enable BBR or BBR plus 项目地址: https://gitcode.com/gh_mirrors/on/one_click_script Linux网络性能优化一直是系统管理员和开发者的重要课题。one_click_script项目提供了一键安装最新Linux内核并开启BBR加速的完整解决方案,其中队列算法的选择对网络性能有着关键影响。本文将深入解析四种主流队列算法:FQ、FQ-Codel、FQ-PIE和CAKE,帮助您选择最适合的网络配置方案。🚀 🔍 什么是队列算法? 队列算法是Linux内核中负责管理网络数据包传输顺序的机制。在网络拥塞时,合理的队列算法能够显著降低延迟、提高吞吐量,为用户带来更流畅的网络体验。在one_click_script项目中,您可以通过简单选择来启用不同的队列算法,

By Ne0inhk
【Linux系统】理解管道通信,匿名管道实现进程池+命名管道实现服务端客户端通信模型(附源码)

【Linux系统】理解管道通信,匿名管道实现进程池+命名管道实现服务端客户端通信模型(附源码)

文章目录 * 一、进程间通信是什么 * 二、管道 * 1. 什么是管道 * 2. 匿名管道 * 3. 命名管道 * 三、实例:匿名管道实现进程池 * 四、实例:命名管道实现服务端客户端通信模型 一、进程间通信是什么 进程间通信(IPC),顾名思义,进程之间需要进行信息交换。 如:数据传输、资源共享、通知事件、进程控制。 进程间通信的方式有:管道、System V IPC、POSIX IPC。 由于进程具有独立性,进程间通信的前提就是,不同的进程能看到同一份资源。 二、管道 1. 什么是管道 管道是类Unix系统中最古老的进程间通信的方式。我们把从一个进程连接到另一个进程的数据流称为一个“管道”。 管道是单向通信的,称为单工通信。 管道分为匿名管道和命名管道。 2. 匿名管道

By Ne0inhk
Web Worker:让前端飞起来的隐形引擎

Web Worker:让前端飞起来的隐形引擎

目录 Web Worker:让前端飞起来的隐形引擎 一、什么是 Web Worker? 1、为什么需要 web worker 2、什么是 web worker 二、基本使用方法 1、创建一个 Worker 文件(worker.js) 2、主线程引入并使用 三、实战案例:在前端处理大批量数据 1、Worker 文件(sortWorker.js) 2、主线程调用 四、Vue3 中如何优雅使用 Web Worker 1、新建 Worker 文件(worker.js) 2、在 Vue3

By Ne0inhk