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.
This commit is contained in:
parent
93494f2ac0
commit
fa9be99568
|
@ -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,7 +179,9 @@ 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() &&
|
||||
if (tbi.ExitStatus == STILL_ACTIVE)
|
||||
{
|
||||
if (tid != GetCurrentThreadId() &&
|
||||
(mdThd->SuspendCount = SuspendThread(hThread)) != (DWORD)-1)
|
||||
{
|
||||
mdThd->SuspendCount--;
|
||||
|
@ -157,33 +189,26 @@ static BOOL fetch_thread_info(struct dump_context* dc, int thd_idx,
|
|||
if (!GetThreadContext(hThread, ctx))
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
if (ReadProcessMemory(dc->hProcess, tbi.TebBaseAddress,
|
||||
&tib, sizeof(tib), NULL))
|
||||
{
|
||||
#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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(hThread);
|
||||
return TRUE;
|
||||
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue