【问题标题】:Why is MiniDumpWriteDump failing?为什么 MiniDumpWriteDump 失败?
【发布时间】:2012-03-23 02:13:50
【问题描述】:

我创建了自己的调试器应用程序。它附加到一个进程并创建一个故障转储文件。这在大多数情况下都有效。我遇到的问题是,当被调试的应用程序正在等待互斥对象时它不起作用(这正是我要调试的问题)。

此外,我创建了一个简单的 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 );
    }
}

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

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

【问题讨论】:

    标签: debugging minidumpwritedump


    【解决方案1】:

    我在 MSDN 上发布了一个问题,有人好心地为我提供了问题的答案。这是讨论的link,以及我在下面复制的工作代码sn-p。

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

    【讨论】:

    • 嗨,上面的东西对我不起作用。问题是我的 MiniDump 是从一个单独的过程中编写的。你的是进程外崩溃处理程序吗?或进行中?你能澄清一下吗?
    • @AnanthaSubramaniam 抱歉,我在 6 年前发布了这篇文章。老实说,我不记得了。我原以为我会把它放在一个单独的“看门狗”线程上来跟踪我的主应用程序线程——这一定是一个全局的。
    【解决方案2】:

    这个问题和我用这个文字回答的另一个question是同一个问题吗?

    即使带有标志 MiniDumpWithHandleData,它是否不包含互斥锁信息,也可能失败,因为某些标志可能与您调用的 DebugHlp.dll 版本不兼容,请参阅:here

    【讨论】:

    • 你好。不,这是一个不同的问题。我之前的问题是关于句柄信​​息的编写。我在这里描述的问题是 MiniDumpWriteDump 无法为大多数处理写入任何内容。我有一个很小的测试应用程序,它拒绝创建任何类型的转储(创建大小为 0 字节的文件)。如果我将调试器应用程序附加到我们更大的应用程序之一,它确实会写一个转储。
    猜你喜欢
    • 2011-05-16
    • 2015-06-19
    • 2014-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多