[PATCH 3/5] [DbgHelp]: now allowing CPU backends to add specific information into a minidump

Eric Pouech eric.pouech at orange.fr
Mon Jan 23 14:37:10 CST 2012


and use it to add a 256 byte block around current program counter

A+
---

 dlls/dbghelp/cpu_arm.c         |    7 ++++
 dlls/dbghelp/cpu_i386.c        |   15 ++++++++
 dlls/dbghelp/cpu_ppc.c         |    7 ++++
 dlls/dbghelp/cpu_sparc.c       |    7 ++++
 dlls/dbghelp/cpu_x86_64.c      |   15 ++++++++
 dlls/dbghelp/dbghelp_private.h |   55 +++++++++++++++++++++++++++++++
 dlls/dbghelp/minidump.c        |   72 +++++-----------------------------------
 7 files changed, 115 insertions(+), 63 deletions(-)


diff --git a/dlls/dbghelp/cpu_arm.c b/dlls/dbghelp/cpu_arm.c
index 413a492..025955e 100644
--- a/dlls/dbghelp/cpu_arm.c
+++ b/dlls/dbghelp/cpu_arm.c
@@ -222,6 +222,12 @@ static const char* arm_fetch_regname(unsigned regno)
     return NULL;
 }
 
+static BOOL arm_fetch_minidump_thread(struct dump_context* dc, unsigned index, unsigned flags, const CONTEXT* ctx)
+{
+    FIXME("NIY\n");
+    return FALSE;
+}
+
 DECLSPEC_HIDDEN struct cpu cpu_arm = {
     IMAGE_FILE_MACHINE_ARMV7,
     4,
@@ -232,4 +238,5 @@ DECLSPEC_HIDDEN struct cpu cpu_arm = {
     arm_map_dwarf_register,
     arm_fetch_context_reg,
     arm_fetch_regname,
+    arm_fetch_minidump_thread,
 };
diff --git a/dlls/dbghelp/cpu_i386.c b/dlls/dbghelp/cpu_i386.c
index e604e10..b51d3fc 100644
--- a/dlls/dbghelp/cpu_i386.c
+++ b/dlls/dbghelp/cpu_i386.c
@@ -659,6 +659,20 @@ static const char* i386_fetch_regname(unsigned regno)
     return NULL;
 }
 
+static BOOL i386_fetch_minidump_thread(struct dump_context* dc, unsigned index, unsigned flags, const CONTEXT* ctx)
+{
+    if (ctx->ContextFlags && (flags & ThreadWriteInstructionWindow))
+    {
+        /* FIXME: crop values across module boundaries, */
+#ifdef __i386__
+        ULONG base = ctx->Eip <= 0x80 ? 0 : ctx->Eip - 0x80;
+        minidump_add_memory_block(dc, base, ctx->Eip + 0x80 - base, 0);
+#endif
+    }
+
+    return TRUE;
+}
+
 DECLSPEC_HIDDEN struct cpu cpu_i386 = {
     IMAGE_FILE_MACHINE_I386,
     4,
@@ -669,4 +683,5 @@ DECLSPEC_HIDDEN struct cpu cpu_i386 = {
     i386_map_dwarf_register,
     i386_fetch_context_reg,
     i386_fetch_regname,
+    i386_fetch_minidump_thread,
 };
diff --git a/dlls/dbghelp/cpu_ppc.c b/dlls/dbghelp/cpu_ppc.c
index 4db9b89..b142e4a 100644
--- a/dlls/dbghelp/cpu_ppc.c
+++ b/dlls/dbghelp/cpu_ppc.c
@@ -72,6 +72,12 @@ static const char* ppc_fetch_regname(unsigned regno)
     return NULL;
 }
 
+static BOOL ppc_fetch_minidump_thread(struct dump_context* dc, unsigned index, unsigned flags, const CONTEXT* ctx)
+{
+    FIXME("NIY\n");
+    return FALSE;
+}
+
 DECLSPEC_HIDDEN struct cpu cpu_ppc = {
     IMAGE_FILE_MACHINE_POWERPC,
     4,
@@ -82,4 +88,5 @@ DECLSPEC_HIDDEN struct cpu cpu_ppc = {
     ppc_map_dwarf_register,
     ppc_fetch_context_reg,
     ppc_fetch_regname,
+    ppc_fetch_minidump_thread,
 };
diff --git a/dlls/dbghelp/cpu_sparc.c b/dlls/dbghelp/cpu_sparc.c
index 7ad4640..bae1c22 100644
--- a/dlls/dbghelp/cpu_sparc.c
+++ b/dlls/dbghelp/cpu_sparc.c
@@ -79,6 +79,12 @@ static const char* sparc_fetch_regname(unsigned regno)
     return NULL;
 }
 
+static BOOL sparc_fetch_minidump_thread(struct dump_context* dc, unsigned index, unsigned flags, const CONTEXT* ctx)
+{
+    FIXME("NIY\n");
+    return FALSE;
+}
+
 DECLSPEC_HIDDEN struct cpu cpu_sparc = {
     IMAGE_FILE_MACHINE_SPARC,
     4,
@@ -89,4 +95,5 @@ DECLSPEC_HIDDEN struct cpu cpu_sparc = {
     sparc_map_dwarf_register,
     sparc_fetch_context_reg,
     sparc_fetch_regname,
+    sparc_fetch_minidump_thread,
 };
diff --git a/dlls/dbghelp/cpu_x86_64.c b/dlls/dbghelp/cpu_x86_64.c
index 8b101d2..695588e 100644
--- a/dlls/dbghelp/cpu_x86_64.c
+++ b/dlls/dbghelp/cpu_x86_64.c
@@ -890,6 +890,20 @@ static const char* x86_64_fetch_regname(unsigned regno)
     return NULL;
 }
 
+static BOOL x86_64_fetch_minidump_thread(struct dump_context* dc, unsigned index, unsigned flags, const CONTEXT* ctx)
+{
+    if (ctx->ContextFlags && (flags & ThreadWriteInstructionWindow))
+    {
+        /* FIXME: crop values across module boundaries, */
+#ifdef __x86_64__
+        ULONG64 base = ctx->Rip <= 0x80 ? 0 : ctx->Rip - 0x80;
+        minidump_add_memory_block(dc, base, ctx->Rip + 0x80 - base, 0);
+#endif
+    }
+
+    return TRUE;
+}
+
 DECLSPEC_HIDDEN struct cpu cpu_x86_64 = {
     IMAGE_FILE_MACHINE_AMD64,
     8,
@@ -900,4 +914,5 @@ DECLSPEC_HIDDEN struct cpu cpu_x86_64 = {
     x86_64_map_dwarf_register,
     x86_64_fetch_context_reg,
     x86_64_fetch_regname,
+    x86_64_fetch_minidump_thread,
 };
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index 57c3374..3bee416 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -463,6 +463,55 @@ struct cpu_stack_walk
     } u;
 };
 
+struct dump_memory
+{
+    ULONG64                             base;
+    ULONG                               size;
+    ULONG                               rva;
+};
+
+struct dump_module
+{
+    unsigned                            is_elf;
+    ULONG64                             base;
+    ULONG                               size;
+    DWORD                               timestamp;
+    DWORD                               checksum;
+    WCHAR                               name[MAX_PATH];
+};
+
+struct dump_thread
+{
+    ULONG                               tid;
+    ULONG                               prio_class;
+    ULONG                               curr_prio;
+};
+
+struct dump_context
+{
+    /* process & thread information */
+    HANDLE                              hProcess;
+    DWORD                               pid;
+    unsigned                            flags_out;
+    /* thread information */
+    struct dump_thread*                 threads;
+    unsigned                            num_threads;
+    /* module information */
+    struct dump_module*                 modules;
+    unsigned                            num_modules;
+    unsigned                            alloc_modules;
+    /* exception information */
+    /* output information */
+    MINIDUMP_TYPE                       type;
+    HANDLE                              hFile;
+    RVA                                 rva;
+    struct dump_memory*                 mem;
+    unsigned                            num_mem;
+    unsigned                            alloc_mem;
+    /* callback information */
+    MINIDUMP_CALLBACK_INFORMATION*      cb;
+};
+
 enum cpu_addr {cpu_addr_pc, cpu_addr_stack, cpu_addr_frame};
 struct cpu
 {
@@ -486,6 +535,9 @@ struct cpu
     /* context related manipulation */
     void*       (*fetch_context_reg)(CONTEXT* context, unsigned regno, unsigned* size);
     const char* (*fetch_regname)(unsigned regno);
+
+    /* minidump per CPU extension */
+    BOOL        (*fetch_minidump_thread)(struct dump_context* dc, unsigned index, unsigned flags, const CONTEXT* ctx);
 };
 
 extern struct cpu*      dbghelp_current_cpu DECLSPEC_HIDDEN;
@@ -527,6 +579,9 @@ extern struct module*
 extern BOOL         macho_read_wine_loader_dbg_info(struct process* pcs) DECLSPEC_HIDDEN;
 extern BOOL         macho_synchronize_module_list(struct process* pcs) DECLSPEC_HIDDEN;
 
+/* minidump.c */
+void minidump_add_memory_block(struct dump_context* dc, ULONG64 base, ULONG size, ULONG rva);
+
 /* module.c */
 extern const WCHAR      S_ElfW[] DECLSPEC_HIDDEN;
 extern const WCHAR      S_WineLoaderW[] DECLSPEC_HIDDEN;
diff --git a/dlls/dbghelp/minidump.c b/dlls/dbghelp/minidump.c
index 757e21d..283fa2a 100644
--- a/dlls/dbghelp/minidump.c
+++ b/dlls/dbghelp/minidump.c
@@ -32,54 +32,6 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
 
-struct dump_memory
-{
-    ULONG64                             base;
-    ULONG                               size;
-    ULONG                               rva;
-};
-
-struct dump_module
-{
-    unsigned                            is_elf;
-    ULONG64                             base;
-    ULONG                               size;
-    DWORD                               timestamp;
-    DWORD                               checksum;
-    WCHAR                               name[MAX_PATH];
-};
-
-struct dump_thread
-{
-    ULONG                               tid;
-    ULONG                               prio_class;
-    ULONG                               curr_prio;
-};
-
-struct dump_context
-{
-    /* process & thread information */
-    HANDLE                              hProcess;
-    DWORD                               pid;
-    /* thread information */
-    struct dump_thread*                 threads;
-    unsigned                            num_threads;
-    /* module information */
-    struct dump_module*                 modules;
-    unsigned                            num_modules;
-    unsigned                            alloc_modules;
-    /* exception information */
-    /* output information */
-    MINIDUMP_TYPE                       type;
-    HANDLE                              hFile;
-    RVA                                 rva;
-    struct dump_memory*                 mem;
-    unsigned                            num_mem;
-    unsigned                            alloc_mem;
-    /* callback information */
-    MINIDUMP_CALLBACK_INFORMATION*      cb;
-};
-
 /******************************************************************
  *		fetch_process_info
  *
@@ -376,14 +328,14 @@ static void fetch_module_versioninfo(LPCWSTR filename, VS_FIXEDFILEINFO* ffi)
 }
 
 /******************************************************************
- *		add_memory_block
+ *		minidump_add_memory_block
  *
  * Add a memory block to be dumped in a minidump
  * If rva is non 0, it's the rva in the minidump where has to be stored
  * also the rva of the memory block when written (this allows to reference
  * a memory block from outside the list of memory blocks).
  */
-static void add_memory_block(struct dump_context* dc, ULONG64 base, ULONG size, ULONG rva)
+void minidump_add_memory_block(struct dump_context* dc, ULONG64 base, ULONG size, ULONG rva)
 {
     if (!dc->mem)
     {
@@ -806,11 +758,11 @@ static  unsigned        dump_threads(struct dump_context* dc,
             }
             if (mdThd.Stack.Memory.DataSize && (flags_out & ThreadWriteStack))
             {
-                add_memory_block(dc, mdThd.Stack.StartOfMemoryRange,
-                                 mdThd.Stack.Memory.DataSize,
-                                 rva_base + sizeof(mdThdList.NumberOfThreads) +
-                                     mdThdList.NumberOfThreads * sizeof(mdThd) +
-                                     FIELD_OFFSET(MINIDUMP_THREAD, Stack.Memory.Rva));
+                minidump_add_memory_block(dc, mdThd.Stack.StartOfMemoryRange,
+                                          mdThd.Stack.Memory.DataSize,
+                                          rva_base + sizeof(mdThdList.NumberOfThreads) +
+                                          mdThdList.NumberOfThreads * sizeof(mdThd) +
+                                          FIELD_OFFSET(MINIDUMP_THREAD, Stack.Memory.Rva));
             }
             writeat(dc, 
                     rva_base + sizeof(mdThdList.NumberOfThreads) +
@@ -818,14 +770,8 @@ static  unsigned        dump_threads(struct dump_context* dc,
                     &mdThd, sizeof(mdThd));
             mdThdList.NumberOfThreads++;
         }
-        if (ctx.ContextFlags && (flags_out & ThreadWriteInstructionWindow))
-        {
-            /* FIXME: - Native dbghelp also dumps 0x80 bytes around EIP
-             *        - also crop values across module boundaries, 
-             *        - and don't make it i386 dependent 
-             */
-            /* add_memory_block(dc, ctx.Eip - 0x80, ctx.Eip + 0x80, 0); */
-        }
+        /* fetch CPU dependant thread info (like 256 bytes around program counter */
+        dbghelp_current_cpu->fetch_minidump_thread(dc, i, flags_out, &ctx);
     }
     writeat(dc, rva_base,
             &mdThdList.NumberOfThreads, sizeof(mdThdList.NumberOfThreads));




More information about the wine-patches mailing list