Add cache mode config
This commit is contained in:
parent
93dde93802
commit
d84a3167d9
17
README.md
17
README.md
@ -224,10 +224,27 @@ The library makes an attempt to fail silently and continue during trace generati
|
||||
`cpptrace::absorb_trace_exceptions` can be used to configure whether these exceptions are absorbed silently internally
|
||||
or wether they're rethrown to the caller.
|
||||
|
||||
`cpptrace::experimental::set_cache_mode` can be used to control time-memory tradeoffs within the library. By default
|
||||
speed is prioritized. If using this function, set the cache mode at the very start of your program before any traces are
|
||||
performed.
|
||||
|
||||
```cpp
|
||||
namespace cpptrace {
|
||||
std::string demangle(const std::string& name);
|
||||
void absorb_trace_exceptions(bool absorb);
|
||||
|
||||
enum class cache_mode {
|
||||
// Only minimal lookup tables
|
||||
prioritize_memory,
|
||||
// Build lookup tables but don't keep them around between trace calls
|
||||
hybrid,
|
||||
// Build lookup tables as needed
|
||||
prioritize_speed
|
||||
};
|
||||
|
||||
namespace experimental {
|
||||
void set_cache_mode(cache_mode mode);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -130,8 +130,22 @@ namespace cpptrace {
|
||||
CPPTRACE_API std::string demangle(const std::string& name);
|
||||
CPPTRACE_API void absorb_trace_exceptions(bool absorb);
|
||||
|
||||
enum class cache_mode {
|
||||
// Only minimal lookup tables
|
||||
prioritize_memory,
|
||||
// Build lookup tables but don't keep them around between trace calls
|
||||
hybrid,
|
||||
// Build lookup tables as needed
|
||||
prioritize_speed
|
||||
};
|
||||
|
||||
namespace experimental {
|
||||
CPPTRACE_API void set_cache_mode(cache_mode mode);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
CPPTRACE_API bool should_absorb_trace_exceptions();
|
||||
CPPTRACE_API enum cache_mode get_cache_mode();
|
||||
}
|
||||
|
||||
class exception : public std::exception {
|
||||
|
||||
@ -26,10 +26,6 @@
|
||||
#define CYAN ESC "36m"
|
||||
|
||||
namespace cpptrace {
|
||||
namespace detail {
|
||||
std::atomic_bool absorb_trace_exceptions(true);
|
||||
}
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
||||
raw_trace raw_trace::current(std::uint_least32_t skip) {
|
||||
return generate_raw_trace(skip + 1);
|
||||
@ -316,13 +312,28 @@ namespace cpptrace {
|
||||
return detail::demangle(name);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
std::atomic_bool absorb_trace_exceptions(true);
|
||||
std::atomic<enum cache_mode> cache_mode(cache_mode::prioritize_speed);
|
||||
}
|
||||
|
||||
CPPTRACE_API void absorb_trace_exceptions(bool absorb) {
|
||||
detail::absorb_trace_exceptions = absorb;
|
||||
}
|
||||
|
||||
namespace experimental {
|
||||
CPPTRACE_API void set_cache_mode(cache_mode mode) {
|
||||
detail::cache_mode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
CPPTRACE_API bool should_absorb_trace_exceptions() {
|
||||
return detail::absorb_trace_exceptions;
|
||||
return absorb_trace_exceptions;
|
||||
}
|
||||
|
||||
CPPTRACE_API enum cache_mode get_cache_mode() {
|
||||
return cache_mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -398,7 +398,13 @@ namespace dbghelp {
|
||||
// TODO: When does this need to be called? Can it be moved to the symbolizer?
|
||||
SymSetOptions(SYMOPT_ALLOW_ABSOLUTE_SYMBOLS);
|
||||
HANDLE proc = GetCurrentProcess();
|
||||
if(get_cache_mode() == cache_mode::prioritize_speed) {
|
||||
get_syminit_manager().init(proc);
|
||||
} else {
|
||||
if(!SymInitialize(proc, NULL, TRUE)) {
|
||||
throw std::logic_error("Cpptrace SymInitialize failed");
|
||||
}
|
||||
}
|
||||
for(const auto frame : frames) {
|
||||
try {
|
||||
trace.push_back(resolve_frame(proc, frame));
|
||||
@ -409,6 +415,11 @@ namespace dbghelp {
|
||||
trace.push_back(null_frame);
|
||||
}
|
||||
}
|
||||
if(get_cache_mode() != cache_mode::prioritize_speed) {
|
||||
if(!SymCleanup(proc)) {
|
||||
throw std::logic_error("Cpptrace SymCleanup failed");
|
||||
}
|
||||
}
|
||||
return trace;
|
||||
}
|
||||
}
|
||||
|
||||
@ -575,7 +575,7 @@ namespace libdwarf {
|
||||
// Check for .debug_aranges for fast lookup
|
||||
wrap(dwarf_get_aranges, dbg, &aranges, &arange_count);
|
||||
}
|
||||
if(ok && !aranges) {
|
||||
if(ok && !aranges && get_cache_mode() != cache_mode::prioritize_memory) {
|
||||
walk_compilation_units([this] (const die_object& cu_die) {
|
||||
Dwarf_Half offset_size = 0;
|
||||
Dwarf_Half dwversion = 0;
|
||||
@ -839,9 +839,13 @@ namespace libdwarf {
|
||||
Dwarf_Half dwversion,
|
||||
stacktrace_frame& frame
|
||||
) {
|
||||
if(get_cache_mode() == cache_mode::prioritize_memory) {
|
||||
retrieve_symbol_walk(cu_die, pc, dwversion, frame);
|
||||
} else {
|
||||
auto off = cu_die.get_global_offset();
|
||||
auto it = subprograms_cache.find(off);
|
||||
if(it == subprograms_cache.end()) {
|
||||
// TODO: Refactor. Do the sort in the preprocess function and return the vec directly.
|
||||
std::vector<subprogram_entry> vec;
|
||||
preprocess_subprograms(cu_die, dwversion, vec);
|
||||
std::sort(vec.begin(), vec.end(), [] (const subprogram_entry& a, const subprogram_entry& b) {
|
||||
@ -874,6 +878,7 @@ namespace libdwarf {
|
||||
ASSERT(vec.size() == 0, "Vec should be empty?");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CPPTRACE_FORCE_NO_INLINE_FOR_PROFILING
|
||||
void retrieve_line_info(
|
||||
@ -998,7 +1003,7 @@ namespace libdwarf {
|
||||
retrieve_symbol(cu_die, pc, dwversion, frame);
|
||||
}
|
||||
} else {
|
||||
if(false) { // TODO: Proper condition
|
||||
if(get_cache_mode() == cache_mode::prioritize_memory) {
|
||||
// walk for the cu and go from there
|
||||
walk_compilation_units([this, pc, &frame] (const die_object& cu_die) {
|
||||
Dwarf_Half offset_size = 0;
|
||||
|
||||
@ -89,7 +89,13 @@ namespace detail {
|
||||
//
|
||||
HANDLE proc = GetCurrentProcess();
|
||||
HANDLE thread = GetCurrentThread();
|
||||
if(get_cache_mode() == cache_mode::prioritize_speed) {
|
||||
get_syminit_manager().init(proc);
|
||||
} else {
|
||||
if(!SymInitialize(proc, NULL, TRUE)) {
|
||||
throw std::logic_error("Cpptrace SymInitialize failed");
|
||||
}
|
||||
}
|
||||
while(trace.size() < max_depth) {
|
||||
if(
|
||||
!StackWalk64(
|
||||
@ -122,6 +128,11 @@ namespace detail {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(get_cache_mode() != cache_mode::prioritize_speed) {
|
||||
if(!SymCleanup(proc)) {
|
||||
throw std::logic_error("Cpptrace SymCleanup failed");
|
||||
}
|
||||
}
|
||||
return trace;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user