最近在一个项目中,使用两个DLL模块。DLLOne用于数据通信,DLLTwo用于业务流程处理,DLLTwo调用了DLLOne中的接口,还有一个exe主程序调用了DLLTwo。在使用VS2015调试时,发现程序发生了异常中断。但是直接双击生成的exe文件程序不会崩溃。
查看调用的堆栈,发现中断的地方位于c++运行库的dllmain_crt_process_attach模块中。
通过排除法,定位到问题点,分别是一个DLL中的socket(AF_INET, SOCK_STREAM, 0)和另外一个模块中的::CoInitialize(NULL) 。当这两个同时存在时,程序会在运行到DLLOne的sg_sock = socket(AF_INET, SOCK_STREAM, 0)后崩溃。
崩溃截图:
DLLOne代码片段:
static SOCKET sg_sock = NULL;
static fd_set sg_rfds;
class SleepUtilInner
{
public:
SleepUtilInner()
{
WSADATA data;
WORD w = MAKEWORD(2, 0);
::WSAStartup(w, &data);
sg_sock = socket(AF_INET, SOCK_STREAM, 0);
}
};
static SleepUtilInner sg_inner;
DLLTwo代码片段:
#include "../DLLOne/DLLOne.h"
#pragma warning(disable: 4146)
#import "C:\Program Files (x86)\Common Files\System\ado\msado15.dll" no_namespace \
rename("EOF","adoEOF")rename("BOF","adoBOF")
DLLTWO_API int DLLTWO_Start(std::string str)
{
::CoInitialize(NULL);
DLLONE_Start(str);
return 0;
}
exe代码片段:
#include "../DLLTWO/DLLTWO.h"
int main()
{
DLLTWO_Start("d");
while (true)
{
Sleep(1000);
}
return 0;
}
解决方法
将socket第三个参数protocol的值由0改成1,2,3,6,17,58。不能设置为0或者6,根本原因需进一步调查分析。