[PATCH] [DbgHelp]: MiniDumpWriteDump called from exception handler (#7426)

Eric Pouech eric.pouech at wanadoo.fr
Mon Feb 19 16:09:24 CST 2007


- MiniDumpWriteDump was unable to provide stack information for the current
  thread, hence did produce unusable minidump when a programs generates the
  minidump from its own exception handler.
- We now support this if the current thread calls MiniDumpWriteDump from an
  exception handler and provides the exception information.

A+
---

 dlls/dbghelp/minidump.c |   95 ++++++++++++++++++++++++++++++-----------------
 1 files changed, 60 insertions(+), 35 deletions(-)

diff --git a/dlls/dbghelp/minidump.c b/dlls/dbghelp/minidump.c
index c1b44b0..a8e2ee0 100644
--- a/dlls/dbghelp/minidump.c
+++ b/dlls/dbghelp/minidump.c
@@ -112,15 +112,45 @@ static BOOL fetch_process_info(struct du
     return FALSE;
 }
 
+static void fetch_thread_stack(struct dump_context* dc, void* teb_addr,
+                               const CONTEXT* ctx, MINIDUMP_MEMORY_DESCRIPTOR* mmd)
+{
+    NT_TIB      tib;
+
+    if (ReadProcessMemory(dc->hProcess, teb_addr, &tib, sizeof(tib), NULL))
+    {
+#ifdef __i386__
+        /* limiting the stack dumping to the size actually used */
+        if (ctx->Esp)
+            mmd->StartOfMemoryRange = (ctx->Esp - 4);
+        else
+            mmd->StartOfMemoryRange = (ULONG_PTR)tib.StackLimit;
+#elif defined(__powerpc__)
+        if (ctx->Iar)
+            mmd->StartOfMemoryRange = ctx->Iar - 4;
+        else
+            mmd->StartOfMemoryRange = (ULONG_PTR)tib.StackLimit;
+#elif defined(__x86_64__)
+        if (ctx->Rsp)
+            mmd->StartOfMemoryRange = (ctx->Rsp - 8);
+        else
+            mmd->StartOfMemoryRange = (ULONG_PTR)tib.StackLimit;
+#else
+#error unsupported CPU
+#endif
+        mmd->Memory.DataSize = (ULONG_PTR)tib.StackBase - mmd->StartOfMemoryRange;
+    }
+}
+
 /******************************************************************
  *		fetch_thread_info
  *
  * fetches some information about thread of id 'tid'
  */
 static BOOL fetch_thread_info(struct dump_context* dc, int thd_idx,
+                              const MINIDUMP_EXCEPTION_INFORMATION* except,
                               MINIDUMP_THREAD* mdThd, CONTEXT* ctx)
 {
-    NT_TIB                      tib;
     DWORD                       tid = dc->spi->ti[thd_idx].dwThreadID;
     HANDLE                      hThread;
     THREAD_BASIC_INFORMATION    tbi;
@@ -149,40 +179,35 @@ static BOOL fetch_thread_info(struct dum
                                  &tbi, sizeof(tbi), NULL) == STATUS_SUCCESS)
     {
         mdThd->Teb = (ULONG_PTR)tbi.TebBaseAddress;
-        if (tbi.ExitStatus == STILL_ACTIVE && tid != GetCurrentThreadId() &&
-            (mdThd->SuspendCount = SuspendThread(hThread)) != (DWORD)-1)
+        if (tbi.ExitStatus == STILL_ACTIVE)
         {
-            mdThd->SuspendCount--;
-            ctx->ContextFlags = CONTEXT_FULL;
-            if (!GetThreadContext(hThread, ctx))
-                memset(ctx, 0, sizeof(*ctx));
+            if (tid != GetCurrentThreadId() &&
+                (mdThd->SuspendCount = SuspendThread(hThread)) != (DWORD)-1)
+            {
+                mdThd->SuspendCount--;
+                ctx->ContextFlags = CONTEXT_FULL;
+                if (!GetThreadContext(hThread, ctx))
+                    memset(ctx, 0, sizeof(*ctx));
 
-            if (ReadProcessMemory(dc->hProcess, tbi.TebBaseAddress, 
-                                  &tib, sizeof(tib), NULL))
+                fetch_thread_stack(dc, tbi.TebBaseAddress, ctx, &mdThd->Stack);
+                ResumeThread(hThread);
+            }
+            else if (tid == GetCurrentThreadId() && except)
             {
-#ifdef __i386__
-                /* limiting the stack dumping to the size actually used */
-                if (ctx->Esp)
-                    mdThd->Stack.StartOfMemoryRange = (ctx->Esp - 4);
-                else
-                    mdThd->Stack.StartOfMemoryRange = (ULONG_PTR)tib.StackLimit;
-#elif defined(__powerpc__)
-                if (ctx->Iar)
-                    mdThd->Stack.StartOfMemoryRange = ctx->Iar - 4;
-                else
-                    mdThd->Stack.StartOfMemoryRange = (ULONG_PTR)tib.StackLimit;
-#elif defined(__x86_64__)
-                if (ctx->Rsp)
-                    mdThd->Stack.StartOfMemoryRange = (ctx->Rsp - 8);
-                else
-                    mdThd->Stack.StartOfMemoryRange = (ULONG_PTR)tib.StackLimit;
-#else
-#error unsupported CPU
-#endif
-                mdThd->Stack.Memory.DataSize = (ULONG_PTR)tib.StackBase -
-                    mdThd->Stack.StartOfMemoryRange;
+                CONTEXT lctx, *pctx;
+                if (except->ClientPointers)
+                {
+                    EXCEPTION_POINTERS      ep;
+
+                    ReadProcessMemory(dc->hProcess, except->ExceptionPointers,
+                                      &ep, sizeof(ep), NULL);
+                    ReadProcessMemory(dc->hProcess, ep.ContextRecord,
+                                      &ctx, sizeof(ctx), NULL);
+                    pctx = &lctx;
+                }
+                else pctx = except->ExceptionPointers->ContextRecord;
+                fetch_thread_stack(dc, tbi.TebBaseAddress, pctx, &mdThd->Stack);
             }
-            ResumeThread(hThread);
         }
     }
     CloseHandle(hThread);
@@ -347,7 +372,6 @@ static  void    dump_exception_info(stru
                           ep.ContextRecord, &ctx, sizeof(ctx), NULL);
         prec = &rec;
         pctx = &ctx;
-        
     }
     else
     {
@@ -516,7 +540,8 @@ static  void    dump_system_info(struct 
  *
  * Dumps into File the information about running threads
  */
-static  void    dump_threads(struct dump_context* dc)
+static  void    dump_threads(struct dump_context* dc,
+                             const MINIDUMP_EXCEPTION_INFORMATION* except)
 {
     MINIDUMP_THREAD             mdThd;
     MINIDUMP_THREAD_LIST        mdThdList;
@@ -533,7 +558,7 @@ static  void    dump_threads(struct dump
 
     for (i = 0; i < dc->spi->dwThreadCount; i++)
     {
-        fetch_thread_info(dc, i, &mdThd, &ctx);
+        fetch_thread_info(dc, i, except, &mdThd, &ctx);
 
         flags_out = ThreadWriteThread | ThreadWriteStack | ThreadWriteContext |
             ThreadWriteInstructionWindow;
@@ -713,7 +738,7 @@ BOOL WINAPI MiniDumpWriteDump(HANDLE hPr
 
     mdDir.StreamType = ThreadListStream;
     mdDir.Location.Rva = dc.rva;
-    dump_threads(&dc);
+    dump_threads(&dc, ExceptionParam);
     mdDir.Location.DataSize = dc.rva - mdDir.Location.Rva;
     writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir), 
             &mdDir, sizeof(mdDir));




More information about the wine-patches mailing list