[PATCH 4/5] [DbgHelp]: allow each CPU backend to save CPU specific memory ranges in minidump
Eric Pouech
eric.pouech at orange.fr
Mon Jan 23 14:37:16 CST 2012
Used this feature to add x86_64 unwind information.
A+
---
dlls/dbghelp/cpu_arm.c | 7 ++++++
dlls/dbghelp/cpu_i386.c | 9 +++++++
dlls/dbghelp/cpu_ppc.c | 7 ++++++
dlls/dbghelp/cpu_sparc.c | 7 ++++++
dlls/dbghelp/cpu_x86_64.c | 49 ++++++++++++++++++++++++++++++++++++++--
dlls/dbghelp/dbghelp_private.h | 1 +
dlls/dbghelp/minidump.c | 3 ++
7 files changed, 81 insertions(+), 2 deletions(-)
diff --git a/dlls/dbghelp/cpu_arm.c b/dlls/dbghelp/cpu_arm.c
index 025955e..2712db4 100644
--- a/dlls/dbghelp/cpu_arm.c
+++ b/dlls/dbghelp/cpu_arm.c
@@ -228,6 +228,12 @@ static BOOL arm_fetch_minidump_thread(struct dump_context* dc, unsigned index, u
return FALSE;
}
+static BOOL arm_fetch_minidump_module(struct dump_context* dc, unsigned index, unsigned flags)
+{
+ FIXME("NIY\n");
+ return FALSE;
+}
+
DECLSPEC_HIDDEN struct cpu cpu_arm = {
IMAGE_FILE_MACHINE_ARMV7,
4,
@@ -239,4 +245,5 @@ DECLSPEC_HIDDEN struct cpu cpu_arm = {
arm_fetch_context_reg,
arm_fetch_regname,
arm_fetch_minidump_thread,
+ arm_fetch_minidump_module,
};
diff --git a/dlls/dbghelp/cpu_i386.c b/dlls/dbghelp/cpu_i386.c
index b51d3fc..3a66def 100644
--- a/dlls/dbghelp/cpu_i386.c
+++ b/dlls/dbghelp/cpu_i386.c
@@ -673,6 +673,14 @@ static BOOL i386_fetch_minidump_thread(struct dump_context* dc, unsigned index,
return TRUE;
}
+static BOOL i386_fetch_minidump_module(struct dump_context* dc, unsigned index, unsigned flags)
+{
+ /* FIXME: actually, we should probably take care of FPO data, unless it's stored in
+ * function table minidump stream
+ */
+ return FALSE;
+}
+
DECLSPEC_HIDDEN struct cpu cpu_i386 = {
IMAGE_FILE_MACHINE_I386,
4,
@@ -684,4 +692,5 @@ DECLSPEC_HIDDEN struct cpu cpu_i386 = {
i386_fetch_context_reg,
i386_fetch_regname,
i386_fetch_minidump_thread,
+ i386_fetch_minidump_module,
};
diff --git a/dlls/dbghelp/cpu_ppc.c b/dlls/dbghelp/cpu_ppc.c
index b142e4a..56571c5 100644
--- a/dlls/dbghelp/cpu_ppc.c
+++ b/dlls/dbghelp/cpu_ppc.c
@@ -78,6 +78,12 @@ static BOOL ppc_fetch_minidump_thread(struct dump_context* dc, unsigned index, u
return FALSE;
}
+static BOOL ppc_fetch_minidump_module(struct dump_context* dc, unsigned index, unsigned flags)
+{
+ FIXME("NIY\n");
+ return FALSE;
+}
+
DECLSPEC_HIDDEN struct cpu cpu_ppc = {
IMAGE_FILE_MACHINE_POWERPC,
4,
@@ -89,4 +95,5 @@ DECLSPEC_HIDDEN struct cpu cpu_ppc = {
ppc_fetch_context_reg,
ppc_fetch_regname,
ppc_fetch_minidump_thread,
+ ppc_fetch_minidump_module,
};
diff --git a/dlls/dbghelp/cpu_sparc.c b/dlls/dbghelp/cpu_sparc.c
index bae1c22..7f5bfaa 100644
--- a/dlls/dbghelp/cpu_sparc.c
+++ b/dlls/dbghelp/cpu_sparc.c
@@ -85,6 +85,12 @@ static BOOL sparc_fetch_minidump_thread(struct dump_context* dc, unsigned index,
return FALSE;
}
+static BOOL sparc_fetch_minidump_module(struct dump_context* dc, unsigned index, unsigned flags)
+{
+ FIXME("NIY\n");
+ return FALSE;
+}
+
DECLSPEC_HIDDEN struct cpu cpu_sparc = {
IMAGE_FILE_MACHINE_SPARC,
4,
@@ -96,4 +102,5 @@ DECLSPEC_HIDDEN struct cpu cpu_sparc = {
sparc_fetch_context_reg,
sparc_fetch_regname,
sparc_fetch_minidump_thread,
+ sparc_fetch_minidump_module,
};
diff --git a/dlls/dbghelp/cpu_x86_64.c b/dlls/dbghelp/cpu_x86_64.c
index 695588e..8de28ef 100644
--- a/dlls/dbghelp/cpu_x86_64.c
+++ b/dlls/dbghelp/cpu_x86_64.c
@@ -145,7 +145,7 @@ static void dump_unwind_info(struct cpu_stack_walk* csw, ULONG64 base, RUNTIME_F
{
if (!sw_read_mem(csw, base + function->UnwindData, &snext, sizeof(snext)))
{
- TRACE("Couldn't unwind RUNTIME_INFO\n");
+ TRACE("Couldn't unwind RUNTIME_INFO at %lx\n", base + function->UnwindData);
return;
}
TRACE("unwind info for function %p-%p chained to function %p-%p\n",
@@ -159,7 +159,7 @@ static void dump_unwind_info(struct cpu_stack_walk* csw, ULONG64 base, RUNTIME_F
!sw_read_mem(csw, addr + FIELD_OFFSET(UNWIND_INFO, UnwindCode),
info->UnwindCode, info->CountOfCodes * sizeof(UNWIND_CODE)))
{
- FIXME("couldn't read memory for UNWIND_INFO\n");
+ FIXME("couldn't read memory for UNWIND_INFO at %lx\n", addr);
return;
}
TRACE("unwind info at %p flags %x prolog 0x%x bytes function %p-%p\n",
@@ -904,6 +904,50 @@ static BOOL x86_64_fetch_minidump_thread(struct dump_context* dc, unsigned index
return TRUE;
}
+static BOOL x86_64_fetch_minidump_module(struct dump_context* dc, unsigned index, unsigned flags)
+{
+ /* FIXME: not sure about the flags... */
+ if (1)
+ {
+ /* FIXME: crop values across module boundaries, */
+#ifdef __x86_64__
+ struct process* pcs;
+ struct module* module;
+ const RUNTIME_FUNCTION* rtf;
+ ULONG size;
+
+ if (!(pcs = process_find_by_handle(dc->hProcess)) ||
+ !(module = module_find_by_addr(pcs, dc->modules[index].base, DMT_UNKNOWN)))
+ return FALSE;
+ rtf = (const RUNTIME_FUNCTION*)pe_map_directory(module, IMAGE_DIRECTORY_ENTRY_EXCEPTION, &size);
+ if (rtf)
+ {
+ const RUNTIME_FUNCTION* end = (const RUNTIME_FUNCTION*)((const char*)rtf + size);
+ UNWIND_INFO ui;
+
+ while (rtf + 1 < end)
+ {
+ while (rtf->UnwindData & 1) /* follow chained entry */
+ {
+ FIXME("RunTime_Function outside IMAGE_DIRECTORY_ENTRY_EXCEPTION unimplemented yet!\n");
+ return FALSE;
+ /* we need to read into the other process */
+ /* rtf = (RUNTIME_FUNCTION*)(module->module.BaseOfImage + (rtf->UnwindData & ~1)); */
+ }
+ if (ReadProcessMemory(dc->hProcess,
+ (void*)(dc->modules[index].base + rtf->UnwindData),
+ &ui, sizeof(ui), NULL))
+ minidump_add_memory_block(dc, dc->modules[index].base + rtf->UnwindData,
+ FIELD_OFFSET(UNWIND_INFO, UnwindCode) + ui.CountOfCodes * sizeof(UNWIND_CODE), 0);
+ rtf++;
+ }
+ }
+#endif
+ }
+
+ return TRUE;
+}
+
DECLSPEC_HIDDEN struct cpu cpu_x86_64 = {
IMAGE_FILE_MACHINE_AMD64,
8,
@@ -915,4 +959,5 @@ DECLSPEC_HIDDEN struct cpu cpu_x86_64 = {
x86_64_fetch_context_reg,
x86_64_fetch_regname,
x86_64_fetch_minidump_thread,
+ x86_64_fetch_minidump_module,
};
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index 3bee416..f18a0fe 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -538,6 +538,7 @@ struct cpu
/* minidump per CPU extension */
BOOL (*fetch_minidump_thread)(struct dump_context* dc, unsigned index, unsigned flags, const CONTEXT* ctx);
+ BOOL (*fetch_minidump_module)(struct dump_context* dc, unsigned index, unsigned flags);
};
extern struct cpu* dbghelp_current_cpu DECLSPEC_HIDDEN;
diff --git a/dlls/dbghelp/minidump.c b/dlls/dbghelp/minidump.c
index 283fa2a..5ad0a7b 100644
--- a/dlls/dbghelp/minidump.c
+++ b/dlls/dbghelp/minidump.c
@@ -513,6 +513,9 @@ static unsigned dump_modules(struct dump_context* dc, BOOL dump_elf)
}
if (flags_out & ModuleWriteModule)
{
+ /* fetch CPU dependant module info (like UNWIND_INFO) */
+ dbghelp_current_cpu->fetch_minidump_module(dc, i, flags_out);
+
mdModule.BaseOfImage = dc->modules[i].base;
mdModule.SizeOfImage = dc->modules[i].size;
mdModule.CheckSum = dc->modules[i].checksum;
More information about the wine-patches
mailing list