我们有一个C#应用程序,调用一个简单的C++包装器类,然后调用一个现有的C++ DLL。 C++代码均为VC++ 6.0。
我们的行为不一致,但是当崩溃发生时,崩溃总是发生在C++包装DLL中,并且总是在同一位置(已使用痛苦的日志记录语句进行了确认)。除了Windows 2008之外,在任何环境下都不会发生这种情况,因此我们怀疑Windows 2008某种程度上正在引起人们的关注,但并不是致命的内存浪费。
这是相关的代码,如果有人对为什么崩溃可能有任何想法,将不胜感激。几天来,我们一直在努力工作,而项目时间表却因希望能够将简单的字符串返回给C#而溜走了。
有人告诉我,我们尝试使用VariantInit设置VARIANT vresult,并在使用VariantClear完成操作后将其清除,但这无济于事。
// JobMgrDll.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "JobMgrDll.h"
#include "jobmgr.h"
CString gcontext;
CString guser;
CString ghost;
CString glog;
JOBMGRDLL_API int nJobMgrDll=0;
extern "C" JOBMGRDLL_API char* perform_billcalc(char* cmd, char* context, char* user,char* host,BSTR* log,int* loglen)
{
char* result = new char[1000];
memset(result,0,999);
result[999] = '\0';
bstr_t bt_command = cmd;
UUID uuid = __uuidof(BRLib::Rules);
VARIANT vresult;
char *p_rv;
gcontext = context;
guser = user;
ghost = host;
write_log("execute_job");
p_rv = execute_job(uuid, "none", bt_command, &vresult);
write_log("DONE execute_job");
CString message;
write_log ("Intializing bstr_t with variant"); // WE ALWAYS GET HERE
bstr_t res(vresult);
//message.Format("%s result = %s",p_rv,res);
//write_log(message);
write_log("copying Result"); // WE DON'T ALWAYS GET HERE, BUT SOMETIMES WE DO
strcpy(result,(char*)res);
write_log(CString(result));
*loglen = glog.GetLength();
*log = glog.AllocSysString();
return result;
}
同样,任何想法都非常感谢。
最佳答案
堆和堆栈损坏的机会比比皆是。不初始化变量会导致自杀。在不检查长度的情况下将C字符串复制到本地char []中一直希望很幸运。真正的损坏可以在任何地方执行,execute_job()或半小时前运行。
考虑一种工具来捕获此类错误,例如Coverity。