参考:段错误产生原因及简单的调试方法
作者:编程那些年
网址:https://mp.weixin.qq.com/s/KP9ZFn71CO_vB2I4igZLMA

段错误产生原因

1.访问不存在的内存地址

如下面代码,ptr没有申请空间就直接拷贝数据:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>int main(int argc, char *argv[])
{char *ptr = NULL;//This is the wrong implementation:strncpy(ptr, "abc", 3);//ptr没有申请空间就直接使用//The right way://ptr = (char *)malloc(sizeof(char) * 10);//memset(ptr, 0, 10);//strncpy(ptr, "abc", 3);return 0;
}

2.访问只读的内存地址

错误做法:往字符串常量空间拷贝新的数据

#include <stdlib.h>
#include <stdio.h>
#include <string.h>int main(int argc, char *argv[])
{char *ptr = "test";strcpy(ptr, "TEST1");return 0;
}

3.访问系统保护的内存地址

如:

#include <stdio.h>int main(int argc, char *argv[])
{int *ptr = (int *)0;*ptr = 100;return 0;
}

4.栈溢出

如:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>int main(int argc, char *argv[])
{main(argc, argv);
}

初学时两种常用的段错误调试方法

1.使用printf输出调试信息

这个是看似最简单但往往很多情况下是十分有效的调试方式,也许可以说是程序员用的最多的调试方式。简单来说,就是在程序的重要代码附近加上printf输出信息,这样可以跟踪并打印出段错误在代码中最可能出现的位置。

使用案例:
以下面这段错误代码为例:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>int main(int argc, char *argv[])
{char *ptr = NULL;//This is the wrong implementation:strncpy(ptr, "abc", 3);//ptr没有申请空间就直接使用return 0;
}

可以在代码中添加printf调试信息:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>int main(int argc, char *argv[])
{printf("line:%d\n", __LINE__); //单纯打印代码行数char *ptr = NULL;//This is the wrong implementation:printf("line:%d\n", __LINE__); //单纯打印代码行数strncpy(ptr, "abc", 3);//ptr没有申请空间就直接使用printf("line:%d\n", __LINE__); //单纯打印代码行数return 0;
}

编译运行后,会有如下输出:

line:7
line:10
Segmentation fault (core dumped)

通过日志信息,就可以看到strncpy(ptr, “abc”, 3);语句没有被执行,我们就可以根据定位到的位置来排除ptr是否是未分配空间或者分配的空间不足引发的问题

2.使用gcc和gdb

调试步骤:

1、为了能够使用gdb调试程序,在编译阶段加上-g参数,还是以下面这段错误代码为例:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>int main(int argc, char *argv[])
{char *ptr = NULL;//This is the wrong implementation:strncpy(ptr, "abc", 3);//ptr没有申请空间就直接使用return 0;
}

编译代码添加-g选项

gcc -g -o test test.c

编译出test程序,然后用gdb调试:

linux@linux:~/test$ gdb ./test
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./test...done.
(gdb) r
Starting program: /home/linux/test/test Program received signal SIGSEGV, Segmentation fault.
0x0000555555554611 in main (argc=1, argv=0x7fffffffe528) at test.c:9
9                               strncpy(ptr, "abc", 3);//ptr没有申请空间就直接使用
(gdb) quit
A debugging session is active.Inferior 1 [process 15829] will be killed.Quit anyway? (y or n) y

从输出看出,程序到SIGSEGV信号,触发段错误,并提示地址0x0000555555554611以及代码第9行出错。

当然,还有利用core文件和gdb配置配合调试、使用objdump以及catchsegv命令的其他更为复杂的调试手段,这里就不展开讲。

段错误产生原因及简单的调试方法相关推荐

  1. PAT1050 螺旋矩阵 (25 分)【全部通过 关于段错误的原因 以及测试点7】

    心得 思路:一个0~10000的数写成M*N的形式,且M>N,则M的范围是0~10000,N的范围是0~100 这个对于m,n的判断很重要,因为二维数组不能开的太大,10000*10000会显示 ...

  2. 2021-01-07关于Linux段错误的原因和解决办法(初学者)

    初学者Linux出现段错误的原因和解决办法 一.使用非法指针(内存地址),包括未经初始化的野指针和内存已经释放的指针.不存在的地址.受系统保护的地址或只读地址.(此类段错误最常见) 解决办法: GDB ...

  3. Segmentation fault段错误出现原因分析及解决方法笔记

    Segmentation fault段错误出现原因分析及解决方法 1.局部变量的大小过大,超过栈分配的空间导致段错误,如double a[500][500], 解决方法:大数据不要放在栈区中,可以考虑 ...

  4. 网站出现403 Forbidden错误的原因以及怎么解决的方法

    这几天刚接手一批新做的网站,在访问网站的时候,会时不时的出现403 Forbidden错误,浏览器会给出403 Forbidden错误提示,在打开Access Error中列出的URL之后, 出现以下 ...

  5. 段错误产生原因及调试总结

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

  6. linux下运行程序后出现段错误的原因和解决案例

    转自:http://blog.csdn.net/sunstars2009918/article/details/7094025 查了不少资料,好多都说是:地址错误,即你使用了没有声明的地址. 一 一个 ...

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

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

  8. linux内存不足+段错误,Linux系统内存错误产生的原因及调试方法(段错误|core dumped)[转]...

    产生段错误就是访问了错误的内存段,一般是你没有权限,或者根本就不存在对应的物理内存,尤其常见的是访问0地址. 一般来说,段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来 ...

  9. linux at24c 前几个字节错误,Linux下的段错误产生的原因及调试方法

    简而言之,产生段错误就是访问了错误的内存段,一般是你没有权限,或者根本就不存在对应的物理内存,尤其常见的是访问0地址. 一般来说,段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由 ...

最新文章

  1. java中遍历map的两种方式
  2. linux 文件系统 启动,linux kernel文件系统启动部分
  3. python 还原九宫格图片_用Python做一个好玩的朋友圈九宫格抽奖
  4. 互联网1分钟 | 0307 阿里巴巴与NBA升级中国合作伙伴关系;小米成立AIoT战略委员会...
  5. 浅谈 RocketMQ、Kafka、Pulsar 的事务消息
  6. jstat的小伙伴:找出system.gc的调用的小工具
  7. oracle数据库sql的执行过程,Oracle体系结构之SQL语句的执行过程
  8. 怎么windows升级?windows版本升级?
  9. 作为一个销售人员,要做到这些
  10. 告别软驱,Win2K3光盘中集成Raid驱动程序
  11. 【CS224N笔记】词向量和词义
  12. java设计一个转动的风扇_【scratch玩转wedo入门课】第3课 转动的风扇
  13. vue2使用element UI中Descriptions组件的遍历问题
  14. HCNE之RIP协议总结
  15. iOS开发:Protocol协议以及委托代理传值
  16. PHP:使用pecl安装 swoole
  17. Port Forwarding in Windows
  18. visual paradigm 绘图学习记录
  19. BP算法的反向传播和权值修正(1)
  20. python-检查网站更新

热门文章

  1. vue项目中所使用的element-UI / echarts
  2. 世界杯快到了,看我用Python爬虫实现(伪)球迷速成!
  3. [Mac]一些命令技巧
  4. 为MFC中的ListBox添加水平滚动条
  5. Nginx使用Expires增加浏览器缓存加速(转)
  6. oracle学习一二
  7. 仅用 []()+! 就足以实现几乎任意Javascript代码
  8. 学习笔记02:直播串讲02
  9. C++总结笔记(一)—— 基础知识汇总
  10. Oracle 数据定义语言,oracle 数据定义语言(DDL)语法