Refactor cu lookup out of pc resolution
This commit is contained in:
parent
8bff5dc9fe
commit
5556aedddb
@ -809,16 +809,17 @@ namespace libdwarf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct cu_info {
|
||||||
|
maybe_owned_die_object cu_die;
|
||||||
|
Dwarf_Half dwversion;
|
||||||
|
};
|
||||||
|
|
||||||
|
// CU resolution has three paths:
|
||||||
|
// - If aranges are present, the pc is looked up in aranges (falls through to next cases if not in aranges)
|
||||||
|
// - If cache mode is prioritize memory, the CUs are walked for a match
|
||||||
|
// - Otherwise a CU cache is built up and CUs are looked up in the map
|
||||||
CPPTRACE_FORCE_NO_INLINE_FOR_PROFILING
|
CPPTRACE_FORCE_NO_INLINE_FOR_PROFILING
|
||||||
void lookup_pc(
|
optional<cu_info> lookup_cu(Dwarf_Addr pc) {
|
||||||
Dwarf_Addr pc,
|
|
||||||
stacktrace_frame& frame,
|
|
||||||
std::vector<stacktrace_frame>& inlines
|
|
||||||
) {
|
|
||||||
if(dump_dwarf) {
|
|
||||||
std::fprintf(stderr, "%s\n", object_path.c_str());
|
|
||||||
std::fprintf(stderr, "%llx\n", to_ull(pc));
|
|
||||||
}
|
|
||||||
// Check for .debug_aranges for fast lookup
|
// Check for .debug_aranges for fast lookup
|
||||||
if(aranges) {
|
if(aranges) {
|
||||||
// Try to find pc in aranges
|
// Try to find pc in aranges
|
||||||
@ -838,9 +839,8 @@ namespace libdwarf {
|
|||||||
std::fprintf(stderr, "Found CU in aranges\n");
|
std::fprintf(stderr, "Found CU in aranges\n");
|
||||||
cu_die.print();
|
cu_die.print();
|
||||||
}
|
}
|
||||||
retrieve_line_info(cu_die, pc, frame); // no offset for line info
|
// resolve_pc(cu_die, dwversion, pc, frame, inlines);
|
||||||
retrieve_symbol(cu_die, pc, dwversion, frame, inlines);
|
return cu_info{maybe_owned_die_object::owned(std::move(cu_die)), dwversion};
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// otherwise, or if not in aranges
|
// otherwise, or if not in aranges
|
||||||
@ -849,7 +849,8 @@ namespace libdwarf {
|
|||||||
// compiler while the C compiler defaults to an older gcc)
|
// compiler while the C compiler defaults to an older gcc)
|
||||||
if(get_cache_mode() == cache_mode::prioritize_memory) {
|
if(get_cache_mode() == cache_mode::prioritize_memory) {
|
||||||
// walk for the cu and go from there
|
// walk for the cu and go from there
|
||||||
walk_compilation_units([this, pc, &frame, &inlines] (const die_object& cu_die) {
|
optional<cu_info> info;
|
||||||
|
walk_compilation_units([pc, &info] (const die_object& cu_die) {
|
||||||
Dwarf_Half offset_size = 0;
|
Dwarf_Half offset_size = 0;
|
||||||
Dwarf_Half dwversion = 0;
|
Dwarf_Half dwversion = 0;
|
||||||
dwarf_get_version_of_die(cu_die.get(), &dwversion, &offset_size);
|
dwarf_get_version_of_die(cu_die.get(), &dwversion, &offset_size);
|
||||||
@ -869,12 +870,13 @@ namespace libdwarf {
|
|||||||
to_ull(pc)
|
to_ull(pc)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
retrieve_line_info(cu_die, pc, frame); // no offset for line info
|
// resolve_pc(cu_die, dwversion, pc, frame, inlines);
|
||||||
retrieve_symbol(cu_die, pc, dwversion, frame, inlines);
|
info = cu_info{maybe_owned_die_object::owned(cu_die.clone()), dwversion};
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
return info;
|
||||||
} else {
|
} else {
|
||||||
lazy_generate_cu_cache();
|
lazy_generate_cu_cache();
|
||||||
// look up the cu
|
// look up the cu
|
||||||
@ -890,14 +892,33 @@ namespace libdwarf {
|
|||||||
if(vec_it != cu_cache.end()) {
|
if(vec_it != cu_cache.end()) {
|
||||||
//vec_it->die.print();
|
//vec_it->die.print();
|
||||||
if(vec_it->die.pc_in_die(vec_it->dwversion, pc)) {
|
if(vec_it->die.pc_in_die(vec_it->dwversion, pc)) {
|
||||||
retrieve_line_info(vec_it->die, pc, frame); // no offset for line info
|
// resolve_pc(vec_it->die, vec_it->dwversion, pc, frame, inlines);
|
||||||
retrieve_symbol(vec_it->die, pc, vec_it->dwversion, frame, inlines);
|
return cu_info{maybe_owned_die_object::ref(vec_it->die), vec_it->dwversion};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// I've had this happen for _start, where there is a cached CU for the object but _start is outside
|
// I've had this happen for _start, where there is a cached CU for the object but _start is outside
|
||||||
// of the CU's PC range
|
// of the CU's PC range
|
||||||
// ASSERT(cu_cache.size() == 0, "Vec should be empty?");
|
// ASSERT(cu_cache.size() == 0, "Vec should be empty?");
|
||||||
}
|
}
|
||||||
|
return nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CPPTRACE_FORCE_NO_INLINE_FOR_PROFILING
|
||||||
|
void resolve_pc(
|
||||||
|
Dwarf_Addr pc,
|
||||||
|
stacktrace_frame& frame,
|
||||||
|
std::vector<stacktrace_frame>& inlines
|
||||||
|
) {
|
||||||
|
if(dump_dwarf) {
|
||||||
|
std::fprintf(stderr, "%s\n", object_path.c_str());
|
||||||
|
std::fprintf(stderr, "%llx\n", to_ull(pc));
|
||||||
|
}
|
||||||
|
optional<cu_info> cu = lookup_cu(pc);
|
||||||
|
if(cu) {
|
||||||
|
const auto& cu_die = cu.unwrap().cu_die.get();
|
||||||
|
retrieve_line_info(cu_die, pc, frame);
|
||||||
|
retrieve_symbol(cu_die, pc, cu.unwrap().dwversion, frame, inlines);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -931,7 +952,7 @@ namespace libdwarf {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
std::vector<stacktrace_frame> inlines;
|
std::vector<stacktrace_frame> inlines;
|
||||||
lookup_pc(
|
resolve_pc(
|
||||||
frame_info.object_address,
|
frame_info.object_address,
|
||||||
frame,
|
frame,
|
||||||
inlines
|
inlines
|
||||||
|
|||||||
@ -491,6 +491,29 @@ namespace libdwarf {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class maybe_owned_die_object {
|
||||||
|
// Hacky... I wish std::variant existed.
|
||||||
|
optional<die_object> owned_die;
|
||||||
|
optional<const die_object*> ref_die;
|
||||||
|
maybe_owned_die_object(die_object&& die) : owned_die(std::move(die)) {}
|
||||||
|
maybe_owned_die_object(const die_object& die) : ref_die(&die) {}
|
||||||
|
public:
|
||||||
|
static maybe_owned_die_object owned(die_object&& die) {
|
||||||
|
return maybe_owned_die_object{std::move(die)};
|
||||||
|
}
|
||||||
|
static maybe_owned_die_object ref(const die_object& die) {
|
||||||
|
return maybe_owned_die_object{die};
|
||||||
|
}
|
||||||
|
const die_object& get() {
|
||||||
|
ASSERT(owned_die || ref_die, "Mal-formed maybe_owned_die_object");
|
||||||
|
if(owned_die) {
|
||||||
|
return owned_die.unwrap();
|
||||||
|
} else {
|
||||||
|
return *ref_die.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user