当前位置:网站首页>段错误产生原因及简单的调试方法(解决树莓派编译没问题,运行时出现Segmentation fault)
段错误产生原因及简单的调试方法(解决树莓派编译没问题,运行时出现Segmentation fault)
2022-04-21 22:12:00 【从入门到捕蛇者说】
段错误产生原因
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命令的其他更为复杂的调试手段,这里就不展开讲。
版权声明
本文为[从入门到捕蛇者说]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_48856218/article/details/124312300
边栏推荐
- ROS机器人从起点到终点(四)蓝桥云实践复现
- Practice of JVM custom class loader in code extensibility
- Building local canal middleware for data migration -- Inspiration from cache breakdown
- 一篇彻底搞懂-->shell脚本
- es6如何求两个数组的交集
- Test cases and design methods
- Outsourcing student management system architecture design document
- 解放双手,推荐一款阿里开源的低代码工具,YYDS~
- Free your hands and recommend a low code tool open source by Alibaba, yyds~
- 【ES6】变量的解构赋值
猜你喜欢

Intensive reading of Fanfan's anti attack paper (II) CVPR 2021 yuan learning training simulator for ultra efficient black box attack (Tsinghua)

How can "Xiaodeng" enterprises solve the problem of weak password in AD domain?

微信小程序怎么实现商品列表跳转商品详情页功能

【WebGL】简单入门教程

Document de conception de l'architecture du système de gestion des étudiants externalisé

Eventbridge integrated cloud service practice

Oracle query execution plan

IDEA通过Jedis操作Linux上的Redis;Failed to connect to any host resolved for DNS name问题

Oracle merge data operation (merge)
![[MySQL] solve the problem of MAC accessing MySQL server on windows](/img/45/53ef2fe3abed114148340787226260.png)
[MySQL] solve the problem of MAC accessing MySQL server on windows
随机推荐
Huayun actively responded to the anti epidemic call of Hefei high tech Zone: practicing social responsibility and contributing to the strength of science and technology enterprises
The @ select annotation is used in the mapper of mybtais, and the if annotation is used
软件的生命周期
【Pinia】第二章 核心概念
Compilation interrupt
Interview must brush algorithm top101 knapsack nine lectures top14
ROS -- error in compiling PCL related programs: could not find a package configuration file provided by "PCL"“
外包學生管理系統架構設計文檔
MYPINPAD和SmartPesa合并,成为移动支付受理领域的全球领导者
Mypinpad and smartpesa merged to become the global leader in mobile payment acceptance
what? Your company has not set the JVM initial and maximum heap memory size to the same value?
Interview must brush algorithm top101 knapsack nine lectures Top13
记录 splite3 库的一个坑(表名和字段定义不能用占位符?)
ES6 how to find the intersection of two arrays
每日一题-LeetCode824-山羊拉丁文-模拟
Configuration and application of STM32 peripheral GPIO
ISMAR 2022 journal paper (tvcg) contribution exchange
一篇彻底搞懂-->shell脚本
【WebGL】简单入门教程
[JVM] 10 interview questions