dwarf debug info option in builds, fix heuristic to try to load debug info from exe itself

This commit is contained in:
Ryan Fleury
2025-10-01 15:36:36 -07:00
parent db66beaf22
commit 7707ba1d60
6 changed files with 47 additions and 30 deletions
+28 -9
View File
@@ -3399,11 +3399,12 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
U32 pdb_dbg_time = 0;
U32 pdb_dbg_age = 0;
Guid pdb_dbg_guid = {0};
String8 pdb_dbg_path = str8_zero();
String8 pdb_dbg_path = {0};
U32 rdi_dbg_time = 0;
Guid rdi_dbg_guid = {0};
String8 rdi_dbg_path = str8_zero();
String8 raddbg_data = str8_zero();
String8 exe_dbg_path = {0};
String8 rdi_dbg_path = {0};
String8 raddbg_data = {0};
Rng1U64 raddbg_section_voff_range = r1u64(0, 0);
Rng1U64 raddbg_is_attached_section_voff_range = r1u64(0, 0);
ProfScope("unpack relevant PE info")
@@ -3453,6 +3454,8 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
U32 data_dir_count = 0;
if(opt_ext_size > 0)
{
Temp scratch = scratch_begin(0, 0);
// rjf: read magic number
U16 opt_ext_magic = 0;
dmn_process_read_struct(process.dmn_handle, vaddr_range.min + opt_ext_off_range.min, &opt_ext_magic);
@@ -3523,6 +3526,12 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
}
}
// 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);
dmn_process_read(process.dmn_handle, r1u64(vaddr_range.min + sec_array_off, vaddr_range.min + sec_array_off + sec_count*sizeof(COFF_SectionHeader)), sec);
// rjf: grab entry point vaddr
entry_point_voff = entry_point;
@@ -3589,13 +3598,18 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
}
}
// rjf: look for DWARF debug info
{
U64 symbol_array_off = file_header.symbol_table_foff;
U64 symbol_count = file_header.symbol_count;
if(symbol_array_off != 0)
{
exe_dbg_path = path;
}
}
// rjf: extract copy of module's raddbg data
{
Temp scratch = scratch_begin(0, 0);
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);
dmn_process_read(process.dmn_handle, r1u64(vaddr_range.min + sec_array_off, vaddr_range.min + sec_array_off + sec_count*sizeof(COFF_SectionHeader)), sec);
for EachIndex(idx, sec_count)
{
String8 section_name = str8_cstring((char *)sec[idx].name);
@@ -3614,7 +3628,6 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
raddbg_data.str = push_array(arena, U8, raddbg_data.size);
dmn_process_read(process.dmn_handle, r1u64(vaddr_range.min + raddbg_section_voff_range.min,
vaddr_range.min + raddbg_section_voff_range.max), raddbg_data.str);
scratch_end(scratch);
}
// rjf: if we have a "raddbg is attached" section, mark the first byte as 1, to signify attachment
@@ -3623,6 +3636,8 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
U8 new_value = 1;
dmn_process_write_struct(process.dmn_handle, vaddr_range.min + raddbg_is_attached_section_voff_range.min, &new_value);
}
scratch_end(scratch);
}
}
@@ -3649,6 +3664,10 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
str8_list_pushf(scratch.arena, &dbg_path_candidates, "%S/%S", exe_folder, rdi_dbg_path);
str8_list_push(scratch.arena, &dbg_path_candidates, rdi_dbg_path);
}
if(exe_dbg_path.size != 0)
{
str8_list_push(scratch.arena, &dbg_path_candidates, path);
}
if(pdb_dbg_path.size != 0)
{
str8_list_pushf(scratch.arena, &dbg_path_candidates, "%S/%S", exe_folder, pdb_dbg_path);
+9 -13
View File
@@ -2,28 +2,24 @@
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal B32
dw_is_dwarf_present_coff_section_table(String8 raw_image,
String8 string_table,
U64 section_count,
COFF_SectionHeader *section_table)
dw_is_dwarf_present_coff_section_table(String8 string_table, U64 section_count, COFF_SectionHeader *section_table)
{
B32 is_dwarf_present = 0;
for (U64 i = 0; i < section_count; ++i) {
COFF_SectionHeader *header = &section_table[i];
String8 name = coff_name_from_section_header(string_table, header);
for EachIndex(idx, section_count)
{
COFF_SectionHeader *header = &section_table[idx];
String8 name = coff_name_from_section_header(string_table, header);
DW_SectionKind s = dw_section_kind_from_string(name);
if (s == DW_Section_Null) {
if(s == DW_Section_Null)
{
s = dw_section_dwo_kind_from_string(name);
}
is_dwarf_present = s != DW_Section_Null;
if (is_dwarf_present) {
if(is_dwarf_present)
{
break;
}
}
return is_dwarf_present;
}
+1 -1
View File
@@ -4,7 +4,7 @@
#ifndef DWARF_COFF_H
#define DWARF_COFF_H
internal B32 dw_is_dwarf_present_coff_section_table(String8 raw_image, String8 string_table, U64 section_count, COFF_SectionHeader *section_table);
internal B32 dw_is_dwarf_present_coff_section_table(String8 string_table, U64 section_count, COFF_SectionHeader *section_table);
internal DW_Input dw_input_from_coff_section_table(Arena *arena, String8 raw_image, String8 string_table, U64 section_count, COFF_SectionHeader *section_table);
#endif // DWARF_COFF_H
+1 -1
View File
@@ -331,7 +331,7 @@ rb_thread_entry_point(void *p)
String8 string_table = str8_substr(file_data, pe_bin_info.string_table_range);
U64 section_count = raw_section_table.size / sizeof(COFF_SectionHeader);
COFF_SectionHeader *section_table = (COFF_SectionHeader *)raw_section_table.str;
if(dw_is_dwarf_present_coff_section_table(file_data, string_table, section_count, section_table))
if(dw_is_dwarf_present_coff_section_table(string_table, section_count, section_table))
{
file_format_flags |= RB_FileFormatFlag_HasDWARF;
}
+1 -1
View File
@@ -1251,7 +1251,7 @@ rd_target_from_cfg(Arena *arena, RD_Cfg *cfg)
target.stdout_path = rd_cfg_child_from_string(cfg, str8_lit("stdout_path"))->first->string;
target.stderr_path = rd_cfg_child_from_string(cfg, str8_lit("stderr_path"))->first->string;
target.stdin_path = rd_cfg_child_from_string(cfg, str8_lit("stdin_path"))->first->string;
target.debug_subprocesses = (rd_cfg_child_from_string(cfg, str8_lit("debug_subprocesses")) != &rd_nil_cfg);
target.debug_subprocesses = !!e_value_from_string(rd_cfg_child_from_string(cfg, str8_lit("debug_subprocesses"))->first->string).u64;
for(RD_Cfg *child = cfg->first; child != &rd_nil_cfg; child = child->next)
{
if(str8_match(child->string, str8_lit("environment"), 0))