一、GDB的调试命令。

C语言是:cc -g tst.c -o tst;C++是g++  -g -o (生成的文件) file.cpp

C++调试程序命令:gdb  file 启动,罗列代码行数ist 1,break (行数),info break,run(r)调试运行,step(s)单步调试,查看变量 print(p) 变量名,查看堆栈式bt,继续调试continue(c),退出程序q

二、Core文件的产生

当linux程序在运行过程中挂掉的时候,可能就出现core文件。通过调试core文件就可以看出来程序在代码那个位置挂掉了。会在指定的目录下生成core文件,core文件时内存的映像并加入了调试信息,主要用来调试

用以下命令来阻止系统生成core文件:
ulimit -c 0
下面的命令可以检查生成core文件的选项是否打开:
ulimit -a
该命令将显示所有的用户定制,其中选项-a代表“all”。

不产生core文件原因,1、没有足够内存空间,2、禁用了core文件的创建,3、设置一个进程当前目录没有写文件的权限

调试core文件

ulimit  -c  unlimited 表示要生成core文件 不限制core文件的大小

三、利用gdb来调试段错误

产生段错误就是访问了错误的内存段,一般是没有权限,或者根本就不存在对应的物理内存,尤其常见的是访问0地址. 在编程中以下几类做法容易导致段错误,基本是是错误地使用指针引起的

1)访问系统数据区,尤其是往 系统保护的内存地址写数据
最常见就是给一个指针以0地址
2)内存越界(数组越界,变量类型不一致等) 访问到不属于你的内存区域

解决方法
我们在用C/C++语言写程序的时侯,内存管理的绝大部分工作都是需要我们来做的。实际上,内存管理是一个比较繁琐的工作,无论你多高明,经验多丰富,难免会在此处犯些小错误,而通常这些错误又是那么的浅显而易于消除。但是手工“除虫”(debug),往往是效率低下且让人厌烦的,本文将就"段错 误"这个内存访问越界的错误谈谈如何快速定位这些"段错误"的语句。

下面将就以下的一个存在段错误的程序介绍几种调试方法:

以下是程序代码

dummy_function(void)
  2 {
  3   unsigned char*ptr=0x00;
  4   *ptr =0x00;
  5
  6 }
  7 int main(void)
  8 {
  9
10    dummy_function();
11    return 0;
12 }

作为一个熟练的C/C++程序员,以上代码的bug应该是很清楚的,因为它尝试操作地址为0的内存区域,而这个内存区域通常是不可访问的禁区,当然就会出错了。我们尝试编译运行它:

1.利用gdb逐步查找段错误

这种方法也是被大众所熟知并广泛采用的方法,首先我们需要一个带有调试信息的可执行程序,所以我们加上“-g -rdynamic"的参数进行编译,然后用gdb调试运行这个新编译的程序,具体步骤如下:

哦?!好像不用一步步调试我们就找到了出错位置d.c文件的第4行,其实就是如此的简单。
从这里我们还发现进程是由于收到了SIGSEGV信号而结束的。通过进一步的查阅文档(man 7 signal),我们知道SIGSEGV默认handler的动作是打印”段错误"的出错信息,并产生Core文件,由此我们又产生了方法2

2.通过对core文件进行调试


哇,好历害,还是一步就定位到了错误所在地,佩服一下Linux/Unix系统的此类设计。
接着考虑下去,以前用windows系统下的ie的时侯,有时打开某些网页,会出现“运行时错误”,这个时侯如果恰好你的机器上又装有windows的编译器的话,他会弹出来一个对话框,问你是否进行调试,如果你选择是,编译器将被打开,并进入调试状态,开始调试。

Linux下如何做到这些呢?我的大脑飞速地旋转着,有了,让它在SIGSEGV的handler中调用gdb,于是第三个方法又诞生了

3.段错误时启用调试程序

1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <signal.h>
  4 #include <string.h>
  5 void dump(int signo)
  6 {
  7    char buf[1024];
  8    char cmd[1024];
  9    FILE*fh;
10   snprintf(buf,sizeof(buf),"/proc/%d/cmdline",getpid());
11    if(!(fh=fopen(buf,"r")))
12    exit(0);
13    if(!fgets(buf,sizeof(buf),fh))
14    exit(0);
15    fclose(fh);
16    if(buf[strlen(buf)-1]='\n')
17    buf[strlen(buf)-1]='\0';
18    sprintf(cmd,sizeof(cmd),"gdb %s%d",buf,getpid());
19    system(cmd);
20    exit(0);
21 }
22
23 void dummy_function(void)
24 {
25   unsigned char*ptr=0x00;
26   *ptr=0x00;
27 }
28
29 int main(void)
30 {
31    signal(SIGSEGV,&dump);
32    dummy_function();
33    return 0;
34 }

怎么样?是不是依旧很酷?
以 上方法都是在系统上有gdb的前提下进行的,如果没有呢?其实glibc为我们提供了此类能够dump栈内容的函数簇,详见 /usr/include/execinfo.h(这些函数都没有提供man page,难怪我们找不到),另外你也可以通过gnu的手册进行学习

4.利用backtrace和objdump进行分析

1#include <execinfo.h>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <signal.h>
  5 void dummy_function(void)
  6 {
  7
  8     unsigned char*ptr=0x00;
  9     *ptr=0x00;
10
11 }
12 void dump(int signo)
13 {
14
15   void*array[10];
16   size_t size;
17   char**strings;
18   size_t i;
19
20   size=backtrace(array,10);
21   strings =backtrace_symbols(array,size);
22
23   printf("Obtained %zd stack frames.\n",size);
24
25   for(i=0;i<size;i++)
26   {
27     printf("%s\n",strings[i]);
28
29
30   }
31
32   free(strings);
33
34   exit(0);
35
36 }
37
38 int main(void)
39 {
40    signal(SIGSEGV,&dump);
41    dummy_function();
42    return 0;
43 }

这次你可能有些失望,似乎没能给出足够的信息来标示错误,不急,先看看能分析出来什么吧,用objdump反汇编程序,找到地址0x804876f对应的代码位置:

GDB调试命令以及GDB调试段错误相关推荐

  1. 使用gdb和core dump迅速定位段错误

    使用gdb和core dump迅速定位段错误 关键字:gdb.段错误.core dump 一.什么是core dump core:内存.核心的意思: dump:抛出,扔出: core dump:前提: ...

  2. linux core文件调试,Linux程序调试助手–core,解决段错误!

    出现问题,不知道怎么解决,出现段错误,解决不了.那试一下core文件信息吧! 采用core文件的方法 1.core文件在什么位置创建? 在进程当前工作目录的下创建.通常与程序在相同的路径下.但如果程序 ...

  3. python gdb coredump_Linux段错误及GDB Coredump调试方法

    最近在Linux环境下做C语言项目,由于是在一个原有项目基础之上进行二次开发,而且项目工程庞大复杂,出现了不少问题,其中遇到最多.花费时间最长的问题就是著名的"段错误"(Segme ...

  4. Linux环境下段错误的产生原因及调试方法小结

    From:http://www.cnblogs.com/panfeng412/archive/2011/11/06/2237857.html 最近在Linux环境下做C语言项目,由于是在一个原有项目基 ...

  5. [转]Linux环境下段错误的产生原因及调试方法小结

    最近在Linux环境下做C语言项目,由于是在一个原有项目基础之上进行二次开发,而且项目工程庞大复杂,出现了不少问题,其中遇到最多.花费时间最长的问题就是著名的"段错误"(Segme ...

  6. Linux下的段错误产生的原因及调试方法-转

    分类: Linux--Ubuntu入门级 重学C/C++2011-10-19 22:13 332人阅读 评论(0) 收藏 举报 因为你调用了glibc的fputs 检查你传进去的char* +++++ ...

  7. Linux平台Segmentation fault(段错误)调试方法

    1. 段错误是什么 一句话来说,段错误是指访问的内存超出了系统给这个程序所设定的内存空间,例如访问了不存在的内存地址.访问了系统保护的内存地址.访问了只读的内存地址等等情况. 2. 段错误的原因 段错 ...

  8. Linux下段错误以及调试方法

    1. 段错误是什么 一句话来说,段错误是指访问的内存超出了系统给这个程序所设定的内存空间,例如访问了不存在的内存地址.访问了系统保护的内存地址.访问了只读的内存地址等等情况.这里贴一个对于" ...

  9. Linux环境下段错误的产生原因及调试方法

    1. 段错误是什么 一句话来说,段错误是指访问的内存超出了系统给这个程序所设定的内存空间,例如访问了不存在的内存地址.访问了系统保护的内存地址.访问了只读的内存地址等等情况.这里贴一个对于" ...

最新文章

  1. RAC修改数据库的spfile位置
  2. ps查看oracle进程数,通过ps -ef | grep oracle查出的进程,怎样对应数据库中跑的进程...
  3. ITK:重新采样分割图像
  4. NEFU709(第K个圆的半径)
  5. C# DataSet转JSON
  6. boot空间不足 linux,linux——boot空间不足
  7. 2021年营销数智化趋势洞察报告:深链经营孕育品牌发展新商机.pdf(附下载链接)...
  8. 数据结构期末复习(四)
  9. 【狂神Mybatis笔记】配置解析
  10. Julia : 关于Atom中的Julia代码排版
  11. 【车牌识别】基于matlab GUI BP神经网络车牌识别【含Matlab源码 669期】
  12. 10页PPT,看懂 SaaS 客户生命周期
  13. 大时代背景下商业地产的数十年转型发展之路
  14. Tbase 源码 (六)
  15. 用户画像标签数据开发之标签权重计算
  16. 基于DRL的城市TSC 综述笔记(一)
  17. 如何在SuperMap iDesktop制作卫星地图
  18. 多条件模糊分页查询(angular+primeng+springboot)
  19. Tilemap瓦片地图
  20. Win10无法使用内置管理员账户打开应用解决办法

热门文章

  1. 计算机网络中的名词简称(中英文对照)_第三章
  2. getopts函数简介
  3. 脚本录制和回放终端会话(script、scriptreplay)使用
  4. 算法总结-UT哈希算法
  5. 汇编指令学习(MOV,MOVSX,MOVZX,LEA,XCHG)
  6. 论文阅读笔记:《一种改进的图卷积网络半监督节点分类》
  7. python break函数用法_Python break用法详解
  8. 大数据Spark实战第七集 机器学习和数据处理
  9. JavaSE-day22
  10. 外贸版ChatGPT,每天节省5小时开发客户时间,可以用来干这些事情