遇到了一个奇怪的问题:

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

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

    事情是这样的 某某银行的imperva DAM审计设备出现蜂鸣的响声.经检查电源没有问题,怀疑是硬盘坏了 . 然后我就去底层查看 运行命令 :impctl platform storage raid ...

  2. 01-Coredump核心转存&&Linux程序地址分析【转】

    转自:http://www.itwendao.com/article/detail/404132.html 目录(?)[-] 一Core Dump核心转存 二Linux程序地址分析 一Core Dum ...

  3. usbnet驱动深入分析-usb虚拟网卡host端【转】

    转自:http://blog.csdn.net/zh98jm/article/details/6339320 1.驱动流程:   2.明确probe函数的功能: probe有usb core 经枚举过 ...

  4. 大数据系列之分布式计算批处理引擎MapReduce实践

    关于MR的工作原理不做过多叙述,本文将对MapReduce的实例WordCount(单词计数程序)做实践,从而理解MapReduce的工作机制. WordCount: 1.应用场景,在大量文件中存储了 ...

  5. RobotFramework基本用法(二)

    双击打开C:\Python27\Scripts目录下的 ride.py 一,定义变量,打印 1,右键File-->New Poreject,在项目下右键New suite,在套件下右键 New ...

  6. linux编译警告 will be initialized after

    http://blog.chinaunix.net/uid-17019762-id-3152012.html 作为一个有强迫症的人,实在是受不了 warning 的存在 这个warning是由于初始化 ...

  7. 02 How to Write Go Code 如何编写go语言代码

    How to Write Go Code   如何编写go语言代码 Introduction   介绍 Code organization  组织代码 Overview  概述 Workspaces  ...

  8. Python元组与字典详解

    Python 元组 Python的元组与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号,列表使用方括号. 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可. 如下实例: tup ...

  9. Javascript之浏览器兼容EventUtil

    var EventUtil = { //添加事件处理程序 addHandler: function (element, type, handler) { if (element.addEventLis ...

  10. Tomcat 上传war包后 会自动部署