From fa9be995687605903bf6617976af39b35647538e Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Mon, 19 Feb 2007 23:09:24 +0100 Subject: [PATCH] dbghelp: MiniDumpWriteDump called from exception handler. - 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. --- dlls/dbghelp/minidump.c | 97 ++++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 36 deletions(-) diff --git a/dlls/dbghelp/minidump.c b/dlls/dbghelp/minidump.c index c1b44b0b082..a8e2ee08761 100644 --- a/dlls/dbghelp/minidump.c +++ b/dlls/dbghelp/minidump.c @@ -112,15 +112,45 @@ static BOOL fetch_process_info(struct dump_context* dc) 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 dump_context* dc, int thd_idx, &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 (ReadProcessMemory(dc->hProcess, tbi.TebBaseAddress, - &tib, sizeof(tib), NULL)) + if (tid != GetCurrentThreadId() && + (mdThd->SuspendCount = SuspendThread(hThread)) != (DWORD)-1) { -#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; + mdThd->SuspendCount--; + ctx->ContextFlags = CONTEXT_FULL; + if (!GetThreadContext(hThread, ctx)) + memset(ctx, 0, sizeof(*ctx)); + + fetch_thread_stack(dc, tbi.TebBaseAddress, ctx, &mdThd->Stack); + ResumeThread(hThread); + } + else if (tid == GetCurrentThreadId() && except) + { + 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(struct dump_context* dc, ep.ContextRecord, &ctx, sizeof(ctx), NULL); prec = &rec; pctx = &ctx; - } else { @@ -516,7 +540,8 @@ static void dump_system_info(struct dump_context* dc) * * 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_context* dc) 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 hProcess, DWORD pid, HANDLE hFile, 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));