为什么Minidump文件内容只有1个进程错误?

时间:2018-05-22 10:33:15

标签: winapi mfc

情况: 我们有一个MFC / C ++ Visual Studio(2005)应用程序,包含许多可执行文件和许多dll,都使用MFC并与DCOM互连。有些正在控制器(w2012)上运行,该控制器控制在WES2009上运行的从属计算机。

问题: 出于诊断目的,我们将minidump嵌入到我们的所有流程中。这个机制在所有进程中都可以正常工作,除了一个:GUI exe。所有进程(包括GUI)使dmp文件 BUT GUI的dmp文件内容似乎不同/错误。当我故意使用例如我们的应用程序崩溃时空指针取消引用,所有进程/ dll(GUI除外)的所有dmp文件都指向原因(空指针取消引用)! GUI进程的dmp文件已创建,可在Visual Studio中打开,但非线程指向原因(空指针取消引用)。 windbg也找不到原因!奇怪的是,当我们手动使用WriteStackDetails()来转储callstack时,它会返回正确的有问题的行!那么为什么MinidumpWriteDump()只能为这一个进程做同样的事情呢?什么可能是歧视因素?任何人都有任何想法?

我们尝试了什么: 我们尝试在所有其他进程和dll中崩溃,除了GUI进程外,它们似乎都运行正常! Unicode /非Unicode似乎并不重要。当我链接包含UnhandledExceptionFilter()和MinidumpWriteDump()的生产代码库时,单独的测试应用程序也能很好地工作。 sub(-sub)dll中的崩溃似乎并不重要。异常处理的项目设置似乎完全相同。任何人都有任何想法?

更多信息和备注:

  1. 我们的生产代码(控制器和从属设备)在不同的虚拟框中运行以进行开发。

  2. 是的,我们理解minidump理想情况下应该是从另一个进程创建的(某个例子在哪里?wrt进程查询和安全性?)但是在进程中执行它似乎工作总是好的'目前。因此,我们现在接受在极少数情况下可能会挂起的风险。

  3. 我的意思是dmp文件内容不同/错误如下: 对于我们的非GUI exe,我们得到以下OK线程/ callstack信息: 0xC0000005:访问冲突读取位置0x00000000。 Studio会自动打开正确的源和"断点"设置为错误的代码行。 在Call stack选项卡中,我在自己的dll中看到了我自己的函数,它导致了崩溃:我的空指针取消引用。 在Threads选项卡中,我还看到了我的活动线程和Location,它还指向崩溃的错误功能。 所以在这种情况下一切都很好用!超级方便的功能!

  4. 对于我们的GUI exe,它链接到相同的生产库代码wrt MinidumpWriteDump()和ExceptionHandlingFiler()代码,我们得到以下NOK线程/ callstack信息: our_exe_pid_2816_tid_2820_crash.dmp中0x77d66e29(ntdll.dll)的未处理异常:0xC0150010:当前执行的线程未激活的激活上下文无效 Visual Studio 2005没有显示我的错误代码是原因! 在Call stack选项卡中,我没有看到自己的错误功能。 “调用堆栈”选项卡显示问题出在ntdll.dll中!RtlDeactivateActivationContextUnsafeFast() 我们代码中显示的最顶层函数调用是一个完全不同的gui helper dll,这与我故意引入的崩溃无关! “线程”选项卡也显示相同的内容。

    对于这两种情况,我使用相同的visual studio 2005(在w7上运行),并使用相同的符号路径设置!视觉工作室2017也无法分析错误' dmp文件。在上述两个测试之间,没有重建,因此exe / dlls和pdbs之间不会发生不匹配。在一种情况下,它工作正常,在另一种情况下没有!?!

    1. 我们使用的精简代码如下所示

      typedef BOOL (_stdcall *tMiniDumpWriteDump)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, 
                                              MINIDUMP_TYPE DumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
                                              CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
                                              CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
      

      TCHAR CCrashReporter :: s_szLogFileNameDmp [MAX_PATH]; CRITICAL_SECTION CCrashReporter :: s_csGuard; LPTOP_LEVEL_EXCEPTION_FILTER CCrashReporter :: s_previousFilter = 0; HMODULE CCrashReporter :: s_hDbgHelp = 0; tMiniDumpWriteDump CCr​​ashReporter :: s_fpMiniDumpWriteDump = 0;

      CCrashReporter :: CCrashReporter() {   LoadDBGHELP();

      s_previousFilter = :: SetUnhandledExceptionFilter(UnhandledExceptionFilter);   :: InitializeCriticalSection(安培; s_csGuard); }

      CCrashReporter ::〜CCrashReporter() {   :: SetUnhandledExceptionFilter(s_previousFilter);

      ...

      if(0!= s_hDbgHelp)   {     FreeLibrary则(s_hDbgHelp);   }

      :: DeleteCriticalSection(安培; s_csGuard); }

      LONG WINAPI CCrashReporter :: UnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo) {   :: EnterCriticalSection的(安培; s_csGuard);

      ...

      GenerateMinidump(pExceptionInfo,s_szLogFileNameDmp);   :: LeaveCriticalSection(安培; s_csGuard);   返回EXCEPTION_EXECUTE_HANDLER; }

      void CCrashReporter :: LoadDBGHELP() {   / * ...搜索dbghelp.dll代码... * /

      s_hDbgHelp = :: LoadLibrary(strDBGHELP_FILENAME);

      if(0 == s_hDbgHelp)   {     / * ...报告错误... * /   }

      if(0!= s_hDbgHelp)   {     ...

      s_fpMiniDumpWriteDump = (tMiniDumpWriteDump)GetProcAddress(s_hDbgHelp, "MiniDumpWriteDump");
      
      if (!s_fpMiniDumpWriteDump)
      {
        FreeLibrary(s_hDbgHelp);
      }
      else
      {
        /* ... log ok ... */
      }
      

      } }

      void CCrashReporter :: GenerateMinidump(const PEXCEPTION_POINTERS pExceptionInfo,                                       LPCTSTR pszLogFileNameDmp) {   HANDLE hReportFileDmp(:: CreateFile(pszLogFileNameDmp,GENERIC_WRITE,0,0,                                      CREATE_ALWAYS,FILE_FLAG_WRITE_THROUGH,0));

      if(INVALID_HANDLE_VALUE!= hReportFileDmp)   {     MINIDUMP_EXCEPTION_INFORMATION stMDEI;

      stMDEI.ThreadId = ::GetCurrentThreadId();
      stMDEI.ExceptionPointers = pExceptionInfo;
      stMDEI.ClientPointers = TRUE;
      
      if(!s_fpMiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(),
                                hReportFileDmp, MiniDumpWithIndirectlyReferencedMemory,
                                &stMDEI, 0, 0))
      {
        /* ... report error ...*/
      }
      else
      {
        /* ... report ok ... */
      }
      
      ::CloseHandle(hReportFileDmp);
      

      }   其他   {       / * ...报告错误... * /   } }

0 个答案:

没有答案