段错误产生原因

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命令的其他更为复杂的调试手段,这里就不展开讲。

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

  1. 段错误产生原因及简单的调试方法

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

  2. [转] Linux C语言 段错误bug的调试

    原来看过一次,后来当自己有段错误的时候,才想起来这个很有用.如果不用他的方法,段错误很恶心的,不好找出来的. 下面就是原文,不过 最初出处不得而知 ======================= 复制 ...

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

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

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

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

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

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

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

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

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

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

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

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

  9. c语言 段错误 指针,求教为什么指针动态申请了空间,scanf的时候还会段错误

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 while(1) { printf("是否要创建新一条学生信息?(y/n)\n"); scanf("%s",ch) ...

  10. pta c语言段错误,PTA常见错误

    1.最常犯的错误:格式错误. 在PTA程序检测中,输入输出要严格按照题目要求.输出的格式要完全按照题目要求来,该空格地方空格,该换行要换行.否则,就算你运行结果是对的,PTA还是提示你格式错误 格式错 ...

最新文章

  1. 动图与数据同步关系研究
  2. JS 触发服务器事件
  3. linux 线程--内核线程、用户线程实现方法
  4. 张志华教授《机器学习导论》和《统计机器学习》课程讲义
  5. linux100day(day6)--shell脚本简单逻辑
  6. IOS UI开发基础之超级猜图完整版本-08
  7. RTMP规范简单分析
  8. 【IT】学生数据库小结2
  9. python递归函数入门教程_Python递归函数
  10. cs231n学习笔记-激活函数-BN-参数优化
  11. 洛谷OJ1162 填涂颜色 DFS填色法
  12. redis 菜鸟教程
  13. CentOS dstat 命令详解(二)参数详解
  14. MACD回零轴有三种方式
  15. U盘删除文件时提示“文件或目录损坏且无法读取”的解决方法
  16. Android 源码之Recovery升级的过程和问题分析
  17. linux centos fedora 安装LBP2900打印机 LBP6230dn LBP6240dn
  18. android手机文件管理器,4 款 Android 文件管理器,总有一款适合你
  19. python机械臂仿真_机械臂 python
  20. 谷歌浏览器突然不能翻译了怎么解决?无法翻译此网页的解决方法

热门文章

  1. 使用适用于Windows的Ultimate Boot CD轻松地重置忘记的密码
  2. win10易升工具使用教程,win10易升如何使用
  3. Blender:雕刻笔刷动态图解(一)
  4. 《算法竞赛 入门经典》
  5. 算法竞赛入门经典第二版 2-6排列
  6. 项目从 tomcat7部署到tomcat8
  7. 机器学习-UCI数据集
  8. 1、金融企业信息化建设的必要性
  9. fanuc服务器显示6,FANUC常用系统参数说明 (6页)-原创力文档
  10. hackerrank测试题·