[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