Debugging 为什么MinidumpWriteMap失败了?

Debugging 为什么MinidumpWriteMap失败了?,debugging,minidumpwritedump,Debugging,Minidumpwritedump,我已经创建了自己的调试器应用程序。它附加到进程并创建崩溃转储文件。这在大多数情况下都有效。我遇到的问题是,当被调试的应用程序正在等待互斥对象时,它将无法工作(这正是我要调试的问题) 此外,我还创建了一个简单的test.exe应用程序,它只循环并调用Sleep(100),但我的调试器每次在此应用程序上调用MiniDumpWriteDump时都会失败 我做错了什么 从下面的代码返回的错误代码是2147942699(0x8007012b) 我还尝试使用以下代码片段增加权限,这些代码片段是我从似乎有类似

我已经创建了自己的调试器应用程序。它附加到进程并创建崩溃转储文件。这在大多数情况下都有效。我遇到的问题是,当被调试的应用程序正在等待互斥对象时,它将无法工作(这正是我要调试的问题)

此外,我还创建了一个简单的test.exe应用程序,它只循环并调用Sleep(100),但我的调试器每次在此应用程序上调用MiniDumpWriteDump时都会失败

我做错了什么

从下面的代码返回的错误代码是2147942699(0x8007012b)

我还尝试使用以下代码片段增加权限,这些代码片段是我从似乎有类似问题的其他人那里借用的:

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

这个问题和我用这篇课文回答的另一个问题一样吗


即使使用标志MiniDumpWithHandleData,它也不包括互斥信息,而且它可能会失败,因为某些标志可能与您调用的DebugHlp.dll版本不兼容。请参见:

我在MSDN上发布了一个问题,有人友好地向我提供了问题的答案。下面是讨论的要点,以及我在下面复制的工作代码片段

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

你好。不,这是另一个问题。我之前的问题涉及句柄信息的编写。我在这里描述的问题是,MinidumpWriteDomainp在大多数已处理的应用程序中都无法写入任何内容。我有一个很小的测试应用程序,它拒绝创建任何类型的转储(创建0字节大小的文件)。如果我将调试器应用程序连接到我们的一个更大的应用程序,它会写一个转储。嗨,上面的事情对我不起作用。问题是我有我的微型转储从一个单独的进程编写。您的是进程外崩溃处理程序吗?还是在进行中?你能澄清一下吗?@AnanthaSubramaniam很抱歉我在6年前发布了这篇文章。我真的不记得了。我本以为我会把它放在一个单独的“看门狗”线程上,以跟踪我的主应用程序线程——这一定是一个全局线程。
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 );
}