0

我们有一个 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;
}

再次,非常感谢任何想法。

4

1 回答 1

1

堆和堆栈损坏的机会比比皆是。不初始化变体是自杀。在不检查长度的情况下将 C 字符串复制到本地 char[] 中希望总是很幸运。真正的损害可能发生在任何地方,execute_job() 或半小时前运行的东西。

考虑一个捕捉此类错误的工具,比如 Coverity。

于 2010-04-29T17:31:00.693 回答