VC内存溢出一例 –- 调用约定不一致 (0)
来源:互联网 发布:java重载的定义 编辑:程序博客网 时间:2024/05/14 10:32
最近在写一个程序,调用了多个DLL,每个DLL代码都支持多线程,Debug的模式下基本调通了,但是在Release模式下,程序因为内存溢出而崩溃,中断在gs_report.c文件的298行位置(_CRT_DEBUGGER_HOOK(_CRT_DEBUGGER_GSFAILURE),如下图:
由于问题是出自某个DLL模块中,并且是多线程的,并且出现中断的断点无法回溯,很难直接定位到是哪个DLL模块的问题。在将一个一个模块被调用的代码注释后,大概确定了可能出问题的模块,以及可能的函数。由于是Release版本的问题,无法设置断点,只好用输出到Output窗口的方式调试,想进一步确定出现内存溢出的代码段。折腾了很长时间,一直没找到问题根源。
网上搜索了一下,有人是Debug版本有这样的内存溢出错误,Release版本没有,是因为字符串填充的时候超过的申请的长度,和本例的情况不一样。开始我也觉得可能是哪个DLL库字符串操作问题,仔细检查了一些,没有发现问题。
后来在测试一个作为参数传输到某个DLL中函数的字符串的时候,发现此字符串在被调用函数之后内容被改变了,而理论上被调用的函数是不改变此字符串的内容。调试了一下,发现此字符串在被调用的函数最后返回之前还是正常的,函数返回之后就不对了,也就是说函数退出之后的出栈操作有问题,不是按入栈完全相反的动作操作的。产生这个问题的原因有可能是函数的声明不对,也就是在DLL中的声明和在主程序中的声明不一致。检查了一下参数和返回值类型,是完全一致的。那会是哪不一样呢?
DLL中的声明: EXPORTDLL unsigned int MyFunction(char * appname);
主函数中的声明: typedef unsigned int (WINAPI *lpMyFunction)(char* appname);
由于问题是出自某个DLL模块中,并且是多线程的,并且出现中断的断点无法回溯,很难直接定位到是哪个DLL模块的问题。在将一个一个模块被调用的代码注释后,大概确定了可能出问题的模块,以及可能的函数。由于是Release版本的问题,无法设置断点,只好用输出到Output窗口的方式调试,想进一步确定出现内存溢出的代码段。折腾了很长时间,一直没找到问题根源。
网上搜索了一下,有人是Debug版本有这样的内存溢出错误,Release版本没有,是因为字符串填充的时候超过的申请的长度,和本例的情况不一样。开始我也觉得可能是哪个DLL库字符串操作问题,仔细检查了一些,没有发现问题。
后来在测试一个作为参数传输到某个DLL中函数的字符串的时候,发现此字符串在被调用函数之后内容被改变了,而理论上被调用的函数是不改变此字符串的内容。调试了一下,发现此字符串在被调用的函数最后返回之前还是正常的,函数返回之后就不对了,也就是说函数退出之后的出栈操作有问题,不是按入栈完全相反的动作操作的。产生这个问题的原因有可能是函数的声明不对,也就是在DLL中的声明和在主程序中的声明不一致。检查了一下参数和返回值类型,是完全一致的。那会是哪不一样呢?
DLL中的声明: EXPORTDLL unsigned int MyFunction(char * appname);
主函数中的声明: typedef unsigned int (WINAPI *lpMyFunction)(char* appname);
在VC中,EXPORTDLL定义为: #define EXPORTDLL extern “C” __declspec (dlexport); WINAPI定义为:#define WINAPI __stdcall ;回想起以前解决过的一些问题,在给回调函数传函数指针时,就为是用__stdcall还是__cdcall折腾过,所以估计这里可能是函数约定调用不一致导致的,正好和前面函数参数值被非法改变有关系。WINAPI这个调用约定是没法改的,那就修改DLL的函数。将DLL项目 Configuration Properties --> C/C++ --> Advanced --> Calling Convention设置从默认的__cdecl(/Gd)改为 __stdcall(/Gz),重新编译,重新运行,一切正常。
转自:http://leadfrenzy.net/index.php?entry=entry101206-092029
- VC内存溢出一例 –- 调用约定不一致 (0)
- VC内存溢出一例 –- 调用约定不一致 (_CRT_DEBUGGER_HOOK(_CRT_DEBUGGER_GSFAILURE)
- VC内存溢出一例 –- 调用约定不一致 (_CRT_DEBUGGER_HOOK(_CRT_DEBUGGER_GSFAILURE)
- 论VC调用约定
- VC 调用约定
- 剖析VC++函数调用约定
- 剖析VC++函数调用约定
- pb调用vc dll约定
- 剖析VC++函数调用约定
- 剖析VC++函数调用约定
- 剖析VC++函数调用约定
- VC函数调用约定[转贴]
- pb调用vc dll约定
- [ZZ]剖析VC++函数调用约定
- 转载:剖析VC++函数调用约定
- 转:剖析VC++函数调用约定
- [VC]函数调用约定解析(C/C++)
- 剖析VC++函数调用约定【转】
- zoj 3162 To Go or Not to Go 数位DP
- 学习WPF,转向移动互联网(windows phone && windows 8 )开发(下)
- 【转】hibernate 错误:org.hibernate.HibernateException: Unable to get the default Bean Validation factory
- Oblique View Frustum
- 吭啊,AFX_WM_PROPERTY_CHANGED消息
- VC内存溢出一例 –- 调用约定不一致 (0)
- 硅谷最牛逼的50个天使投资人
- 几个经常需要自定义的组件:UIScrollview、UItextView、UIButton
- Android NDK环境搭建和配置
- 淺談 PHP-MySQL, PHP-MySQLi, PDO 的差異
- Android如何键盘按键响应事
- 数据仓库缓慢变化维(Slow changing demenison) 的实现方案
- Web Workers處理多線程 - 線程單層嵌套
- 假期~