Setup global dwarf_resolver cache for dwarf resolving
This commit is contained in:
parent
e82f6e360f
commit
d4bc913607
@ -17,6 +17,7 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <libdwarf.h>
|
#include <libdwarf.h>
|
||||||
@ -199,6 +200,39 @@ namespace libdwarf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dwarf_resolver(const dwarf_resolver&) = delete;
|
||||||
|
dwarf_resolver& operator=(const dwarf_resolver&) = delete;
|
||||||
|
|
||||||
|
dwarf_resolver(dwarf_resolver&& other) :
|
||||||
|
obj_path(std::move(other.obj_path)),
|
||||||
|
dbg(other.dbg),
|
||||||
|
ok(other.ok),
|
||||||
|
aranges(other.aranges),
|
||||||
|
arange_count(other.arange_count),
|
||||||
|
line_contexts(std::move(other.line_contexts)),
|
||||||
|
subprograms_cache(std::move(other.subprograms_cache)),
|
||||||
|
cu_cache(std::move(other.cu_cache)),
|
||||||
|
tmp_object_path(std::move(other.tmp_object_path))
|
||||||
|
{
|
||||||
|
other.dbg = nullptr;
|
||||||
|
other.aranges = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
dwarf_resolver& operator=(dwarf_resolver&& other) {
|
||||||
|
obj_path = std::move(other.obj_path);
|
||||||
|
dbg = other.dbg;
|
||||||
|
ok = other.ok;
|
||||||
|
aranges = other.aranges;
|
||||||
|
arange_count = other.arange_count;
|
||||||
|
line_contexts = std::move(other.line_contexts);
|
||||||
|
subprograms_cache = std::move(other.subprograms_cache);
|
||||||
|
cu_cache = std::move(other.cu_cache);
|
||||||
|
tmp_object_path = std::move(other.tmp_object_path);
|
||||||
|
other.dbg = nullptr;
|
||||||
|
other.aranges = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
// walk all CU's in a dbg, callback is called on each die and should return true to
|
// walk all CU's in a dbg, callback is called on each die and should return true to
|
||||||
// continue traversal
|
// continue traversal
|
||||||
void walk_compilation_units(std::function<bool(const die_object&)> fn) {
|
void walk_compilation_units(std::function<bool(const die_object&)> fn) {
|
||||||
@ -633,19 +667,29 @@ namespace libdwarf {
|
|||||||
std::vector<stacktrace_frame> resolve_frames(const std::vector<object_frame>& frames) {
|
std::vector<stacktrace_frame> resolve_frames(const std::vector<object_frame>& frames) {
|
||||||
std::vector<stacktrace_frame> trace(frames.size(), null_frame);
|
std::vector<stacktrace_frame> trace(frames.size(), null_frame);
|
||||||
static std::mutex mutex;
|
static std::mutex mutex;
|
||||||
|
// cache resolvers since objects are likely to be traced more than once
|
||||||
|
static std::unordered_map<std::string, dwarf_resolver> resolver_map;
|
||||||
// Locking around all libdwarf interaction per https://github.com/davea42/libdwarf-code/discussions/184
|
// Locking around all libdwarf interaction per https://github.com/davea42/libdwarf-code/discussions/184
|
||||||
const std::lock_guard<std::mutex> lock(mutex);
|
const std::lock_guard<std::mutex> lock(mutex);
|
||||||
for(const auto& obj_entry : collate_frames(frames, trace)) {
|
for(const auto& obj_entry : collate_frames(frames, trace)) {
|
||||||
try {
|
try {
|
||||||
const auto& obj_name = obj_entry.first;
|
const auto& obj_name = obj_entry.first;
|
||||||
dwarf_resolver resolver(obj_name);
|
optional<dwarf_resolver> resolver_object;// = nullopt;
|
||||||
|
dwarf_resolver* resolver = nullptr;
|
||||||
|
auto it = resolver_map.find(obj_name);
|
||||||
|
if(it != resolver_map.end()) {
|
||||||
|
resolver = &it->second;
|
||||||
|
} else {
|
||||||
|
resolver_object = dwarf_resolver(obj_name);
|
||||||
|
resolver = &resolver_object.unwrap();
|
||||||
|
}
|
||||||
// If there's no debug information it'll mark itself as not ok
|
// If there's no debug information it'll mark itself as not ok
|
||||||
if(resolver.ok) {
|
if(resolver->ok) {
|
||||||
for(const auto& entry : obj_entry.second) {
|
for(const auto& entry : obj_entry.second) {
|
||||||
try {
|
try {
|
||||||
const auto& dlframe = entry.first.get();
|
const auto& dlframe = entry.first.get();
|
||||||
auto& frame = entry.second.get();
|
auto& frame = entry.second.get();
|
||||||
frame = resolver.resolve_frame(dlframe);
|
frame = resolver->resolve_frame(dlframe);
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
if(!should_absorb_trace_exceptions()) {
|
if(!should_absorb_trace_exceptions()) {
|
||||||
throw;
|
throw;
|
||||||
@ -653,6 +697,9 @@ namespace libdwarf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(resolver_object.has_value() && get_cache_mode() == cache_mode::prioritize_speed) {
|
||||||
|
resolver_map.insert({obj_name, std::move(resolver_object).unwrap()});
|
||||||
|
}
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
if(!should_absorb_trace_exceptions()) {
|
if(!should_absorb_trace_exceptions()) {
|
||||||
throw;
|
throw;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user