遇到了一个奇怪的问题:

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

但隔了一段时间这个函数又报错了,原因是我加一行代码,但这行代码就是一个赋值语句;于是我不甘心,又开始排除法,最后定位到一个变量,加上它报错,不加就不报错;我一直怀疑是不是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. ASM配置OGG

    两种方法:http://blog.sina.com.cn/s/blog_aa84cfe40101lsks.html 使用ACFS配置OGG:http://ylw6006.blog.51cto.com/ ...

  2. mysql处理旧数据-使用模板以及临时表,不建议直接使用本表!!

    一 业务背景新版本中新建了一个项目的角色表,即每个项目都拥有几个角色,原来历史项目是没有角色的,这就要求使用脚本对表中的历史项目进行处理, 业务需求:每个项目都要有三个角色: 表 : pm_proje ...

  3. 【HASPDOG】卸载

    rpm -qa | grep aksusdb rpm -e aksusdb... rm -rf /var/hasplm

  4. Linux下C程序的反汇编【转】

    转自:http://blog.csdn.net/u011192270/article/details/50224267 前言:本文主要介绍几种反汇编的方法. gcc gcc的完整编译过程大致为:预处理 ...

  5. plupload 上传组件的使用

    在这之前在感谢园子好多大牛的文章,在这里就不列出来了. 进入正题. svn检索https://github.com/moxiecode/plupload 获取到代码,这篇文章使用的是v2.1.8 主要 ...

  6. 【Andorid开发框架学习】之Volley入门

    Volley是Android平台上的网络通信库,能使网络通信更快,更简单,更健壮.Volley特别适合数据量不大但是通信频繁的场景.在listView显示图片这方面,使用volley也是比较好的,不必 ...

  7. Python [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed 解决方法

    一个搭建在SAE上的Django应用,使用新浪微博提供的Python SDK已经稳定运行一年有余,但最近开始持续出现微博认证失败的状况. 摘录微博python SDK的错误提示如下所示: ERROR: ...

  8. python基础--subprocess模块

    可以执行shell命令的相关模块和函数有: os.system os.spawn* os.popen*          --废弃 popen2.*           --废弃 commands.* ...

  9. MS-SQL2005服务器登录名、角色、数据库用户、角色、架构的关系

    MS SQL2005对2000进行了很大的改进,而用户关系这部分也变得相当复杂了,很多朋友都对此一知半解!下面,我将把我应用中总结的和大家分享下,先从概念入手,希望对不理解的朋友有点提示. 今天我们要 ...

  10. Effective STL 学习笔记 Item 18: 慎用 vector<bool>

    vector<bool> 看起来像是一个存放布尔变量的容器,但是其实本身其实并不是一个容器,它里面存放的对象也不是布尔变量,这一点在 GCC 源码中 vector<bool> ...