mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-11 00:08:07 +00:00
checkpoint on dump file parsing / cache construction; temporarily turn off crash dump command, since still wip
This commit is contained in:
+9
-6
@@ -163,7 +163,8 @@ enum
|
|||||||
#define COFF_SectionFlags_ExtractAlign(f) (COFF_SectionAlign)(((f) >> COFF_SectionFlag_AlignShift) & COFF_SectionFlag_AlignMask)
|
#define COFF_SectionFlags_ExtractAlign(f) (COFF_SectionAlign)(((f) >> COFF_SectionFlag_AlignShift) & COFF_SectionFlag_AlignMask)
|
||||||
#define COFF_SectionFlags_LnkFlags ((COFF_SectionFlag_AlignMask << COFF_SectionFlag_AlignShift) | COFF_SectionFlag_LnkCOMDAT | COFF_SectionFlag_LnkInfo | COFF_SectionFlag_LnkOther | COFF_SectionFlag_LnkRemove | COFF_SectionFlag_LnkNRelocOvfl)
|
#define COFF_SectionFlags_LnkFlags ((COFF_SectionFlag_AlignMask << COFF_SectionFlag_AlignShift) | COFF_SectionFlag_LnkCOMDAT | COFF_SectionFlag_LnkInfo | COFF_SectionFlag_LnkOther | COFF_SectionFlag_LnkRemove | COFF_SectionFlag_LnkNRelocOvfl)
|
||||||
|
|
||||||
typedef struct COFF_SectionHeader
|
typedef struct COFF_SectionHeader COFF_SectionHeader;
|
||||||
|
struct COFF_SectionHeader
|
||||||
{
|
{
|
||||||
U8 name[8];
|
U8 name[8];
|
||||||
U32 vsize;
|
U32 vsize;
|
||||||
@@ -175,12 +176,12 @@ typedef struct COFF_SectionHeader
|
|||||||
U16 reloc_count;
|
U16 reloc_count;
|
||||||
U16 line_count;
|
U16 line_count;
|
||||||
COFF_SectionFlags flags;
|
COFF_SectionFlags flags;
|
||||||
} COFF_SectionHeader;
|
};
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
typedef U8 COFF_SymType;
|
typedef U8 COFF_SymType;
|
||||||
enum
|
typedef enum COFF_SymTypeEnum
|
||||||
{
|
{
|
||||||
COFF_SymType_Null,
|
COFF_SymType_Null,
|
||||||
COFF_SymType_Void,
|
COFF_SymType_Void,
|
||||||
@@ -198,10 +199,11 @@ enum
|
|||||||
COFF_SymType_Word,
|
COFF_SymType_Word,
|
||||||
COFF_SymType_UInt,
|
COFF_SymType_UInt,
|
||||||
COFF_SymType_DWord
|
COFF_SymType_DWord
|
||||||
};
|
}
|
||||||
|
COFF_SymTypeEnum;
|
||||||
|
|
||||||
typedef U8 COFF_SymStorageClass;
|
typedef U8 COFF_SymStorageClass;
|
||||||
enum
|
typedef enum COFF_SymStorageClassEnum
|
||||||
{
|
{
|
||||||
COFF_SymStorageClass_Null = 0x00,
|
COFF_SymStorageClass_Null = 0x00,
|
||||||
COFF_SymStorageClass_Automatic = 0x01,
|
COFF_SymStorageClass_Automatic = 0x01,
|
||||||
@@ -230,7 +232,8 @@ enum
|
|||||||
COFF_SymStorageClass_WeakExternal = 0x69,
|
COFF_SymStorageClass_WeakExternal = 0x69,
|
||||||
COFF_SymStorageClass_CLRToken = 0x6b,
|
COFF_SymStorageClass_CLRToken = 0x6b,
|
||||||
COFF_SymStorageClass_EndOfFunction = 0xff
|
COFF_SymStorageClass_EndOfFunction = 0xff
|
||||||
};
|
}
|
||||||
|
COFF_SymStorageClassEnum;
|
||||||
|
|
||||||
typedef U8 COFF_SymDType;
|
typedef U8 COFF_SymDType;
|
||||||
enum
|
enum
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ D_CmdTable: // | | | |
|
|||||||
{Attach 1 1 0 0 "query:unattached_processes" PID null Nil Null 0 0 0 0 0 1 1 Null "attach" "Attach" "Attaches to a process that is already running on the local machine." "" "" }
|
{Attach 1 1 0 0 "query:unattached_processes" PID null Nil Null 0 0 0 0 0 1 1 Null "attach" "Attach" "Attaches to a process that is already running on the local machine." "" "" }
|
||||||
|
|
||||||
//- rjf: crash dump opening
|
//- rjf: crash dump opening
|
||||||
{OpenCrashDump 1 1 0 0 `folder:\\"$input\\"` FilePath null Nil Null 0 0 0 0 0 1 1 FileOutline "open_crash_dump" "Open Crash Dump" "Opens a crash dump file and recreates debuggee state at the time of the crash." "" "" }
|
{OpenCrashDump 0 0 0 0 `folder:\\"$input\\"` FilePath null Nil Null 0 0 0 0 0 1 1 FileOutline "open_crash_dump" "Open Crash Dump" "Opens a crash dump file and recreates debuggee state at the time of the crash." "" "" }
|
||||||
}
|
}
|
||||||
|
|
||||||
@enum D_CmdKind:
|
@enum D_CmdKind:
|
||||||
|
|||||||
@@ -3830,6 +3830,12 @@ d_ctrl_thread__module_open(D_Handle process, D_Handle module, Rng1U64 vaddr_rang
|
|||||||
U32 data_dir_max = (opt_ext_size - reported_data_dir_offset) / sizeof(PE_DataDirectory);
|
U32 data_dir_max = (opt_ext_size - reported_data_dir_offset) / sizeof(PE_DataDirectory);
|
||||||
data_dir_count = ClampTop(reported_data_dir_count, data_dir_max);
|
data_dir_count = ClampTop(reported_data_dir_count, data_dir_max);
|
||||||
|
|
||||||
|
// rjf: extract sections
|
||||||
|
U64 sec_array_off = opt_ext_off_range.max;
|
||||||
|
U64 sec_count = file_header.section_count;
|
||||||
|
COFF_SectionHeader *sec = push_array(scratch.arena, COFF_SectionHeader, sec_count);
|
||||||
|
d_process_read(process, r1u64(vaddr_range.min + sec_array_off, vaddr_range.min + sec_array_off + sec_count*sizeof(COFF_SectionHeader)), sec);
|
||||||
|
|
||||||
// rjf: grab pdatas from exceptions section
|
// rjf: grab pdatas from exceptions section
|
||||||
if(data_dir_count > PE_DataDirectoryIndex_EXCEPTIONS)
|
if(data_dir_count > PE_DataDirectoryIndex_EXCEPTIONS)
|
||||||
{
|
{
|
||||||
@@ -3841,12 +3847,6 @@ d_ctrl_thread__module_open(D_Handle process, D_Handle module, Rng1U64 vaddr_rang
|
|||||||
d_process_read(process, r1u64(vaddr_range.min + pdatas_voff_range.min, vaddr_range.min + pdatas_voff_range.max), pdatas);
|
d_process_read(process, r1u64(vaddr_range.min + pdatas_voff_range.min, vaddr_range.min + pdatas_voff_range.max), pdatas);
|
||||||
}
|
}
|
||||||
|
|
||||||
// rjf: extract sections
|
|
||||||
U64 sec_array_off = opt_ext_off_range.max;
|
|
||||||
U64 sec_count = file_header.section_count;
|
|
||||||
COFF_SectionHeader *sec = push_array(scratch.arena, COFF_SectionHeader, sec_count);
|
|
||||||
d_process_read(process, r1u64(vaddr_range.min + sec_array_off, vaddr_range.min + sec_array_off + sec_count*sizeof(COFF_SectionHeader)), sec);
|
|
||||||
|
|
||||||
// rjf: grab entry point vaddr
|
// rjf: grab entry point vaddr
|
||||||
entry_point_voff = entry_point;
|
entry_point_voff = entry_point;
|
||||||
|
|
||||||
@@ -3968,11 +3968,9 @@ d_ctrl_thread__module_open(D_Handle process, D_Handle module, Rng1U64 vaddr_rang
|
|||||||
switch(elf_sig[ELF_Identifier_Class])
|
switch(elf_sig[ELF_Identifier_Class])
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case ELF_Class_None:{}break;
|
case ELF_Class_None:
|
||||||
case ELF_Class_32:
|
case ELF_Class_32:
|
||||||
{
|
{}break;
|
||||||
NotImplemented;
|
|
||||||
}break;
|
|
||||||
case ELF_Class_64:
|
case ELF_Class_64:
|
||||||
{
|
{
|
||||||
ELF_Hdr64 *ehdr = (ELF_Hdr64 *)d_data_from_process_vaddr_range(scratch.arena, process, r1u64(vaddr_range.min, vaddr_range.min + sizeof(*ehdr)), 0).str;
|
ELF_Hdr64 *ehdr = (ELF_Hdr64 *)d_data_from_process_vaddr_range(scratch.arena, process, r1u64(vaddr_range.min, vaddr_range.min + sizeof(*ehdr)), 0).str;
|
||||||
@@ -3994,12 +3992,7 @@ d_ctrl_thread__module_open(D_Handle process, D_Handle module, Rng1U64 vaddr_rang
|
|||||||
{
|
{
|
||||||
void *phdrs_raw = d_data_from_process_vaddr_range(scratch.arena, process, elf_phdr_vrange, 0).str;
|
void *phdrs_raw = d_data_from_process_vaddr_range(scratch.arena, process, elf_phdr_vrange, 0).str;
|
||||||
if(phdrs_raw == 0) { goto elf_exit; }
|
if(phdrs_raw == 0) { goto elf_exit; }
|
||||||
|
if(elf_phdr_entsize == sizeof(ELF_Phdr64))
|
||||||
if(elf_phdr_entsize == sizeof(ELF_Phdr32))
|
|
||||||
{
|
|
||||||
NotImplemented;
|
|
||||||
}
|
|
||||||
else if(elf_phdr_entsize == sizeof(ELF_Phdr64))
|
|
||||||
{
|
{
|
||||||
U64 elf_phcount = dim_1u64(elf_phdr_vrange) / elf_phdr_entsize;
|
U64 elf_phcount = dim_1u64(elf_phdr_vrange) / elf_phdr_entsize;
|
||||||
ELF_Phdr64 *phdrs64 = phdrs_raw;
|
ELF_Phdr64 *phdrs64 = phdrs_raw;
|
||||||
@@ -4201,9 +4194,11 @@ d_ctrl_thread__close_dump_process(D_MsgID msg_id, D_Handle process)
|
|||||||
U64 hash = d_hash_from_handle(process);
|
U64 hash = d_hash_from_handle(process);
|
||||||
U64 slot_idx = hash%cache->slots_count;
|
U64 slot_idx = hash%cache->slots_count;
|
||||||
Stripe *stripe = stripe_from_slot_idx(&cache->stripes, slot_idx);
|
Stripe *stripe = stripe_from_slot_idx(&cache->stripes, slot_idx);
|
||||||
|
|
||||||
|
// rjf: remove node
|
||||||
|
D_DumpNode *node = 0;
|
||||||
RWMutexScope(stripe->rw_mutex, 1)
|
RWMutexScope(stripe->rw_mutex, 1)
|
||||||
{
|
{
|
||||||
D_DumpNode *node = 0;
|
|
||||||
for(D_DumpNode *n = cache->slots[slot_idx].first; n != 0; n = n->next)
|
for(D_DumpNode *n = cache->slots[slot_idx].first; n != 0; n = n->next)
|
||||||
{
|
{
|
||||||
if(d_handle_match(n->process, process))
|
if(d_handle_match(n->process, process))
|
||||||
@@ -4215,13 +4210,29 @@ d_ctrl_thread__close_dump_process(D_MsgID msg_id, D_Handle process)
|
|||||||
if(node != 0)
|
if(node != 0)
|
||||||
{
|
{
|
||||||
DLLRemove(cache->slots[slot_idx].first, cache->slots[slot_idx].last, node);
|
DLLRemove(cache->slots[slot_idx].first, cache->slots[slot_idx].last, node);
|
||||||
node->next = (D_DumpNode *)stripe->free;
|
}
|
||||||
stripe->free = node;
|
}
|
||||||
|
|
||||||
|
// rjf: release node contents
|
||||||
|
if(node != 0)
|
||||||
|
{
|
||||||
|
for EachIndex(idx, node->modules_count)
|
||||||
|
{
|
||||||
|
file_map_view_close(node->modules[idx].map, node->modules[idx].base, r1u64(0, node->modules[idx].props.size));
|
||||||
|
file_map_close(node->modules[idx].map);
|
||||||
|
file_close(node->modules[idx].file);
|
||||||
|
}
|
||||||
file_map_view_close(node->map, node->base, r1u64(0, node->props.size));
|
file_map_view_close(node->map, node->base, r1u64(0, node->props.size));
|
||||||
file_map_close(node->map);
|
file_map_close(node->map);
|
||||||
file_close(node->file);
|
file_close(node->file);
|
||||||
arena_release(node->arena);
|
arena_release(node->arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rjf: attach node to free list
|
||||||
|
if(node != 0) RWMutexScope(stripe->rw_mutex, 1)
|
||||||
|
{
|
||||||
|
node->next = (D_DumpNode *)stripe->free;
|
||||||
|
stripe->free = node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5125,7 +5136,11 @@ d_ctrl_thread__open_crash_dump(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
|||||||
U64 memory_ranges_count = 0;
|
U64 memory_ranges_count = 0;
|
||||||
D_DumpThread *dump_threads = 0;
|
D_DumpThread *dump_threads = 0;
|
||||||
U64 dump_threads_count = 0;
|
U64 dump_threads_count = 0;
|
||||||
|
D_DumpModule *dump_modules = 0;
|
||||||
|
U64 dump_modules_count = 0;
|
||||||
D_Handle process = {0};
|
D_Handle process = {0};
|
||||||
|
Arch process_arch = Arch_Null;
|
||||||
|
OperatingSystem process_os = OperatingSystem_Null;
|
||||||
{
|
{
|
||||||
//- rjf: try minidump parse -> construct events for entity creation
|
//- rjf: try minidump parse -> construct events for entity creation
|
||||||
{
|
{
|
||||||
@@ -5213,9 +5228,6 @@ d_ctrl_thread__open_crash_dump(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// rjf: allocate parse artifact arena
|
|
||||||
arena = arena_alloc();
|
|
||||||
|
|
||||||
// rjf: gather memory ranges
|
// rjf: gather memory ranges
|
||||||
memory_ranges_count = memories_count + memories64_count;
|
memory_ranges_count = memories_count + memories64_count;
|
||||||
memory_ranges = push_array(arena, D_DumpMemoryRange, memory_ranges_count);
|
memory_ranges = push_array(arena, D_DumpMemoryRange, memory_ranges_count);
|
||||||
@@ -5235,50 +5247,34 @@ d_ctrl_thread__open_crash_dump(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// rjf: system info -> arch
|
// rjf: system info -> arch
|
||||||
Arch arch = Arch_Null;
|
|
||||||
if(system_info != 0) switch(system_info->processor_architecture)
|
if(system_info != 0) switch(system_info->processor_architecture)
|
||||||
{
|
{
|
||||||
default:{}break;
|
default:{}break;
|
||||||
case MDMP_Arch_x86:{arch = Arch_x86;}break;
|
case MDMP_Arch_x86:{process_arch = Arch_x86;}break;
|
||||||
case MDMP_Arch_x64:{arch = Arch_x64;}break;
|
case MDMP_Arch_x64:{process_arch = Arch_x64;}break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// rjf: process creation
|
// rjf: create process handle
|
||||||
U64 handle_id_gen = 1;
|
d_ctrl_state->ctrl_thread_dump_handle_id_gen += 1;
|
||||||
process = d_dump_handle_make(D_MachineID_Local, handle_id_gen);
|
process = d_dump_handle_make(D_MachineID_Local, d_ctrl_state->ctrl_thread_dump_handle_id_gen);
|
||||||
handle_id_gen += 1;
|
process_os = OperatingSystem_Windows; // NOTE(rjf): minidumps are always windows
|
||||||
{
|
|
||||||
D_Event *evt = d_event_list_push(scratch.arena, &evts);
|
|
||||||
evt->kind = D_EventKind_NewProc;
|
|
||||||
evt->msg_id = msg->msg_id;
|
|
||||||
evt->entity = process;
|
|
||||||
evt->arch = arch;
|
|
||||||
evt->target_os = OperatingSystem_Windows;
|
|
||||||
evt->string = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
// rjf: thread creation
|
// rjf: gather threads
|
||||||
dump_threads_count = threads_count;
|
dump_threads_count = threads_count;
|
||||||
dump_threads = push_array(arena, D_DumpThread, dump_threads_count);
|
dump_threads = push_array(arena, D_DumpThread, dump_threads_count);
|
||||||
for EachIndex(idx, threads_count)
|
for EachIndex(idx, threads_count)
|
||||||
{
|
{
|
||||||
|
d_ctrl_state->ctrl_thread_dump_handle_id_gen += 1;
|
||||||
MDMP_Thread *thread = &threads[idx];
|
MDMP_Thread *thread = &threads[idx];
|
||||||
D_Handle thread_handle = d_dump_handle_make(D_MachineID_Local, handle_id_gen);
|
D_Handle thread_handle = d_dump_handle_make(D_MachineID_Local, d_ctrl_state->ctrl_thread_dump_handle_id_gen);
|
||||||
dump_threads[idx].thread_handle = thread_handle;
|
dump_threads[idx].thread_handle = thread_handle;
|
||||||
|
dump_threads[idx].id = thread->id;
|
||||||
dump_threads[idx].context_foff = thread->thread_context.foff;
|
dump_threads[idx].context_foff = thread->thread_context.foff;
|
||||||
D_Event *evt = d_event_list_push(scratch.arena, &evts);
|
|
||||||
evt->kind = D_EventKind_NewThread;
|
|
||||||
evt->msg_id = msg->msg_id;
|
|
||||||
evt->entity = thread_handle;
|
|
||||||
evt->parent = process;
|
|
||||||
evt->arch = arch;
|
|
||||||
evt->entity_id = thread->id;
|
|
||||||
// TODO(rjf): evt->stack_base = ; (use thread->stack)
|
|
||||||
// TODO(rjf): evt->tls_root = ; (use thread->thread_context)
|
|
||||||
handle_id_gen += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// rjf: module loads
|
// rjf: gather modules
|
||||||
|
dump_modules_count = modules_count;
|
||||||
|
dump_modules = push_array(arena, D_DumpModule, dump_modules_count);
|
||||||
for EachIndex(idx, modules_count)
|
for EachIndex(idx, modules_count)
|
||||||
{
|
{
|
||||||
// rjf: unpack module
|
// rjf: unpack module
|
||||||
@@ -5296,60 +5292,37 @@ d_ctrl_thread__open_crash_dump(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
|||||||
module_name = path_normalized_from_string(scratch.arena, module_name);
|
module_name = path_normalized_from_string(scratch.arena, module_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// rjf: open module
|
// rjf: open module file
|
||||||
D_Handle module_handle = d_dump_handle_make(D_MachineID_Local, handle_id_gen);
|
File module_file = file_open(AccessFlag_Read|AccessFlag_ShareRead, module_name);
|
||||||
handle_id_gen += 1;
|
FileProperties module_props = properties_from_file(module_file);
|
||||||
d_ctrl_thread__module_open(process, module_handle, vaddr_range, module_name, r1u64(0, 0), 0);
|
FileMap module_map = file_map_open(AccessFlag_Read, module_file);
|
||||||
|
void *module_base = file_map_view_open(module_map, AccessFlag_Read, r1u64(0, module_props.size));
|
||||||
|
|
||||||
// rjf: open debug info
|
// rjf: store
|
||||||
String8 initial_debug_info_path = d_initial_debug_info_path_from_module(scratch.arena, module_handle);
|
d_ctrl_state->ctrl_thread_dump_handle_id_gen += 1;
|
||||||
U64 debug_info_timestamp = properties_from_file_path(initial_debug_info_path).modified;
|
dump_modules[idx].module_handle = d_dump_handle_make(D_MachineID_Local, d_ctrl_state->ctrl_thread_dump_handle_id_gen);
|
||||||
DI_Key initial_dbgi_key = di_key_from_path_timestamp(initial_debug_info_path, debug_info_timestamp);
|
dump_modules[idx].vaddr_range = vaddr_range;
|
||||||
di_open(initial_dbgi_key);
|
dump_modules[idx].path = str8_copy(arena, module_name);
|
||||||
|
dump_modules[idx].file = module_file;
|
||||||
|
dump_modules[idx].props = module_props;
|
||||||
|
dump_modules[idx].map = module_map;
|
||||||
|
dump_modules[idx].base = module_base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// rjf: push module load event
|
//- rjf: record process creation
|
||||||
{
|
{
|
||||||
D_Event *evt = d_event_list_push(scratch.arena, &evts);
|
D_Event *evt = d_event_list_push(scratch.arena, &evts);
|
||||||
evt->kind = D_EventKind_NewModule;
|
evt->kind = D_EventKind_NewProc;
|
||||||
evt->msg_id = msg->msg_id;
|
evt->msg_id = msg->msg_id;
|
||||||
evt->entity = module_handle;
|
evt->entity = process;
|
||||||
evt->parent = process;
|
evt->arch = process_arch;
|
||||||
evt->arch = arch;
|
evt->target_os = process_os;
|
||||||
evt->vaddr_rng = vaddr_range;
|
evt->string = path;
|
||||||
evt->string = module_name;
|
|
||||||
// TODO(rjf): evt->stack_base = ; (use thread->stack)
|
|
||||||
// TODO(rjf): evt->tls_root = ; (use thread->thread_context)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// rjf: push debug info initial path set event
|
|
||||||
{
|
|
||||||
D_Event *evt = d_event_list_push(scratch.arena, &evts);
|
|
||||||
evt->kind = D_EventKind_ModuleDebugInfoPathChange;
|
|
||||||
evt->msg_id = msg->msg_id;
|
|
||||||
evt->entity = module_handle;
|
|
||||||
evt->parent = process;
|
|
||||||
evt->timestamp = debug_info_timestamp;
|
|
||||||
evt->string = initial_debug_info_path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//- rjf: record stop
|
|
||||||
{
|
|
||||||
D_Event *event = d_event_list_push(scratch.arena, &evts);
|
|
||||||
event->kind = D_EventKind_Stopped;
|
|
||||||
event->cause = D_EventCause_Finished;
|
|
||||||
event->msg_id = msg->msg_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- rjf: push all events from the parse
|
|
||||||
ins_atomic_u64_inc_eval(&d_ctrl_state->mem_gen);
|
|
||||||
ins_atomic_u64_inc_eval(&d_ctrl_state->reg_gen);
|
|
||||||
ins_atomic_u64_inc_eval(&d_ctrl_state->run_gen);
|
|
||||||
d_c2u_push_events(&evts);
|
|
||||||
|
|
||||||
//- rjf: store the dump parse artifacts in the dump cache, otherwise release
|
//- rjf: store the dump parse artifacts in the dump cache, otherwise release
|
||||||
if(stored)
|
if(stored)
|
||||||
{
|
{
|
||||||
@@ -5379,6 +5352,8 @@ d_ctrl_thread__open_crash_dump(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
|||||||
node->memory_ranges_count = memory_ranges_count;
|
node->memory_ranges_count = memory_ranges_count;
|
||||||
node->threads = dump_threads;
|
node->threads = dump_threads;
|
||||||
node->threads_count = dump_threads_count;
|
node->threads_count = dump_threads_count;
|
||||||
|
node->modules = dump_modules;
|
||||||
|
node->modules_count = dump_modules_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -5392,6 +5367,75 @@ d_ctrl_thread__open_crash_dump(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
|||||||
file_close(file);
|
file_close(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- rjf: record thread creation
|
||||||
|
for EachIndex(idx, dump_threads_count)
|
||||||
|
{
|
||||||
|
D_Handle thread_handle = dump_threads[idx].thread_handle;
|
||||||
|
D_Event *evt = d_event_list_push(scratch.arena, &evts);
|
||||||
|
evt->kind = D_EventKind_NewThread;
|
||||||
|
evt->msg_id = msg->msg_id;
|
||||||
|
evt->entity = thread_handle;
|
||||||
|
evt->parent = process;
|
||||||
|
evt->arch = process_arch;
|
||||||
|
evt->entity_id = dump_threads[idx].id;
|
||||||
|
// TODO(rjf): evt->stack_base = ; (use thread->stack)
|
||||||
|
// TODO(rjf): evt->tls_root = ; (use thread->thread_context)
|
||||||
|
}
|
||||||
|
|
||||||
|
//- rjf: record module loading
|
||||||
|
for EachIndex(idx, dump_modules_count)
|
||||||
|
{
|
||||||
|
// rjf: open module
|
||||||
|
D_Handle module_handle = dump_modules[idx].module_handle;
|
||||||
|
Rng1U64 vaddr_range = dump_modules[idx].vaddr_range;
|
||||||
|
d_ctrl_thread__module_open(process, module_handle, vaddr_range, dump_modules[idx].path, r1u64(0, 0), 0);
|
||||||
|
|
||||||
|
// rjf: open debug info
|
||||||
|
String8 initial_debug_info_path = d_initial_debug_info_path_from_module(scratch.arena, module_handle);
|
||||||
|
U64 debug_info_timestamp = properties_from_file_path(initial_debug_info_path).modified;
|
||||||
|
DI_Key initial_dbgi_key = di_key_from_path_timestamp(initial_debug_info_path, debug_info_timestamp);
|
||||||
|
di_open(initial_dbgi_key);
|
||||||
|
|
||||||
|
// rjf: push module load event
|
||||||
|
{
|
||||||
|
D_Event *evt = d_event_list_push(scratch.arena, &evts);
|
||||||
|
evt->kind = D_EventKind_NewModule;
|
||||||
|
evt->msg_id = msg->msg_id;
|
||||||
|
evt->entity = module_handle;
|
||||||
|
evt->parent = process;
|
||||||
|
evt->arch = process_arch;
|
||||||
|
evt->vaddr_rng = vaddr_range;
|
||||||
|
evt->string = dump_modules[idx].path;
|
||||||
|
// TODO(rjf): evt->stack_base = ; (use thread->stack)
|
||||||
|
// TODO(rjf): evt->tls_root = ; (use thread->thread_context)
|
||||||
|
}
|
||||||
|
|
||||||
|
// rjf: push debug info initial path set event
|
||||||
|
{
|
||||||
|
D_Event *evt = d_event_list_push(scratch.arena, &evts);
|
||||||
|
evt->kind = D_EventKind_ModuleDebugInfoPathChange;
|
||||||
|
evt->msg_id = msg->msg_id;
|
||||||
|
evt->entity = module_handle;
|
||||||
|
evt->parent = process;
|
||||||
|
evt->timestamp = debug_info_timestamp;
|
||||||
|
evt->string = initial_debug_info_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//- rjf: record stop
|
||||||
|
{
|
||||||
|
D_Event *event = d_event_list_push(scratch.arena, &evts);
|
||||||
|
event->kind = D_EventKind_Stopped;
|
||||||
|
event->cause = D_EventCause_Finished;
|
||||||
|
event->msg_id = msg->msg_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- rjf: push all events from the parse
|
||||||
|
ins_atomic_u64_inc_eval(&d_ctrl_state->mem_gen);
|
||||||
|
ins_atomic_u64_inc_eval(&d_ctrl_state->reg_gen);
|
||||||
|
ins_atomic_u64_inc_eval(&d_ctrl_state->run_gen);
|
||||||
|
d_c2u_push_events(&evts);
|
||||||
|
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -228,9 +228,22 @@ typedef struct D_DumpThread D_DumpThread;
|
|||||||
struct D_DumpThread
|
struct D_DumpThread
|
||||||
{
|
{
|
||||||
D_Handle thread_handle;
|
D_Handle thread_handle;
|
||||||
|
U32 id;
|
||||||
U64 context_foff;
|
U64 context_foff;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct D_DumpModule D_DumpModule;
|
||||||
|
struct D_DumpModule
|
||||||
|
{
|
||||||
|
D_Handle module_handle;
|
||||||
|
Rng1U64 vaddr_range;
|
||||||
|
String8 path;
|
||||||
|
File file;
|
||||||
|
FileProperties props;
|
||||||
|
FileMap map;
|
||||||
|
void *base;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct D_DumpNode D_DumpNode;
|
typedef struct D_DumpNode D_DumpNode;
|
||||||
struct D_DumpNode
|
struct D_DumpNode
|
||||||
{
|
{
|
||||||
@@ -246,6 +259,8 @@ struct D_DumpNode
|
|||||||
U64 memory_ranges_count;
|
U64 memory_ranges_count;
|
||||||
D_DumpThread *threads;
|
D_DumpThread *threads;
|
||||||
U64 threads_count;
|
U64 threads_count;
|
||||||
|
D_DumpModule *modules;
|
||||||
|
U64 modules_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct D_DumpSlot D_DumpSlot;
|
typedef struct D_DumpSlot D_DumpSlot;
|
||||||
@@ -349,6 +364,7 @@ struct D_CtrlState
|
|||||||
CondVar c2u_ring_cv;
|
CondVar c2u_ring_cv;
|
||||||
|
|
||||||
// rjf: ctrl thread state
|
// rjf: ctrl thread state
|
||||||
|
U64 ctrl_thread_dump_handle_id_gen;
|
||||||
U64 ctrl_thread_run_state;
|
U64 ctrl_thread_run_state;
|
||||||
String8 ctrl_thread_log_path;
|
String8 ctrl_thread_log_path;
|
||||||
Thread ctrl_thread;
|
Thread ctrl_thread;
|
||||||
|
|||||||
@@ -610,7 +610,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[249] =
|
|||||||
{ str8_lit_comp("set_entity_color"), str8_lit_comp("Sets the passed entity's color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), D_EntityKind_Null}},
|
{ str8_lit_comp("set_entity_color"), str8_lit_comp("Sets the passed entity's color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), D_EntityKind_Null}},
|
||||||
{ str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), D_EntityKind_Null}},
|
{ str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), D_EntityKind_Null}},
|
||||||
{ str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp("query:unattached_processes"), str8_lit_comp(""), D_EntityKind_Null}},
|
{ str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp("query:unattached_processes"), str8_lit_comp(""), D_EntityKind_Null}},
|
||||||
{ str8_lit_comp("open_crash_dump"), str8_lit_comp("Opens a crash dump file and recreates debuggee state at the time of the crash."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), D_EntityKind_Null}},
|
{ str8_lit_comp("open_crash_dump"), str8_lit_comp("Opens a crash dump file and recreates debuggee state at the time of the crash."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), D_EntityKind_Null}},
|
||||||
{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), D_EntityKind_Null}},
|
{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), D_EntityKind_Null}},
|
||||||
{ str8_lit_comp("open_palette"), str8_lit_comp("Opens the palette."), str8_lit_comp("help,cmd,lister"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), D_EntityKind_Null}},
|
{ str8_lit_comp("open_palette"), str8_lit_comp("Opens the palette."), str8_lit_comp("help,cmd,lister"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), D_EntityKind_Null}},
|
||||||
{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("query:commands"), str8_lit_comp("commands"), D_EntityKind_Null}},
|
{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("query:commands"), str8_lit_comp("commands"), D_EntityKind_Null}},
|
||||||
|
|||||||
@@ -5575,11 +5575,11 @@ rd_window_frame(void)
|
|||||||
}
|
}
|
||||||
else if(dbg_info_entity->string.size != 0)
|
else if(dbg_info_entity->string.size != 0)
|
||||||
{
|
{
|
||||||
ui_labelf("Debug information not found at %S", dbg_info_entity->string);
|
ui_labelf("Debug info not found at %S", dbg_info_entity->string);
|
||||||
}
|
}
|
||||||
else if(dbg_info_entity->string.size == 0)
|
else if(dbg_info_entity->string.size == 0)
|
||||||
{
|
{
|
||||||
ui_labelf("Debug information location not found in module file");
|
ui_labelf("Debug info location not found in module file");
|
||||||
}
|
}
|
||||||
access_close(access);
|
access_close(access);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -612,7 +612,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, D_Entity *entity, B32 include_extr
|
|||||||
if(rdi->raw_data_size == 0)
|
if(rdi->raw_data_size == 0)
|
||||||
{
|
{
|
||||||
dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" "));
|
dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" "));
|
||||||
dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("(Debug information not loaded)"), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .size = extras_size, .color = secondary_color);
|
dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("(Debug info not loaded)"), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .size = extras_size, .color = secondary_color);
|
||||||
}
|
}
|
||||||
access_close(access);
|
access_close(access);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1101,6 +1101,7 @@ file_map_view_open(FileMap map, AccessFlags flags, Rng1U64 range)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void *result = MapViewOfFile(handle, access_flags, off_hi, off_lo, size);
|
void *result = MapViewOfFile(handle, access_flags, off_hi, off_lo, size);
|
||||||
|
DWORD err = GetLastError();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user