GDB调试 core dump及debug
前言
当我们在Windows上进行开发,使用Visual Studio进行调试很简单,各种断点等用鼠标点点点就能设置。但是工作的时候,更多的是在linux服务器上跑程序,这个时候调试debug都是基于GDB的。本文主要介绍Linux下GDB调试相关,对于Windows开发人员来说,GDB鼠标点点点很简单就不过多赘述。
需要用到GDB的时候主要是两种情况:需要debug跟踪程序的单步运行结果和出现cored dump时,用GDB查看程序在哪崩溃。本文也主要从着两个方面来介绍。
gdb 分析core dump
core文件其实就是内存的映像,当程序崩溃时,存储内存的相应信息,用于对程序进行调试。当程序崩溃时便会产生core文件,其实准确的应该说是core dump文件,默认生成位置与可执行程序位于同一目录下,文件名为core。
ulimit -a
: 查看系统参数,若后面的数字为0,则代表不生成core文件
ulimit -c unlimited
: 将core文件大小设置为无限制,即生成core文件
gdb 程序名 core文件名
: 查看core文件
例如:
1、gdb python core.71114
2、出现以下内容
回车
3、c
4、bt(bt 显示所有帧栈)
gdb debug跟踪程序
GDB支持断点、单步执行、打印变量、观察变量、查看寄存器、查看堆栈等调试手段。在Linux环境软件开发中,GDB是主要的调试工具,用来调试C和 C++程序。
在开发过程,如果程序的运行结果不符合预期,第一时间就是打开GDB进行调试,在对应的地方设置断点,然后分析原因。下表是常用的gdb命令
命令 | 命令缩写 | 命令说明 |
---|---|---|
set args | 设置主程序的参数 | |
break | b | 设置断点 |
backtrace | bt | 列出当前堆栈中的所有帧 |
run | r | 开始运行程序。运行到第一个断点位置,如果没有断点就直接运行结束 |
next | n | 执行当前行。如果当前行包含函数调用,不会进入函数 |
step | s | 执行当前行。如果当前行包含函数调用,则进入函数,执行函数体第一条语句。注意,如果函数是库函数或者第三方提供的函数,由于没有源代码,也无法进入函数体 |
frame | f | 栈帧用来存储函数的变量值等信息 |
p | 显示变量或表达式的值 | |
continue | c | 继续运行程序,直到下一个断点或者程序结束 |
set var name = value | 设置变量的值 | |
quit | q | 退出gdb环境 |
示例:
1、gdb ./test_main
2、b main (在main的起始地方打断点)
3、b 15 (等效于b main.cpp:15,在main.cpp的第15行打断点)
4、info b (查看断点的信息)
5、r (运行程序,并在第一个断点处暂停)
6、bt (列出当前堆栈中的所有帧)
7、s(执行了step命令,即进入函数内)
8、p (打印当前栈帧下的某个变量的值)
9、c (继续运行,在下一个断点处暂停)
10、c (直至程序结束)
11、q(停止程序)
vscode配置linux可视化gdb调试
配置好linux可视化gdb,即和Windows debug 鼠标点点点打断点操作一样简单了。
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) debug binding mlir",
"type": "cppdbg",
"request": "launch",
"program": "/home/.../test/test_main",
"args": [
],
"stopAtEntry": false,
"cwd": "/home/.../test",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
}
]
}