[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