dbghelp: Allow CPU backends to add specific information into a minidump.

Use it to add a 256 byte block around current program counter.
This commit is contained in:
Eric Pouech 2012-01-23 21:37:10 +01:00 committed by Alexandre Julliard
parent d02295d998
commit 1c5450f91f
7 changed files with 115 additions and 63 deletions

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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;

View File

@ -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 dependent 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));