接手一个软件,前辈们把一些核心功能封装进了几个DLL,所以没有源代码,你懂的现在软件在运行时会不定时(注意是不定时)产生异常,异常信息为:"0x004c5032"指令引用的"0x00000000"内存,该内存不能为"Read"。参考了网上一些方法,如《仅通过崩溃地址找出源代码的出错行》等但都没能找到问题点,后来偶然发现这个0x004c5032地址可能是在某一个DLL中,问题是DLL没有源代码,有没有办法像计算主程序代码行一样,计算出DLL中的异常代码行??急求各位大哥及高人的指点,不胜感激!异常DLL定位
解决方案 »
- 在做基于wince的串口通信,棘手了!请大侠帮忙!
- 怎么把pDC里的内容复制到CBitmap里
- 关于打开文件的编程
- 哪位朋友知道在哪里可以下载到 cegui 类库??谢谢
- CSocket的send函数可否改成非阻塞的,这种情况用什么send好啊
- 急求:24位彩色图像分割k—均值算法!
- 在一个GUI程序中要调用一个费时计算的funciton,有哪些方法能避免界面没有响应?
- 怎么将一个文本文件的每一行的每一列保存到变量中
- 在win7非管理员用户注册组件失败,是不是com会死在win7?
- 很久没写activex了,今天需要写一个程序,但是OnDraw不起作用了
- GDI 图像处理问题
- CoCreateInstance()需要clsid和iid,那类型库的guid是做什么用的呢?
有用的,因为那前辈认为没问题所以不理睬,如果能证明是DLL问题,就可以通过老总找他们
可我没有DLL的源代码,跟不进去,而且由于是偶发性的,我在debug下也没有截获到异常,怀疑是不是只有release下才有问题
在回调函数中写MiniDumpWriteDump即可
可我没有DLL的源代码,跟不进去,而且由于是偶发性的,我在debug下也没有截获到异常,怀疑是不是只有release下才有问题
crash有,dump中有call stack就可以看到是否由DLL中引起。
感谢两位版主的解答,有没有办法也能直接定位到DLL的代码行,就像通过分析map文件能定位主程序代码行一样??
虎哥 有例子吗,实在没做过SetUnhandledExceptionFilter + Minidump,
回调函数函数例子:LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *pExceptionPointers)
{ SetErrorMode( SEM_NOGPFAULTERRORBOX ); //收集信息
CString strBuild;
strBuild.Format(_T("Build: %s %s"), __DATE__, __TIME__);
CString strError;
HMODULE hModule;
TCHAR szModuleName[MAX_PATH] = _T("");
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)pExceptionPointers->ExceptionRecord->ExceptionAddress, &hModule);
GetModuleFileName(hModule, szModuleName, ARRAYSIZE(szModuleName));
strError.AppendFormat(_T("%s %d , %d ,%d."), szModuleName,pExceptionPointers->ExceptionRecord->ExceptionCode, pExceptionPointers->ExceptionRecord->ExceptionFlags, pExceptionPointers->ExceptionRecord->ExceptionAddress); //生成 mini crash dump
BOOL bMiniDumpSuccessful;
// TCHAR szPath[MAX_PATH];
TCHAR szFileName[MAX_PATH];
TCHAR* szAppName = _T("OCTOPUS");
TCHAR* szVersion = _T("v1.0");
DWORD dwBufferSize = MAX_PATH;
HANDLE hDumpFile;
SYSTEMTIME stLocalTime;
MINIDUMP_EXCEPTION_INFORMATION ExpParam;
GetLocalTime( &stLocalTime );
CString cstrName = GetAppPath(); memset(szFileName,0,MAX_PATH); TCHAR abPath[MAX_PATH];
memset(abPath,0,MAX_PATH);
memcpy(abPath,cstrName.GetBuffer(),cstrName.GetLength()); // StringCchPrintfA( szFileName, MAX_PATH, _T("%s%s"), cstrName.GetBuffer(), szAppName );
// CreateDirectory( szFileName, NULL );
StringCchPrintfA( szFileName, MAX_PATH, _T("%04d%02d%02d-%02d%02d%02d-%ld-%ld_%s.dmp"),
stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond,
GetCurrentProcessId(), GetCurrentThreadId(),OCTOPUS_VERSION_NUM); strcat(abPath,szFileName); hDumpFile = CreateFile(abPath, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);// MINIDUMP_USER_STREAM UserStream[2];
// MINIDUMP_USER_STREAM_INFORMATION UserInfo;
// UserInfo.UserStreamCount = 1;
// UserInfo.UserStreamArray = UserStream;
// UserStream[0].Type = CommentStreamA;
// UserStream[0].BufferSize = strBuild.GetLength()*sizeof(TCHAR);
// UserStream[0].Buffer = strBuild.GetBuffer();
// UserStream[1].Type = CommentStreamA;
// UserStream[1].BufferSize = strError.GetLength()*sizeof(TCHAR);
// UserStream[1].Buffer = strError.GetBuffer(); ExpParam.ThreadId = GetCurrentThreadId();
ExpParam.ExceptionPointers = pExceptionPointers;
ExpParam.ClientPointers = TRUE; // MINIDUMP_TYPE MiniDumpWithDataSegs = MiniDumpNormal
// | MiniDumpWithUnloadedModules
// | MiniDumpWithIndirectlyReferencedMemory
// | MiniDumpScanMemory
// | MiniDumpWithProcessThreadData
// | MiniDumpWithThreadInfo; bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
hDumpFile, MiniDumpNormal/*MiniDumpWithPrivateReadWriteMemory*/, &ExpParam, NULL, NULL); if(TRUE == bMiniDumpSuccessful)
{
//AfxMessageBox(_T("Please send dmp file to the developers!\n They will deal with the trouble!"));
if(IDOK==MessageBox(NULL,_T("Confirm to send the crash information to the developer for improvement?"),_T("Er...,Octopus crashed!"),MB_OKCANCEL))
{
char cUserName[255];
char errInfo[256];
memset(cUserName,0,sizeof(cUserName));
memset(errInfo,0,sizeof(errInfo)); DWORD dwcbBuffer = 255;
GetUserName(cUserName,&dwcbBuffer);
sprintf_s(errInfo,"%s%s","this dmp file is sent off by user:",cUserName); char* attachFiles[2];
attachFiles[0]=(char*)malloc(sizeof(char)*256);
attachFiles[1]=(char*)malloc(sizeof(char)*256); memset(attachFiles[0],0,256);
memset(attachFiles[1],0,256); strcpy(attachFiles[0],abPath); int res=sendmail(errInfo,attachFiles,1);
if(0 == res)
{
AfxMessageBox(_T("Send dmp File Successfully!"));
}
else
{
AfxMessageBox(_T("Send dmp File Failed!"));
}
}
}
else
{
int id;
id = GetLastError();
CString cstrId;
cstrId.Format(_T("dmp File Create Failed!Please check your memory!ID:%d"),id);
AfxMessageBox(cstrId);
} exit(0); return EXCEPTION_EXECUTE_HANDLER/*EXCEPTION_CONTINUE_SEARCH*/; //或者 EXCEPTION_EXECUTE_HANDLER 关闭程序
}
感谢两位版主的解答,有没有办法也能直接定位到DLL的代码行,就像通过分析map文件能定位主程序代码行一样??
结合DLL对应的PDB文件,windbg可以帮你找到代码行数
正好要问老大这个问题,这几个DLL人家连源代码都不给,更不可能有PDB文件了,只有一个DLL还能定位吗?
另外,按虎哥的方法生成了DMP文件,但我觉得有个问题,这个dmp文件是针对整个软件的,而DLL部分只有头文件没有源代码,还能通过dmp文件实现定位吗?
正好要问老大这个问题,这几个DLL人家连源代码都不给,更不可能有PDB文件了,只有一个DLL还能定位吗?
看12L
谢谢,可没明白您的意思怎么做另外,虽然我也想运行给那人看,让他低头认错,但我更想找出实际出错的地方,以解决问题为主
profile一般情况下能直接定位错误,相当于你od载入
正好要问老大这个问题,这几个DLL人家连源代码都不给,更不可能有PDB文件了,只有一个DLL还能定位吗?
直接把dump crash的call stack打印给别人看