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:
parent
d02295d998
commit
1c5450f91f
@ -222,6 +222,12 @@ static const char* arm_fetch_regname(unsigned regno)
|
|||||||
return NULL;
|
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 = {
|
DECLSPEC_HIDDEN struct cpu cpu_arm = {
|
||||||
IMAGE_FILE_MACHINE_ARMV7,
|
IMAGE_FILE_MACHINE_ARMV7,
|
||||||
4,
|
4,
|
||||||
@ -232,4 +238,5 @@ DECLSPEC_HIDDEN struct cpu cpu_arm = {
|
|||||||
arm_map_dwarf_register,
|
arm_map_dwarf_register,
|
||||||
arm_fetch_context_reg,
|
arm_fetch_context_reg,
|
||||||
arm_fetch_regname,
|
arm_fetch_regname,
|
||||||
|
arm_fetch_minidump_thread,
|
||||||
};
|
};
|
||||||
|
@ -659,6 +659,20 @@ static const char* i386_fetch_regname(unsigned regno)
|
|||||||
return NULL;
|
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 = {
|
DECLSPEC_HIDDEN struct cpu cpu_i386 = {
|
||||||
IMAGE_FILE_MACHINE_I386,
|
IMAGE_FILE_MACHINE_I386,
|
||||||
4,
|
4,
|
||||||
@ -669,4 +683,5 @@ DECLSPEC_HIDDEN struct cpu cpu_i386 = {
|
|||||||
i386_map_dwarf_register,
|
i386_map_dwarf_register,
|
||||||
i386_fetch_context_reg,
|
i386_fetch_context_reg,
|
||||||
i386_fetch_regname,
|
i386_fetch_regname,
|
||||||
|
i386_fetch_minidump_thread,
|
||||||
};
|
};
|
||||||
|
@ -72,6 +72,12 @@ static const char* ppc_fetch_regname(unsigned regno)
|
|||||||
return NULL;
|
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 = {
|
DECLSPEC_HIDDEN struct cpu cpu_ppc = {
|
||||||
IMAGE_FILE_MACHINE_POWERPC,
|
IMAGE_FILE_MACHINE_POWERPC,
|
||||||
4,
|
4,
|
||||||
@ -82,4 +88,5 @@ DECLSPEC_HIDDEN struct cpu cpu_ppc = {
|
|||||||
ppc_map_dwarf_register,
|
ppc_map_dwarf_register,
|
||||||
ppc_fetch_context_reg,
|
ppc_fetch_context_reg,
|
||||||
ppc_fetch_regname,
|
ppc_fetch_regname,
|
||||||
|
ppc_fetch_minidump_thread,
|
||||||
};
|
};
|
||||||
|
@ -79,6 +79,12 @@ static const char* sparc_fetch_regname(unsigned regno)
|
|||||||
return NULL;
|
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 = {
|
DECLSPEC_HIDDEN struct cpu cpu_sparc = {
|
||||||
IMAGE_FILE_MACHINE_SPARC,
|
IMAGE_FILE_MACHINE_SPARC,
|
||||||
4,
|
4,
|
||||||
@ -89,4 +95,5 @@ DECLSPEC_HIDDEN struct cpu cpu_sparc = {
|
|||||||
sparc_map_dwarf_register,
|
sparc_map_dwarf_register,
|
||||||
sparc_fetch_context_reg,
|
sparc_fetch_context_reg,
|
||||||
sparc_fetch_regname,
|
sparc_fetch_regname,
|
||||||
|
sparc_fetch_minidump_thread,
|
||||||
};
|
};
|
||||||
|
@ -890,6 +890,20 @@ static const char* x86_64_fetch_regname(unsigned regno)
|
|||||||
return NULL;
|
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 = {
|
DECLSPEC_HIDDEN struct cpu cpu_x86_64 = {
|
||||||
IMAGE_FILE_MACHINE_AMD64,
|
IMAGE_FILE_MACHINE_AMD64,
|
||||||
8,
|
8,
|
||||||
@ -900,4 +914,5 @@ DECLSPEC_HIDDEN struct cpu cpu_x86_64 = {
|
|||||||
x86_64_map_dwarf_register,
|
x86_64_map_dwarf_register,
|
||||||
x86_64_fetch_context_reg,
|
x86_64_fetch_context_reg,
|
||||||
x86_64_fetch_regname,
|
x86_64_fetch_regname,
|
||||||
|
x86_64_fetch_minidump_thread,
|
||||||
};
|
};
|
||||||
|
@ -463,6 +463,55 @@ struct cpu_stack_walk
|
|||||||
} u;
|
} 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};
|
enum cpu_addr {cpu_addr_pc, cpu_addr_stack, cpu_addr_frame};
|
||||||
struct cpu
|
struct cpu
|
||||||
{
|
{
|
||||||
@ -486,6 +535,9 @@ struct cpu
|
|||||||
/* context related manipulation */
|
/* context related manipulation */
|
||||||
void* (*fetch_context_reg)(CONTEXT* context, unsigned regno, unsigned* size);
|
void* (*fetch_context_reg)(CONTEXT* context, unsigned regno, unsigned* size);
|
||||||
const char* (*fetch_regname)(unsigned regno);
|
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;
|
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_read_wine_loader_dbg_info(struct process* pcs) DECLSPEC_HIDDEN;
|
||||||
extern BOOL macho_synchronize_module_list(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 */
|
/* module.c */
|
||||||
extern const WCHAR S_ElfW[] DECLSPEC_HIDDEN;
|
extern const WCHAR S_ElfW[] DECLSPEC_HIDDEN;
|
||||||
extern const WCHAR S_WineLoaderW[] DECLSPEC_HIDDEN;
|
extern const WCHAR S_WineLoaderW[] DECLSPEC_HIDDEN;
|
||||||
|
@ -32,54 +32,6 @@
|
|||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
|
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
|
* 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
|
* 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
|
* 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
|
* also the rva of the memory block when written (this allows to reference
|
||||||
* a memory block from outside the list of memory blocks).
|
* 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)
|
if (!dc->mem)
|
||||||
{
|
{
|
||||||
@ -806,11 +758,11 @@ static unsigned dump_threads(struct dump_context* dc,
|
|||||||
}
|
}
|
||||||
if (mdThd.Stack.Memory.DataSize && (flags_out & ThreadWriteStack))
|
if (mdThd.Stack.Memory.DataSize && (flags_out & ThreadWriteStack))
|
||||||
{
|
{
|
||||||
add_memory_block(dc, mdThd.Stack.StartOfMemoryRange,
|
minidump_add_memory_block(dc, mdThd.Stack.StartOfMemoryRange,
|
||||||
mdThd.Stack.Memory.DataSize,
|
mdThd.Stack.Memory.DataSize,
|
||||||
rva_base + sizeof(mdThdList.NumberOfThreads) +
|
rva_base + sizeof(mdThdList.NumberOfThreads) +
|
||||||
mdThdList.NumberOfThreads * sizeof(mdThd) +
|
mdThdList.NumberOfThreads * sizeof(mdThd) +
|
||||||
FIELD_OFFSET(MINIDUMP_THREAD, Stack.Memory.Rva));
|
FIELD_OFFSET(MINIDUMP_THREAD, Stack.Memory.Rva));
|
||||||
}
|
}
|
||||||
writeat(dc,
|
writeat(dc,
|
||||||
rva_base + sizeof(mdThdList.NumberOfThreads) +
|
rva_base + sizeof(mdThdList.NumberOfThreads) +
|
||||||
@ -818,14 +770,8 @@ static unsigned dump_threads(struct dump_context* dc,
|
|||||||
&mdThd, sizeof(mdThd));
|
&mdThd, sizeof(mdThd));
|
||||||
mdThdList.NumberOfThreads++;
|
mdThdList.NumberOfThreads++;
|
||||||
}
|
}
|
||||||
if (ctx.ContextFlags && (flags_out & ThreadWriteInstructionWindow))
|
/* fetch CPU dependent thread info (like 256 bytes around program counter */
|
||||||
{
|
dbghelp_current_cpu->fetch_minidump_thread(dc, i, flags_out, &ctx);
|
||||||
/* 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); */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
writeat(dc, rva_base,
|
writeat(dc, rva_base,
|
||||||
&mdThdList.NumberOfThreads, sizeof(mdThdList.NumberOfThreads));
|
&mdThdList.NumberOfThreads, sizeof(mdThdList.NumberOfThreads));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user