我已经创建了自己的调试器应用程序。它附加到进程并创建崩溃转储文件。这大多数时间都有效。我遇到的问题是,当被调试的应用程序正在等待互斥对象时,它将无法工作(这是我想要调试的问题)。
此外,我创建了一个简单的test.exe应用程序,它只是循环并调用Sleep(100)但我的调试器每次在此应用程序上调用MiniDumpWriteDump时都会失败。
我做错了什么?
我从下面的代码返回的错误代码是2147942699(0x8007012b)
void WriteCrashDump( EXCEPTION_DEBUG_INFO *pExceptionInfo )
{
CONTEXT c;
memset( &c, 0, sizeof( c ) );
GetThreadContext( hThread, &c );
EXCEPTION_POINTERS ep;
memset( &ep, 0, sizeof( ep ) );
ep.ContextRecord = &c;
ep.ExceptionRecord = &pExceptionInfo->ExceptionRecord;
MINIDUMP_EXCEPTION_INFORMATION minidump_exception;
memset( &minidump_exception, 0, sizeof( minidump_exception ) );
minidump_exception .ThreadId = dwThreadId;
minidump_exception.ExceptionPointers = &ep;
minidump_exception.ClientPointers = true;
char txDumpPath[ MAX_PATH + 1 ];
sprintf( txDumpPath, "%s.dmp", txProcess );
HANDLE hFile = CreateFile( txDumpPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( hFile )
{
BOOL fSuccess;
SetLastError( 0L );
int nDumpOptions =
MiniDumpNormal
| MiniDumpWithDataSegs
| MiniDumpWithFullMemory
| MiniDumpWithHandleData
| MiniDumpFilterMemory
| MiniDumpScanMemory
| MiniDumpWithUnloadedModules
| MiniDumpWithIndirectlyReferencedMemory
| MiniDumpFilterModulePaths
| MiniDumpWithProcessThreadData
| MiniDumpWithPrivateReadWriteMemory
| MiniDumpWithoutOptionalData
;
fSuccess = MiniDumpWriteDump( hProcess,
dwProcessId,
hFile,
(MINIDUMP_TYPE) nDumpOptions,
&minidump_exception,
NULL,
NULL );
DWORD dwErr = GetLastError();
if( ! fSuccess )
printf( "MiniDumpWriteDump -FAILED (LastError:%u)\n", dwErr );
CloseHandle( hFile );
}
}
我还尝试使用以下代码片段来增加权限,我从其他似乎有类似问题的人那里借用了代码片段:
BOOL SetDumpPrivileges()
{
BOOL fSuccess = FALSE;
HANDLE TokenHandle = NULL;
TOKEN_PRIVILEGES TokenPrivileges;
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&TokenHandle))
{
printf("Could not get the process token");
goto Cleanup;
}
TokenPrivileges.PrivilegeCount = 1;
if (!LookupPrivilegeValue(NULL,
SE_DEBUG_NAME,
&TokenPrivileges.Privileges[0].Luid))
{
printf("Couldn't lookup SeDebugPrivilege name");
goto Cleanup;
}
TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
//Add privileges here.
if (!AdjustTokenPrivileges(TokenHandle,
FALSE,
&TokenPrivileges,
sizeof(TokenPrivileges),
NULL,
NULL))
{
printf("Could not revoke the debug privilege");
goto Cleanup;
}
fSuccess = TRUE;
Cleanup:
if (TokenHandle)
{
CloseHandle(TokenHandle);
}
return fSuccess;
}
答案 0 :(得分:2)
我在MSDN上发了一个问题,有人向我提供了我的问题的答案。以下是讨论的link以及我在下面复制的工作代码段。
void WriteCrashDump( EXCEPTION_DEBUG_INFO *pExceptionInfo )
{
CONTEXT c;
memset( &c, 0, sizeof( c ) );
HANDLE hThread;
c.ContextFlags = CONTEXT_FULL;
hThread = _OpenThread( THREAD_ALL_ACCESS, FALSE, dwThreadId );
GetThreadContext( hThread, &c );
EXCEPTION_POINTERS ep;
memset( &ep, 0, sizeof( ep ) );
ep.ContextRecord = &c;
ep.ExceptionRecord = &pExceptionInfo->ExceptionRecord;
MINIDUMP_EXCEPTION_INFORMATION minidump_exception;
memset( &minidump_exception, 0, sizeof( minidump_exception ) );
minidump_exception.ThreadId = dwThreadId;
minidump_exception.ExceptionPointers = &ep;
minidump_exception.ExceptionPointers->ContextRecord = &c;
minidump_exception.ClientPointers = false;
char txDumpPath[ MAX_PATH + 1 ];
time_t tNow = time( NULL );
struct tm *pTm = localtime( &tNow );
sprintf( txDumpPath, "%s.%02d%02d%04d_%02d%02d%02d.dmp",
txProcess,
pTm->tm_mday,
pTm->tm_mon,
pTm->tm_year,
pTm->tm_hour,
pTm->tm_min,
pTm->tm_sec );
HANDLE hFile = CreateFile( txDumpPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( hFile != INVALID_HANDLE_VALUE )
{
BOOL fSuccess;
printf( "hProcess : %d (0x%x)\n", hProcess, hProcess );
printf( "dwProcessId: %u (0x%lx)\n", dwProcessId, dwProcessId );
printf( "dwThreadId : %u (0x%lx)\n", dwThreadId, dwThreadId );
SetLastError( 0L );
fSuccess = MiniDumpWriteDump( hProcess,
dwProcessId,
hFile,
MiniDumpNormal,
&minidump_exception,
NULL,
NULL );
DWORD dwErr = GetLastError();
if( ! fSuccess )
{
printf( "MiniDumpWriteDump -FAILED (LastError:%u)\n", dwErr );
LPVOID lpMsgBuf;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwErr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL );
// Display the string.
printf( "%s\n", (LPCTSTR)lpMsgBuf );
// Free the buffer.
LocalFree( lpMsgBuf );
}
}
if( hThread )
CloseHandle( hThread );
}
答案 1 :(得分:0)