一个ILLEGLE INSTRUCTION转SEGMENT FAULT的诡异CORE

absunique 2016-05-09 03:24:34
碰到一个ILLEGAL INSTRUCTION后面转SEGMANET FAULT的诡异的问题,求助一下……
先简单描述一下代码结果,实际比这个复杂,但大概也差不多
a1.c/a2.c/a3.c=>LIBA.SO
e.c + LIBA.SO=>execBin

下面我开始讲述一下,查找原因的过程(前后一个月……悲剧,到现在还没找到原因),感觉进展都可以写成一个小小说了……

阶段一,这个时候,CORE原因是ILLEGAL INSTRUCTION。
只有一个ILLEGAL INSTRUCTION,文件里有CORE的地方,但是根本无法定位原因。
因此只能开始瞎猜,首先怀疑LIBA.SO,因为这是一个开源代码基本上改过来的,唯一使用MALLOC的地方。
考虑到这个SO的功能是解析配置文件,只会有主线程调用,因此将LIBA.SO中动态分配内存(MALLOC/CALLOC/STRDUP)的地方,全部改成静态分配(全局BUFFER)。

改完之后,CORE消失,但是代码本身检查过,没有问题,而且有问题,为何会造成ILLEGAL INSTRUCTION?这感觉像是段错误覆盖了栈中的代码导致?后面再看

阶段二,中间有个小插曲:因为这套代码在操作系统升级前后都跑过,升级后才有的CORE,因此使用两个环境复现:
AIX7.1.2 未出现
AIX7.1.3 基于7.1.3全新编译或使用7.1.2编译的均会出现ILLEGAL INSTRUCTION。
暂时感觉毫无任何帮助。

阶段三:
因为ILLEGAL INSTRUCTION出现的慢(不停的运行过程中才出),所以在A函数中,使用了一些无用的变量(几百K),结果在A调用B时,立马出现CORE
此时CORE变成了SEGMENT FAULT。
这里的函数A是一个用户线程的入口函数,其间会调用函数B。
尝试在创建线程A的时候,增加堆栈大小,段错误消失。

阶段四:
这里肯定要问,是不是我加的变量导致SEGMENT FAULT?
没错,但是函数A内的变量少的可怜,是谁导致它,回想到阶段一改了LIBA.SO,如何证明和LIBA.SO有关系。
于是,验证如下:
首先调用LIBA.SO中的内容,都是在主线程,在A线程中没有调用。
其次因为LIBA.SO是解析配置文件,文件越在,MALLOCL的内存越多。
好了,程序任何都不改,只改配置文件,结果:
小的配置文件,不CORE
大的配置文件,必CORE
也就是说,导致线程堆栈溢出的,并不是用户线程A中的临时变量, 而是主线程调用LIBA.SO,导致堆栈溢出。

联想起阶段一,LIBA.SO的嫌疑越来越大。

到现在,由于线头太多,全部梳理出来几个关键点:
1、LIBA.SO中动态分配内存,改成静态,OK不CORE
2、用户线程A堆栈溢出,加大堆栈,OK不CORE了
3、上述任何作法,在两个操作系统中,都是7.1.2不CORE 7.1.3CORE,即使是完全同构的代码,这和操作系统有什么关系?

问题是,什么导致溢出的?是LIBASO分配的堆的内存使用越界,导致栈溢出吗?不同操作系统保护不一样?
...全文
380 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2016-05-16
  • 打赏
  • 举报
回复
没准底层具体实现malloc时,至少需要一定大小的堆栈空间支持。
absunique 2016-05-16
  • 打赏
  • 举报
回复
引用 12 楼 zhao4zhong1 的回复:
使用link的命令行参数设置更大的堆栈。 仅供参考: /STACK (Stack Allocations) Home | Overview | How Do I | Linker Options The Stack Allocations (/STACK:reserve[,commit]) option sets the size of the stack in bytes. To find this option in the development environment, click Settings on the Project menu. Then click the Link tab, and click Output in the Category box. The Reserve text box (or in the reserve argument on the command line) specifies the total stack allocation in virtual memory. The default stack size is 1 MB. The linker rounds up the specified value to the nearest 4 bytes. The optional value specified in the Commit text box (or in the commit argument on the command line) is subject to interpretation by the operating system. In Windows NT, it specifies the amount of physical memory to allocate at a time. Committed virtual memory causes space to be reserved in the paging file. A higher commit value saves time when the application needs more stack space, but increases the memory requirements and possibly the startup time. Specify the reserve and commit values in decimal or C-language notation. Another way to set the size of the stack is with the STACKSIZE statement in a module-definition (.DEF) file. STACKSIZE overrides the Stack Allocations (/STACK) option if both are specified. You can change the stack after the .EXE file is built by using the EDITBIN tool.
增加堆栈的确可以解决。问题是没有定位到原因……该线程的局部变量非常少,而且在主线程中,如果使用的LIBA.SO中不用MALLOC,工作线程中的堆栈问题也就没有了,这个很奇怪。
赵4老师 2016-05-16
  • 打赏
  • 举报
回复
使用link的命令行参数设置更大的堆栈。 仅供参考: /STACK (Stack Allocations) Home | Overview | How Do I | Linker Options The Stack Allocations (/STACK:reserve[,commit]) option sets the size of the stack in bytes. To find this option in the development environment, click Settings on the Project menu. Then click the Link tab, and click Output in the Category box. The Reserve text box (or in the reserve argument on the command line) specifies the total stack allocation in virtual memory. The default stack size is 1 MB. The linker rounds up the specified value to the nearest 4 bytes. The optional value specified in the Commit text box (or in the commit argument on the command line) is subject to interpretation by the operating system. In Windows NT, it specifies the amount of physical memory to allocate at a time. Committed virtual memory causes space to be reserved in the paging file. A higher commit value saves time when the application needs more stack space, but increases the memory requirements and possibly the startup time. Specify the reserve and commit values in decimal or C-language notation. Another way to set the size of the stack is with the STACKSIZE statement in a module-definition (.DEF) file. STACKSIZE overrides the Stack Allocations (/STACK) option if both are specified. You can change the stack after the .EXE file is built by using the EDITBIN tool.
absunique 2016-05-16
  • 打赏
  • 举报
回复
引用 9 楼 DTCPzhuxh 的回复:
不能明确的帮楼主解决问题。之前我有遇到过相同的程序一个在aix下运行则能正常运行,但是在linux下则报段错误,所以不同的操作系统保护措施肯定是有些区别的。 给楼主两点建议: 1、aix的话用dbx应该是可以调处段错误的位置; 2、还有我看楼主多次提到malloc,不知道楼主malloc用完之后有没有使用free。
另外段错误的位置是一个SPRINTF,感觉很像线程堆栈不够用了。
absunique 2016-05-16
  • 打赏
  • 举报
回复
引用 9 楼 DTCPzhuxh 的回复:
不能明确的帮楼主解决问题。之前我有遇到过相同的程序一个在aix下运行则能正常运行,但是在linux下则报段错误,所以不同的操作系统保护措施肯定是有些区别的。 给楼主两点建议: 1、aix的话用dbx应该是可以调处段错误的位置; 2、还有我看楼主多次提到malloc,不知道楼主malloc用完之后有没有使用free。
引用 9 楼 DTCPzhuxh 的回复:
不能明确的帮楼主解决问题。之前我有遇到过相同的程序一个在aix下运行则能正常运行,但是在linux下则报段错误,所以不同的操作系统保护措施肯定是有些区别的。 给楼主两点建议: 1、aix的话用dbx应该是可以调处段错误的位置; 2、还有我看楼主多次提到malloc,不知道楼主malloc用完之后有没有使用free。
1、DBX使用REGISTERS看到有 STDU R3,-3240(R3) 这样的地方,但是这句命令看不出有啥异常啊…… 2、MALLOC使的FREE有用,但是即使不用最多也是内存泄漏,现在感觉像是堆栈溢出……
赵4老师 2016-05-10
  • 打赏
  • 举报
回复
会用→会有
赵4老师 2016-05-10
  • 打赏
  • 举报
回复
AIX会用同样问题。我觉得。
absunique 2016-05-10
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
[quote=引用 2 楼 absunique 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] C Run-Time Libraries http://msdn.microsoft.com/zh-cn/library/abx4dbyh(VS.80).aspx
请问和这个有什么关系啊?[/quote] 里面应该说明了在库中调用C Run-Time Libraries中的malloc类函数时需要注意的几个方面。[/quote]
引用 3 楼 zhao4zhong1 的回复:
[quote=引用 2 楼 absunique 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] C Run-Time Libraries http://msdn.microsoft.com/zh-cn/library/abx4dbyh(VS.80).aspx
请问和这个有什么关系啊?[/quote] 里面应该说明了在库中调用C Run-Time Libraries中的malloc类函数时需要注意的几个方面。[/quote] 大哥,我是AIX的……
DTCPzhuxh 2016-05-10
  • 打赏
  • 举报
回复
不能明确的帮楼主解决问题。之前我有遇到过相同的程序一个在aix下运行则能正常运行,但是在linux下则报段错误,所以不同的操作系统保护措施肯定是有些区别的。 给楼主两点建议: 1、aix的话用dbx应该是可以调处段错误的位置; 2、还有我看楼主多次提到malloc,不知道楼主malloc用完之后有没有使用free。
赵4老师 2016-05-10
  • 打赏
  • 举报
回复
Potential Errors Passing CRT Objects Across DLL Boundaries. https://msdn.microsoft.com/zh-cn/library/ms235460(v=vs.80).aspx
absunique 2016-05-10
  • 打赏
  • 举报
回复
引用 6 楼 zhao4zhong1 的回复:
会用→会有
引用 6 楼 zhao4zhong1 的回复:
会用→会有
引用 6 楼 zhao4zhong1 的回复:
会用→会有
你这个链接里没有啊,能不能发具体的链接?
赵4老师 2016-05-09
  • 打赏
  • 举报
回复
引用 2 楼 absunique 的回复:
[quote=引用 1 楼 zhao4zhong1 的回复:] C Run-Time Libraries http://msdn.microsoft.com/zh-cn/library/abx4dbyh(VS.80).aspx
请问和这个有什么关系啊?[/quote] 里面应该说明了在库中调用C Run-Time Libraries中的malloc类函数时需要注意的几个方面。
absunique 2016-05-09
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
C Run-Time Libraries http://msdn.microsoft.com/zh-cn/library/abx4dbyh(VS.80).aspx
请问和这个有什么关系啊?
赵4老师 2016-05-09
  • 打赏
  • 举报
回复
内容概要:本文围绕《【卫星信号】模拟卫星信号传播研究(Matlab代码实现)》这一技术资源展开,系统介绍了利用Matlab进行卫星信号传播过程建模与仿真的方法。该资源聚焦于构建卫星信号在复杂空间环境中的传播模型,综合考虑自由空间路径损耗、大气吸收、多径效应、多普勒频移、电离层闪烁及噪声干扰等多种物理因素,通过Matlab编程实现信号传输特性的动态仿真与可视化分析,帮助研究人员深入掌握卫星通信信道的关键特性与建模流程。; 适合人群:具备Matlab编程能力和通信原理基础知识的高校研究生、科研机构研究人员及从事卫星通信、导航定位、遥感遥测等领域的工程技术人员,特别适用于需要完成相关课题仿真、毕业设计或项目开发的初级与中级科研人员。; 使用场景及目标:①用于教学与课程设计中加深对卫星信号传播机制的理解;②支撑卫星通信系统链路预算、接收机灵敏度分析与抗干扰算法设计;③服务于学术论文撰写、科研项目申报中的仿真验证环节,提供可复用的代码框架与建模思路。; 阅读建议:建议读者结合经典通信理论教材同步学习,重点剖析代码中关于信号调制、信道建模、噪声叠加与接收端解调等模块的实现逻辑,动手运行并调整轨道参数、频率、环境条件等变量,观察信号质量变化,从而深化对卫星信道动态行为的认知。
内容概要:本文系统介绍了2024年最新提出的两种智能优化算法——青蒿素优化算法与霜冰优化算法(RIME),并通过Matlab代码实现对二者进行了深入对比研究。文档不仅阐述了两种算法的核心原理与数学模型,还全面展示了其在电力系统优化、新能源调度、路径规划、机器学习参数调优等复杂工程问题中的应用性能差异。文中涵盖了微电网调度、电动汽车充电优化、无人机三维路径规划、风光互补制氢系统调度等多个前沿科研方向的典型案例,并配套提供了完整的Matlab仿真代码与模型资源,便于读者复现高水平学术论文成果并开展创新性研究。; 适合人群:具备一定编程基础,熟练掌握Matlab/Simulink环境,正在从事智能优化算法相关研究的研究生、高校教师及工程技术人员,尤其适用于专注于能源系统优化、智能交通、智能制造、自动化控制等领域的科研工作者。; 使用场景及目标:①深入理解青蒿素算法与RIME算法的基本思想、迭代机制与收敛特性;②通过实际代码复现EI、顶刊级别论文中的优化模型;③在具体科研项目中对比两类算法的寻优能力、稳定性与计算效率,完成算法选型与改进;④拓展新型优化算法在多能互补系统、智能路径规划、分布式调度等交叉学科中的创新应用。; 阅读建议:建议读者结合网盘提供的完整代码资源,按照文档中给出的应用实例循序渐进地实践操作,重点关注不同场景下的参数设置策略、算法收敛曲线分析与鲁棒性表现,同时关注公众号“荔枝科研社”获取持续的技术支持与更新资料。

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧