[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