一个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分配的堆的内存使用越界,导致栈溢出吗?不同操作系统保护不一样?
...全文
418 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
  • 打赏
  • 举报
回复
打开链接下载源码: https://pan.quark.cn/s/e18529987bb9 ### ETS中文教程:KNX施耐德智能家居 #### 知识点一:ETS软件概述与启动 ETS(Engineering Tool Software)是由施耐德电气研发的一款专业设计工具,其核心功能在于构建和配置基于KNX标准的智能家居及楼宇自动化系统。KNX代表一种国际公认的开放式标准,该标准在楼宇自动化领域得到广泛应用,其目的是实现不同品牌设备之间的互联互通。 **软件启动方法**:ETS软件可以通过双击其图标来启动,或者从开始菜单中选择“File”->“New Project”,亦或直接使用Ctrl+N快捷键来启动该软件。 #### 知识点二:工程项目创建 在启动新的工程项目时,需要遵循以下流程: 1. **项目命名**:推荐使用数字与字母的组合来命名项目,例如“Officebuildings”,这样的命名方式有助于日后的管理和识别。 2. **构建建筑物模型**:在“Buildings/Functions”部分添加建筑物,自定义其名称(例如“mg”),并确认创建操作。 3. **添加房间**:针对每一个建筑物,可以进一步添加房间,同样地,为房间自定义名称(如“1F”),以此来构建完整的建筑模型。 #### 知识点三:设备加载与配置 设备加载是ETS软件中的核心环节,其作用在于将实际的智能设备(包括开关、传感器等)整合到项目中: 1. **设备加载过程**:在目标房间处进行右键点击,选择“Add Devices”,随后通过“Product Finder”对话框选择合适的制造商和产品系列,以此来加载所需的设备类型。 2. **地址分配**:在设备加载完成后,应手动为其分配独...
代码下载链接: https://pan.quark.cn/s/a4b39357ea24 在客户端编程中,有时我们需要对用户上传的Excel文件内容进行管理,并将其化为JSON格式以便进行后续操作或与服务器端进行数据交换。这一过程通常包含文件读取、数据解析以及格式换等步骤。以下是一些关于如何运用JavaScript达成这一功能的核心要点: 1. **File API**:在当前版本的浏览器中,我们可以借助File API来获取用户上传的文件。`FileReader`对象提供了异步获取文件内容的方法,例如`readAsArrayBuffer()`,用于读取文件内容。 2. **XLSX库**:由于浏览器自带的API不直接支持Excel文件的解析,我们需要借助第三方库。其中,`xlsx`库是一个广受欢迎的选择,它能解析多种Excel文件格式(如XLS、XLSX、CSV等)并提供便捷的数据操作接口。 3. **获取Excel文件**:借助`xlsx`库,我们首先需要将File API获取到的`ArrayBuffer`换为可解析的格式。例如,可以调用`XLSX.read(arrayBuffer, {type: buffer})`进行格式换。 4. **解析工作表内容**:`xlsx`库解析完成后,会返回一个对象,其中包含了所有工作表的信息。我们可以通过`XLSX.utils.sheet_to_json(worksheet)`方法将单个工作表换为二维数组,这类似于Excel中的表格数据。 5. **化为JSON对象**:二维数组可以很方便地化为JSON对象。遍历数组,每行数据作为JSON对象的一个属性,属性名为单元格的列名,属性值为单元格的值。可以使用`Arr...
源码下载地址: https://pan.quark.cn/s/de26074cf420 CadLib4.0被定位为一个功能丰富的.NET CAD类库,它为开发人员提供了在C#或其它.NET编程语言环境中嵌入CAD功能的可能性,从而简化了DWG和DXF文件的构建与修改过程。这个压缩文件内含了必要的DLL组件以及一个基于WinForms的应用实例,该实例清晰展示了在Visual Studio 2010开发环境中如何进行CAD文件的读取和处理,特别是对于AutoCAD 2014所支持的最新文件格式具备良好的兼容性。 1. **CadLib**:CadLib作为核心的类库,为与AutoCAD的DWG和DXF文件进行交互提供了接口和实现机制。它通过封装CAD数据结构和相关操作,让开发人员无需深入探究底层CAD格式细节,即可便捷地完成CAD文件的输入输出操作。 2. **WW.Cad.dll**:此DLL文件被视为CadLib的核心构成部分,其中汇集了所有与CAD操作直接关联的类和函数。例如,开发人员可借助此库来初始化新的图纸,向其中添加各类几何元素(比如直线、圆形、多段线等),或是提取已有图纸中的数据信息。 3. **WW.dll**:该DLL可能扮演着CadLib的辅助角色,里面存放了通用的工具函数和类,它们为CadLib各项功能的实现提供了支持。这些功能可能涵盖数据换、异常管理或图形的视觉呈现等方面。 4. **WW.Pdf.dll**:此文件或许具备将CAD图纸内容换为PDF文档的能力。开发者可利用这一特性,将设计成果导出为PDF格式,方便进行打印或在线传播,而无需借助AutoCAD软件。 5. **WW.GL.dll**:从其命名推断,该文...

65,213

社区成员

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

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