背景
调试 Linux 程序一般有两种, 一种是检查程序的日志输出, 但如果问题与 IO 有关就不能通过日志获得调试信息了;
虽然 gdb 不常用且命令复杂, 但却是不可或缺呀.
常用调试命令
分类 | 序号 | 命令 | 说明 |
运行 | 1 | r | run 简写,运行程序,遇到断点暂停 |
2 | c | continue 简写,继续执行直到下一个断点或程序结束 | |
3 | n | next 简写,单步跟踪,遇函数调用时不进入函数体 | |
4 | s | step 简写,单步进入,遇函数调用时进入函数体 | |
5 | until | 如果进入循环体,until 将继续执行直到跳出循环体 | |
6 | until +n | 继续运行,到第 n 行暂停 | |
7 | finish | 继续执行,直到当前函数返回,并打印函数返回时的堆栈地址及返回值等相关信息 | |
8 | call 函数 (参数) | 手动调用程序中的可见函数并传参 | |
9 | q | quit 简写,退出 gdb | |
断点 | 10 | b line/func if a > b | 设置条件断点,断点位置是某文件的某行或某个函数入口处,如果条件成立则断点设置成功 |
11 | delete n | 删除第 n 个断点 | |
12 | disable n | 暂停第 n 个断点 | |
13 | enable n | 开启第 n 个断点 | |
14 | clear n | 删除第 n 行上的断点 | |
15 | info b | 查看断点设置情况 | |
16 | delete breakpoints | 删除所有断点 | |
查看源码 | 17 | l | 接着显示上次显示的后面的源码 |
18 | l n | 显示第 n 行附近的源码 | |
19 | l func | 显示函数 func 附近的源码 | |
打印表达式 | 20 | print a | 打印变量 a 的值 |
21 | print ++a | a 加 1 后打印 | |
22 | print name | 打印字符串 name 的值 | |
23 | priint func(n) | 调用函数 func 并传参 n,n 可以是一个常量,也可以是一个程序中已定义的变量 | |
24 | display 表达式 | 常用于单步调试 | |
25 | watch 表达式 | 监视表达式,当表达式的值改变时运行暂停并打印监视点的值 | |
26 | whatis | 查询变量或函数 | |
27 | info function | 打印所有函数信息 | |
28 | info locals | 显示当前堆栈的所有变量 | |
查询运行状态 | 29 | where/bt | 查看当前堆栈列表 |
30 | bt backtrace | 显示当前调用堆栈 | |
31 | up/down | 改变堆栈深度 | |
32 | set args 参数 | 设置运行参数 | |
33 | show args | 查看运行参数 | |
34 | info program | 查看运行状态 | |
分割窗口 | 35 | layout src | 显示源码窗口 |
36 | layout asm | 显示反汇编窗口 | |
37 | layout regs | 显示源码 / 反汇编和 CPU 寄存器窗口 | |
38 | layout split | 显示源码和反汇编窗口 | |
39 | ctrl + l | 清空窗口 |
调试流程总结
- #include <iostream>
- using namespace std;
- int func(int n){
- int sum=0;
- for(int i=0; i<n; i++){
- sum+=i;
- }
- return sum;
- }
- int main(){
- long result = 0;
- for(int i=1; i<=100; i++){
- result += i;
- }
- cout<<"result[1-100] ="<<result<<endl;
- cout<<"result[1-250] ="<<func(250)<<endl;
- }
- SET(CMAKE_BUILD_TYPE "Debug")
- SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
- SET(CMAKE_C_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall -g -ggdb")
来源: http://www.bubuko.com/infodetail-3358786.html