2010-04-29 16 views
0

Nous avons une application C#, appelant une classe C++ wrapper simple, qui appelle ensuite une DLL C++ existante. Le code C++ est tout VC++ 6.0.Coulée entre variant et bstr_t provoquant un crash incohérent dans Windows 2008

Nous obtenons un comportement incohérent, mais le plantage, quand il arrive, se produit toujours dans la DLL encapsuleur C++, et toujours au même endroit (ont confirmé en utilisant des instructions de journalisation douloureuses). Cela n'arrive jamais sur n'importe quel environnement, sauf sur Windows 2008, donc nous soupçonnons que quelque chose de mauvais mais pas mortel est en train de se passer sur Windows 2008.

Voici le code approprié, si quelqu'un a des idées sur la raison pour laquelle cela pourrait se bloquer, il serait très apprécié. Nous nous sommes arraché les cheveux pendant quelques jours et les délais du projet sont en train de glisser pour ne pas pouvoir retourner une simple chaîne en C# ...

On m'a dit que nous avions essayé de régler le VARIANT vresult utilisant VariantInit, et l'effaçant lorsque nous avons terminé avec VariantClear, mais cela n'a pas aidé.

// 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; 
} 

Encore une fois, toutes les idées beaucoup, très appréciées.

Répondre

1

Les opportunités de corruption de tas et de pile abondent. Ne pas initialiser la variante est suicidaire. Copier une chaîne C dans un char local [] sans vérifier la longueur espère toujours avoir de la chance. Les vrais dégâts pourraient être faits n'importe où, execute_job() ou quelque chose qui a fonctionné il y a une demi-heure. Considérons un outil pour attraper des erreurs comme celles-ci, quelque chose comme Coverity.