遇到了一个奇怪的问题:

有一个回调函数中发生了段错误,但经检查也没有什么明显的错误,然后用排除法一点一点屏蔽,最后定位在一个函数里出错,但这个函数没什么明显错误。最后把入口参数改为引用传递就不报错误。

但隔了一段时间这个函数又报错了,原因是我加一行代码,但这行代码就是一个赋值语句;于是我不甘心,又开始排除法,最后定位到一个变量,加上它报错,不加就不报错;我一直怀疑是不是linux对一个函数的大小有限制;于是将这个函数换成全局变量,而在此函数中用的此变量时候采用指针,诶,不再报段错误了,世界终于安静了。

但不知是根本原因是什么,于是就疯狂的在网上找呀找,也找到了一点线索,原来的这个限制函数内局部变量大小的东西叫函数栈,而linux中这函数栈大小中系统定义的,程序中函数分配的栈一旦超出了这个大小,就会segmentation fault.

下面将搜集到的资料整理一下。

查看函数栈的大小:

linux函数栈空间大小的shell命令是:ulimit -s

如果上8192,单位是KB,总共8M

修改函数栈的大小:

linux函数栈空间大小的shell命令是:ulimit -s 数字

函数栈发生错误的经典场景:

1、函数如果是递归函数,且函数内部包含较大的变量,那么非常容易栈溢出。

2、函数使用了某数组,数组大小由一个宏定义或常量指定,当后期代码升级的时候,加大了宏定义或常量的大小,导致原先的代码出现栈溢出。代码扩展性差。

函数栈大小限制导致段错误实例:

#include <string.h>

#include <stdio.h>

int main()

{

int a [10 * 1024 * 1024];

a[0] = 1;

return 0;

}

上面的代码运行就会报段错误。

原因:

ulimit -s

10240

可以看到linux配置的线程栈的大小为10M。

函数里面使用了两个大的数组,超出了linux线程栈大小配置的上限,而函数调用是需要栈的,当空间不足,导致越界,所以core掉。所以在函数中劲量少使用大的数据,而是使用堆分配内存(全局变量或Malloc)。

注意:

为什么加上a[0] = 1;才会core,不加是不会core呢

因为在linux中,只有在使用时候才会分配内存,如果没有a[0]=1;并不会在栈上为a数组分配内存,所以不会导致core掉。

函数栈溢出引起的段错误segmentation fault的更多相关文章

  1. linux C++ 莫名奇异的段错误(segmentation fault),无法调用其他函数

    进来在linux下开发C++项目,遇到了非常奇怪的bug. 项目须要多线程实现,在写好代码后,每当执行到线程函数内部,当内部调用其他函数如printf.fopen等时就会提示段错误(segmentat ...

  2. Linux下的段错误(Segmentation fault)

    Linux开发中常见段错误问题原因分析 1 使用非法的内存地址(指针),包括使用未经初始化及已经释放的指针.不存在的地址.受系统保护的地址,只读的地址等,这一类也是最常见和最好解决的段错误问题,使用G ...

  3. linux: QT安装时出现段错误segmentation fault

    环境:macOS 10.14.6 VMware Fusion版本:11.0.1 QT版本:qt-creator-linux-x86_64-opensource-2.5.2.bin 安装时出现:segm ...

  4. 用gdb调试程序笔记: 以段错误(Segmental fault)为例

    用gdb调试程序笔记: 以段错误(Segmental fault)为例[转] 1.背景介绍2.程序中常见的bug分类3.程序调试器(如gdb)有什么用4.段错误(Segmental fault)介绍5 ...

  5. 利用linux信号机制调试段错误(Segment fault)

    在实际开发过程中,大家可能会遇到段错误的问题,虽然是个老问题,但是其带来的隐患是极大的,只要出现一次,程序立即崩溃中止.如果程序运行在PC中,segment fault的调试相对比较方便,因为可以通过 ...

  6. 利用linux信号机制调试段错误(Segment fault)【转】

    转自:http://blog.csdn.net/ab198604/article/details/6164517 版权声明:本文为博主原创文章,未经博主允许不得转载. 在实际开发过程中,大家可能会遇到 ...

  7. 【Z】段错误Segment Fault定位,即core dump文件与gdb定位

    使用C++开发系统有时会出现段错误,即Segment Fault.此类错误程序直接崩溃,通常没有任何有用信息输出,很难定位bug,因而无从解决问题.今天我们介绍core dump文件,并使用gdb进行 ...

  8. 结构体指针之 段错误 具体解释(segmentation fault)

    一个网友问了我一个问题.一个C程序执行出现了段错误,这个问题非常好.非常多刚開始学习的人都easy犯这个错误,详细代码例如以下: watermark/2/text/aHR0cDovL2Jsb2cuY3 ...

  9. 在Linux中调试段错误(core dumped)

    在Linux中调试段错误(core dumped) 在作比赛的时候经常遇到段错误, 但是一般都采用的是printf打印信息这种笨方法,而且定位bug比较慢,今天尝试利用gdb工具调试段错误. 段错误( ...

随机推荐

  1. 【原创】Linux环境下的图形系统和AMD R600显卡编程(1)——Linux环境下的图形系统简介

    Linux/Unix环境下最早的图形系统是Xorg图形系统,Xorg图形系统通过扩展的方式以适应显卡和桌面图形发展的需要,然而随着软硬件的发展,特别是嵌入式系统的发展,Xorg显得庞大而落后.开源社区 ...

  2. 理解mipi协议【转】

    转自:http://blog.csdn.net/wanglining1987/article/details/50202615 完成mipi信号通道分配后,需要生成与物理层对接的时序.同步信号: MI ...

  3. Tslib移植与分析【转】

    转自:http://blog.csdn.net/water_cow/article/details/7215308 目标平台:LOONGSON-1B开发板(mips32指令集)编译平台:x86PC-- ...

  4. mycat读写分离与主从切换【转】

    什么是mycat,以及mycat的优点和特性本文不做赘述,本文继续本着实战的态度,来分享一些个人对mycat的基础功能实践.本文mycat的读写分离和主从切换的环境为mysql主从环境. 如何安装my ...

  5. Java不为人知的小秘密

    Java中的main方法必须有一个外壳类,而且必须是静态的! Java中的所有函数都属于某个类的方法,所以main方法也不例外,必须放在一个类中才能编译运行. 例如: public class tex ...

  6. python之uinttest,用例执行顺序

    unittest单元测试框架, 以test开头的测试用例,默认执行顺序是按照ASC码来执行 如果有类,先排序执行类,在执行类中,再排序用例顺序执行 如果想要按照指定的顺序执行测试用例. 那么就需要用到 ...

  7. No.9 selenium学习之路之CSS定位

    CSS定位方式: 元素中间加“.”表示是class 1.通过ID定位 driver.find_element_by_css_selector("#ID值") 2.通过class定位 ...

  8. 配置sql server 2000以允许远程访问

    配置sql server 2000以允许远程访问适合故障:1. 用sql企业管理器能访问sql server 2000(因为它是采用命名管道(named pipes)方式进行方式),但用ado.net ...

  9. SQL Server存储过程的删除方法

    SQL Server存储过程的删除方法使我们经常会用到的,下面就为您介绍扩展存储过程的删除方法,如果您对SQL Server存储过程方面感兴趣的话,不妨一看. --清除SQL Server所有的危险扩 ...

  10. matlab设定mex接驳的C/C++编译器

    使用C/C++编写核心算法,使用matlab调用算法.做上层封装,通常是提升效率并提供易用性的一个不错的选择. mex需要设定接驳的C/C++编译器,官方文档在这里:https://ww2.mathw ...