Linux系统下gdb调试
Linux系统下gdb调试
开发环境
linux centOS
yum -y install gdb
gdb用法介绍
(1)生成带有调试信息的可运行程序,命令如下:
g++ -g main.cpp -o main //生成带有调试信息的可运行程序main,编译参数-g
测试程序hello.cpp如下:
#include<iostream>
using namespace std;
int main(){
cout<< "hello world" <<endl;
return 0;
}
生成可执行文件命令如下:
g++ hello.cpp -o hello #生成可执行文件不带调试信息
g++ -g hello.cpp -o hello_g #生成可执行文件带有调试信息
结果如下:
ls -lh # 以人类可读的方式显示当前目录中的文件和目录大小
方法1:
a> 输入gdb。
b>输入file hello
没有调试信息的结果如下:
有调试信息的结果如下:
以看出,没有调试信息的会提示:No debugging symbols found in…,有调试信息的会提示Reading symbols from …。
方法2:
使用readelf命令来显示elf格式的目标文件格式。(elf文件有三种类型:a>可重定位文件:用户和其他目标一起创建可执行文件或者共享目标文件,如lib*.a文件。b>可执行文件:生成进程映像,载入内存运行,如可执行文件*.out。c> 共享目标文件:用于和其他共享目标文件或者可重定位文件一起生成可执行文件,如*.so。)
readelf的选项参数有-a,-h,-l,-S,-g,-t,-s,-e,-n,等,此处使用参数-S,查看elf文件的节头信息,节头是对可执行程序中代码段和数据位置和大小的描述。
没有调试信息结果如下:
有调试信息的结果如下:
关于readelf命令用法可参考readelf命令_Linux readelf 命令用法详解:用于显示elf格式文件的信息 (ailinux.net)
关于elf文件节头格式描述如下:ELF文件格式第三讲,节头(section header) (icode9.com)
关于elf文件格式内容参考:ELF(文件格式)_百度百科 (baidu.com)
ELF文件格式的详解_pingxiaozhao的博客-CSDN博客_elf 文件格式
(2)运行调试程序:(gdb)run、start
*gdb调试目标程序方式(默认以不带参可执行程序为例,程序为(1)中code)start
gdb ./hello_g
run命令运行调试程序:运行程序,直到运行程序结束,或遇到断点停止(简写命令r)。运行如下:
start命令:启动可执行程序,运行到main函数的第一句出停止,如下:
附加知识:启动带参可执行程序
gdb带参程序方法start
demo的代码如下:
#include<iostream>
using namespace std;
int main(int argc, char** argv)
{
cout<< "argc value is " <<argc <<endl;
for(int i=0; i<argc; i++)
{
cout << "i is " <<i <<" Value is " <<argv[i] <<endl;
}
return 0;
}
demo 代码简单回顾:
argc参数:统计参数格式,其中记录了命令行中命令和参数的个数;
argv:指向字符指针的指针,实质时数组。里面存的数据顺序是:命令,参数1,参数2,,,
关于main函数详细可参考main函数_百度百科 (baidu.com)
//非gdb下带参程序运行
a>生成可执行文件testArgDebug,命令: g++ -g testArgDebug.cpp -o testArgDebug
b>输入带参并运行代码,命令: ./testArgDebug 1 23 4
结果如下:
//gdb下带参程序运行
gdb下带参程序的运行有以下两种方式:
a> 先设置参数,再利用run运行程序。命令:set args
该命令需要注意:如果没有设置参数,则与前一个命令使用的参数相同,该命令详细介绍可参考:
参数(使用 GDB 调试) (sourceware.org)
该方法启动程序的过程如下:
b> 在run时添加参数,启动调试程序过程如下:
上面的两种方式都可以
gdb带参程序方法end*
(3)源码查看:(gdb)list
gdb中显示源码的命令为list,需要注意的是可执行文件需要跟源码在同级目录。
测试的demo如下:
#include <iostream>
#include <string.h>
using namespace std;
void ConvertFunc(int &a,int &b)
{
a = a+b;
b = a - b;
a = a-b;
}
int FindMaxVal(int a[],int nNum)
{
int temp = 0;
for(int i = 0;i < nNum;i++)
{
if(a[i] > temp)
{
temp = a[i];
}
}
return temp;
}
int FindMinVal(int a[],int nNum)
{
int temp = 100000;
for(int i = 0;i < nNum;i++)
{
if(a[i] < temp)
{
temp = a[i];
}
}
return temp;
}
int main()
{
int nA = 10;
int nB = 20;
cout << "Before Switch nA is " << nA << " nB is " << nB << endl;
ConvertFunc(nA,nB);
cout << "After Switch nA is " << nA << " nB is " << nB << endl;
int arrnVal[] = {3,2,90,26,50};
int nMaxVal = 0;
nMaxVal = FindMaxVal(arrnVal,sizeof(arrnVal)/sizeof(arrnVal[0]));
int nMinVal = 0;
nMinVal = FindMinVal(arrnVal,sizeof(arrnVal)/sizeof(arrnVal[0]));
cout << "Arr Max val is " << nMaxVal << " Min val is " << nMinVal << endl;
return 0;
}
(4)运行参数查看show
show命令是描述gdb本身相关状态信息,通过在show后面+具体的参数可以获取对应信息。
a>show args 显示程序启动时的参数。
eg:
b>show environment 打印程序运行时的环境变量
eg:
show的参数还有更多,如 language、paths、code-cache等,可以自行查看。
(5)断点设置
设置断点、设置条件断点、查看断点、删除断点、禁用断点、运行某个断点:(gdb)break、break…if conditon、info b、delete break 1、disable break 1、enable break
使用测试的demo为(3)中的代码。
注:在启动时可以设置不显示gdb相关版本信息,命令为 gdb -q a.out
***设置断点break(简写b)
a>break function(type,type) /break class::function在函数function处设置断点.
eg:
c>break line-or-function if exp设置条件断点,在行数line处或者在function处设置具体条件
eg:
参考
https://blog.csdn.net/hanxiaoyong_/article/details/126548015