遇到了一个奇怪的问题:

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

但隔了一段时间这个函数又报错了,原因是我加一行代码,但这行代码就是一个赋值语句;于是我不甘心,又开始排除法,最后定位到一个变量,加上它报错,不加就不报错;我一直怀疑是不是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. gnome桌面无法使用笔记本的触摸板

    原来使用ubuntu的时候,升级了gnome之后触摸板就不能用了,不能说不能用了,应该是自己不会配置然后不好用了,具体状况如是,可以在登录界面gdm使用触摸板以及点击,但是进入桌面之后就不能点击了.后 ...

  2. 如何使用vs2012单步调试uGUI(unity3d 5.3f4)

    下载uGUI源代码 uGUI源代码地址:https://bitbucket.org/Unity-Technologies/ui 下载代码工具:tortoisehg-3.6.2-x64.msi http ...

  3. maven profile 优先级

    maven profile是有优先级别 也就是说在setting.xml的profile优先级比pom中同名的profile高. 可以使用 mvn help:active-profiles 这个命令是 ...

  4. ParameterizedType获取java泛型参数类型

    ParameterizedType getClass().getGenericSuperclass() 返回表示此 Class 所表示的实体(类.接口.基本类型或 void)的直接超类的 Type,然 ...

  5. DOS命令大全(一)

    #1 一: net use \\ip\ipc$ " " /user:" " 建立IPC空链接 net use \\ip\ipc$ "密码" ...

  6. dedecms调用文章列表第一篇和下面几篇不同的方法

    {dede:arclist row=1 orderby=pubdate infolen=60 limit=0,1} <li class="dot1"><img s ...

  7. css同时满足两个类名才有效果的写法

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  8. python_接口自动化测试框架

    本文总结分享介绍接口测试框架开发,环境使用python3+selenium3+unittest+ddt+requests测试框架及ddt数据驱动,采用Excel管理测试用例等集成测试数据功能,以及使用 ...

  9. 可怕的线程上下文类装载器(TCCL)

    在明天的 OSGi 2012 社区活动上,我将以"如何使你的类库在不依赖 OSGi 的情况下进行友好地 OSGi"为主题进行演讲.在演讲中我将会提及 Java 的线程上下文类加载器 ...

  10. SourceTree 3.0.17如何跳过注册进行安装? — git图形化工具(一)

    SourceTree 3.0.17个人版本的尝试跳过注册方式好几次都没成功,于是下载了企业版本https://www.sourcetreeapp.com/enterprise. 安装过程: 1.首次点 ...