Linux环境下,程序调试是开发过程中的关键环节,单步执行作为核心调试手段,允许开发者逐行或逐指令跟踪程序执行流程,观察变量状态变化,精准定位逻辑错误,本文将详细介绍如何通过主流调试工具实现单步执行,重点以GDB(GNU Debugger)为例展开说明。

大多数Linux发行版默认已安装GDB,若未安装,可通过包管理器快速安装(如Ubuntu使用sudo apt install gdb,CentOS使用sudo yum install gdb),调试前需确保程序包含调试信息,编译时添加-g选项(如gcc -g -o program program.c),否则GDB无法显示源码行号和变量名。
启动GDB后,需通过断点控制程序执行流程,使用break [行号]或break [函数名]设置断点,例如break 10在第10行暂停,break main在main函数入口暂停,还可设置条件断点,如break 10 if i==5,仅当变量i等于5时触发断点,断点设置完成后,通过run(缩写r)启动程序,程序会运行至第一个断点处暂停,此时可开始单步执行。
GDB提供了多种单步执行命令,满足不同调试场景需求,核心命令如下表所示:
| 命令(缩写) | 功能描述 | 示例 |
|---|---|---|
| step (s) | 逐行执行,若当前行是函数调用则进入函数内部 | s |
| next (n) | 逐行执行,若当前行是函数调用则直接执行完函数 | n |
| finish | 执行完当前函数,返回到调用处,并显示函数返回值 | finish |
| until (u) | 执行到当前函数的指定行或退出循环 | u 20 |
| continue (c) | 继续执行程序,直到遇到下一个断点 | c |
调试过程中,实时查看变量值是关键,使用print [变量名](缩写p)可显示变量当前值,如p i查看变量i;display [变量名]则会在每次单步后自动显示指定变量,持续跟踪其变化,对于数组或结构体,可通过p array[0]@3显示数组前3个元素,或p struct.member访问结构体成员。

若需调试多线程程序,GDB支持线程切换与调度控制,通过info threads查看所有线程,thread [线程ID]切换当前调试线程,set scheduler-locking on可锁定当前线程,避免其他线程干扰单步执行,对于C++程序,GDB还支持虚函数跟踪(info vtbl [对象名])和异常捕获(catch throw)。
若命令行操作不便,可使用GDB的文本用户界面(TUI),通过gdb -tui ./a.out启动,界面分屏显示源码、寄存器与命令行;或借助图形化工具如DDD(ddd ./a.out),通过可视化界面设置断点、查看变量,降低操作门槛。
熟练掌握GDB单步调试技巧,能显著提升程序问题定位效率,是Linux开发者必备技能。
FAQs

Q1:GDB单步执行时如何查看数组或指针指向的内容?
A1:使用print命令结合数组索引或指针解引用,对于数组int arr[5],p arr[0]@5可打印整个数组;对于指针int *ptr,p *ptr查看指针指向的值,p *ptr@3查看从ptr地址开始的3个元素,若需查看内存内容,还可使用x/[格式] [地址],如x/5wd ptr以十进制格式查看ptr地址开始的5个32位整数。
Q2:调试时如何跳过循环体,直接执行到循环结束后的代码?
A2:使用until [行号](缩写u)命令,当前在循环内部(第15-30行),输入u 35(假设循环结束在第35行),程序会继续执行直到第35行或退出循环,若循环内嵌套函数调用,until会跳过函数调用,直接执行到指定行;若需跳过整个循环,可在循环前设置断点,通过continue执行到循环后,再结合next跟踪后续代码。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/35999.html