Linux gdb调试 coredump 基础

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
进行检测



猜你喜欢

转载自blog.csdn.net/qq_45743563/article/details/109854047