Linux gdb调试
gcc -g hello_demo.c -o hello //编译 生成调试的文件
gdb hello //开始调试
help//帮助命令
***\*设置断点\****
break 命令用于设置断点,命令接受行号或者函数名作为参数。
使用info break 可以查看当前断点得信息
使用 clear +之前设置断点得名字或者行号 可以清除断点
run 运行 到断点得地方停下
next 单步执行逐过程 next 2 执行两行
如果想继续运行,可以使用continue 命令(缩写为 c )指导 gdb 继续运行程序,直至遇到下一个断点。
如果想继续单步执行,可以继续使用 next,也是以使用 step (缩写为 s), step 和 next 的最大的区别在于,step 遇到函数是会进入到内部,而next 不会进入内部.
***\*监视变量\****
调试程序最基本的需求就是监视变量的值,可以使用 print 命令(缩写为 p) 显示指定变量的值。 停到断点处 使用p 变量名
***\*临时修改变量\****
当某些特殊情况下,我们想让程序进入一些特殊的流程时,gdb允许用户在程序运行时改变变量的值,通过 set var 命令实现这一点
set var 变量名=100
***\*查看堆栈情况\****
每次程序调用一个函数,函数的地址、参数、函数内部变量都会被压入“栈”(Stack) 中,运行时堆栈信息对于程序员非常重要,使用 “bt”命令可以看到当前运行时栈的情况。
***\*退出 gdb\****
调试完毕,使用quit命令(缩写为q) 退出 gdb程序。
安装 ftp.gnu.org/gnu/gdb/ //浏览器打开
8.0版本边 有两个红色得三角形 复制名字
Linux命令 wget http://ftp.gnu.org/gnu/gdb/复制得名字
//下载完毕 使用tar -zxvf gdb-8.1.1.tar.gz 进行解压
进入解压得目录 执行./configure 在执行make
history 查看gdb得命令
***\*注意:\****
如果系统没有安装gdb ,可以体验使用源码安装的方式来安装:
\1. wget http://ftp.gnu.org/gnu/gdb/gdb-8.1.1.tar.gz
\2. tar -zxvf gdb-8.1.1.tar.gz
\3. cd gdb-8.1.1
\4. ./configure
\5. make
\6. make install
--------------
### ***\*Coredump 调试\****
***\*coredump是什么?\****
程序异常退出时,会产生一个core文件,该文件记录了程序运行时的内存,
寄存器状态,堆栈指针,内存管理信息还有各种函数调用堆栈信息等,我们
可以理解为是程序工作当前状态存储生成的一个文件,通过工具分析这个文
件,我们可以定位到程序异常退出的时候对应的堆栈调用等信息,找出问题
所在并进行及时解决。
***\*前期设置\****
1) 设置core文件生成的目录,其中%e表示程序文件名,%p表示进程ID,
否则会在程序的当前目录生成dore文件;
echo /data/coredump/core.%e.%p >/proc/sys/kernel/core_pattern
2) 当前执行程序的用户对core目录有写权限且有足够的空间存储core文件;
3) 生成不受限制的core文件;
ulimit -c unlimited
程序异常结束之后执行
gdb 程序名 /data/coredump/生成得core文件
查看错误得位置
bt 可查看堆栈信息
如果你要查看某一层的信息,你需要切换当前的栈,一般来说,程序停止时,最顶层的栈就是当前栈,如果你要查看栈下面层的详细信息,首先要做的是切换当前栈。
frame <n>
f <n>
n是一个从0开始的整数,是栈中的层编号。比如:frame 0,表示栈顶,frame 1,表示栈的第二层。
up <n>
表示向栈的上面移动n层,可以不打n,表示向上移动一层。
down <n>
表示向栈的下面移动n层,可以不打n,表示向下移动一层。
info f
这个命令会打印出更为详细的当前栈层的信息,只不过,大多数都是运行时的内内地址。比如:函数地址,调用函数的地址,被调用函数的地址,目前的函数是由什么样的程序语言写成的、函数参数地址及值、局部变量的地址等等。如:
info args
打印出当前函数的参数名及其值。
info locals
打印出当前函数中所有局部变量及其值。
--------------------------------------------------------------------------
增加信号钩子得方式来获取错误 加头文件
#include<sinal.h>
//信号钩子函数,获取栈信息,然后在日志中打印
void handle_segv(int signum)
{
void *array[100];
size_t size;
char **strings;
size_t i;
signal(signum, SIG_DFL); /* 还原默认的信号处理handler */
size = backtrace (array, 100);
strings = (char **)backtrace_symbols (array, size);
fprintf(stderr,"Launcher received SIG: %d Stack trace:\n", signum);
for (i = 0; i < size; i++)
{
fprintf(stderr,"%d %s \n",i,strings[i]);
}
free (strings);
}
在main 函数中加入:
signal(SIGSEGV, handle_segv); // SIGSEGV 11 Core Invalid memory reference//一旦出现这个信号就调用这个函数打印堆栈(访问无效得内存)
signal(SIGABRT, handle_segv); // SIGABRT 6 Core Abort signal from//程序意外得终止 调用这个函数
注意:编译时一定要带上 -g 选项
使用addr2line命令检测:
addr2line -a 写打印出来得地址 -e demo_log
进行检测
Linux gdb调试 coredump 基础
猜你喜欢
转载自blog.csdn.net/qq_45743563/article/details/109854047
今日推荐
周排行