我正在尝试为我的最终用户制作一个工具,如果应用程序挂起(即应用程序的外部),它可以创建我的应用程序的MiniDump。我使用与内部MiniDumper相同的代码,但使用应用程序的句柄和进程Im,但在调用MiniDumpWriteDump时,我一直收到错误代码0xD0000024。有什么想法吗?
void produceDump( const char* exe )
{
DWORD processId = 0;
HANDLE process = findProcess(exe, processId);
if (!process || processId == 0)
{
printf("Unable to find exe %s to produce dump.\n", exe);
return;
}
LONG retval = EXCEPTION_CONTINUE_SEARCH;
HWND hParent = NULL; // find a better value for your app
// firstly see if dbghelp.dll is around and has the function we need
// look next to the EXE first, as the one in System32 might be old
// (e.g. Windows 2000)
HMODULE hDll = NULL;
char szDbgHelpPath[_MAX_PATH];
if (GetModuleFileName( NULL, szDbgHelpPath, _MAX_PATH ))
{
char *pSlash = _tcsrchr( szDbgHelpPath, '\\' );
if (pSlash)
{
_tcscpy( pSlash+1, "DBGHELP.DLL" );
hDll = ::LoadLibrary( szDbgHelpPath );
}
}
if (hDll==NULL)
{
// load any version we can
hDll = ::LoadLibrary( "DBGHELP.DLL" );
}
LPCTSTR szResult = NULL;
int err = 0;
if (hDll)
{
MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress( hDll, "MiniDumpWriteDump" );
if (pDump)
{
char szDumpPath[_MAX_PATH];
char szScratch [_MAX_PATH];
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
char comAppPath[MAX_PATH];
SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA , NULL, SHGFP_TYPE_CURRENT, comAppPath );
//COMMONAPP_PATH
_snprintf(szDumpPath, _MAX_PATH, "%s\\DN", comAppPath);
CreateDirectory(szDumpPath, NULL);
_snprintf(szDumpPath, _MAX_PATH, "%s\\DN\\D", comAppPath);
CreateDirectory(szDumpPath, NULL);
_snprintf(szDumpPath, _MAX_PATH, "%s\\DN\\D\\dumps", comAppPath);
CreateDirectory(szDumpPath, NULL);
char fileName[_MAX_PATH];
_snprintf(fileName, _MAX_PATH, "%s_Dump_%04d%02d%02d_%02d%02d%02d.dmp", exe, timeinfo->tm_year+1900, timeinfo->tm_mon, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec );
_snprintf(szDumpPath, _MAX_PATH, "%s\\DN\\D\\dumps\\%s", comAppPath, fileName);
// create the file
HANDLE hFile = ::CreateFile( szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if (hFile!=INVALID_HANDLE_VALUE)
{
MINIDUMP_CALLBACK_INFORMATION mci;
mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE)MyMiniDumpCallback;
mci.CallbackParam = 0;
MINIDUMP_TYPE mdt = (MINIDUMP_TYPE)(MiniDumpWithPrivateReadWriteMemory |
MiniDumpWithDataSegs |
MiniDumpWithHandleData |
//MiniDumpWithFullMemoryInfo |
//MiniDumpWithThreadInfo |
MiniDumpWithProcessThreadData |
MiniDumpWithUnloadedModules );
// write the dump
BOOL bOK = pDump( process, processId, hFile, mdt, NULL, NULL, &mci );
DWORD lastErr = GetLastError();
if (bOK)
{
printf("Crash dump saved to: %s\n", szDumpPath);
return;
}
else
{
_snprintf( szScratch, _MAX_PATH, "Failed to save dump file to '%s' (error %u)", szDumpPath, lastErr);
szResult = szScratch;
err = ERR_CANTSAVEFILE;
}
::CloseHandle(hFile);
}
else
{
_snprintf( szScratch, _MAX_PATH, "Failed to create dump file '%s' (error %u)", szDumpPath, GetLastError());
szResult = szScratch;
err = ERR_CANTMAKEFILE;
}
}
else
{
szResult = "DBGHELP.DLL too old";
err = ERR_DBGHELP_TOOLD;
}
}
else
{
szResult = "DBGHELP.DLL not found";
err = ERR_DBGHELP_NOTFOUND;
}
printf("Could not produce a crash dump of %s.\n\n[error: %u %s].\n", exe, err, szResult);
return;
}此代码在进程内部(即使用SetUnhandledExceptionFilter)可100%正常工作
发布于 2010-04-09 13:03:19
您是否使用必要的访问权限打开进程?MiniDumpWriteDump()需要使用PROCESS_QUERY_INFORMATION和PROCESS_VM_READ访问权限打开进程句柄。当使用GetCurrentProcess()时,我认为这些权限是自动授予的,但当使用OpenProcess()打开另一个进程时,您必须请求这些权限。
为此,您可能还必须使用enable SeDebugPrivilege,这会给帐户没有该权限的用户带来问题。但是,文档似乎没有明确说明SeDebugPrivilege对于PROCESS_QUERY_INFORMATION和PROCESS_VM_READ权限(而不是所有进程访问权限)是否是必需的,特别是在打开以相同用户帐户运行的进程时。
发布于 2010-04-09 13:22:39
我看到您显式地将MyMiniDumpCallback转换为PMINIDUMP_CALLBACK_INFORMATION类型。这看起来很可疑,就好像您遇到了一个编译器错误,因为类型不匹配而绕过了这个错误。PMINIDUMP_CALLBACK_INFORMATION是一个结构,而不是一个函数指针。
将函数指针直接转换为PMINIDUMP_CALLBACK_INFORMATION可能是有效的,因为该结构的第一个参数是回调函数。但再一次,它看起来真的很可疑。也许你错误地声明了回调函数(比如忘记了CALLBACK/__stdcall修饰符)。让你的代码编译,而不是先转换那些形式参数,然后我会更倾向于帮助你。
另外,你有没有检查过你的回调函数是否被调用了?
https://stackoverflow.com/questions/2598615
复制相似问题