diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2021-09-03 12:20:56 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2021-09-06 14:40:50 +0200 |
commit | 1d021c87208c44b4943e4260ae58fb2478851d47 (patch) | |
tree | 57cb98c3b486d96f525ed5eb3c15d8714575e059 /sal/osl | |
parent | 9aa2fcb408334f48b9ba3a7525b4f20f8e0f19e9 (diff) |
also cache addr2line results
Change-Id: Ib4351ba7a585ada3887f1cbeb5d676733250598b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121585
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'sal/osl')
-rw-r--r-- | sal/osl/unx/backtraceapi.cxx | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/sal/osl/unx/backtraceapi.cxx b/sal/osl/unx/backtraceapi.cxx index e24a9150c91d..8e55cc338020 100644 --- a/sal/osl/unx/backtraceapi.cxx +++ b/sal/osl/unx/backtraceapi.cxx @@ -52,6 +52,8 @@ std::unique_ptr<sal::BacktraceState> sal::backtrace_get(sal_uInt32 maxDepth) #include <vector> #include <osl/process.h> #include <rtl/strbuf.hxx> +#include <osl/mutex.hxx> +#include <o3tl/lru_map.hxx> #include "file_url.hxx" namespace @@ -59,11 +61,16 @@ namespace struct FrameData { const char* file = nullptr; + void* addr; ptrdiff_t offset; OString info; bool handled = false; }; +typedef o3tl::lru_map<void*, OString> FrameCache; +osl::Mutex frameCacheMutex; +FrameCache frameCache( 256 ); + void process_file_addr2line( const char* file, std::vector<FrameData>& frameData ) { OUString binary("addr2line"); @@ -77,7 +84,7 @@ void process_file_addr2line( const char* file, std::vector<FrameData>& frameData args.push_back( arg2.pData ); for( FrameData& frame : frameData ) { - if( strcmp( file, frame.file ) == 0 ) + if( frame.file != nullptr && strcmp( file, frame.file ) == 0 ) { addrs.push_back("0x" + OUString::number(frame.offset, 16)); args.push_back(addrs.back().pData); @@ -144,7 +151,7 @@ void process_file_addr2line( const char* file, std::vector<FrameData>& frameData size_t linesPos = 0; for( FrameData& frame : frameData ) { - if( strcmp( file, frame.file ) == 0 ) + if( frame.file != nullptr && strcmp( file, frame.file ) == 0 ) { // There should be two lines, first function name and second source file information. // If each of them starts with ??, it is invalid/unknown. @@ -157,6 +164,8 @@ void process_file_addr2line( const char* file, std::vector<FrameData>& frameData frame.info = function + " in " + file; else frame.info = function + " at " + source; + osl::MutexGuard guard(frameCacheMutex); + frameCache.insert( { frame.addr, frame.info } ); } } } @@ -174,11 +183,20 @@ OUString sal::backtrace_to_string(BacktraceState* backtraceState) { Dl_info dli; void* addr = backtraceState->buffer[i]; - if (dladdr(addr, &dli) != 0) + osl::ClearableMutexGuard guard(frameCacheMutex); + auto it = frameCache.find(addr); + guard.clear(); + if( it != frameCache.end()) + { + frameData[ i ].info = it->second; + frameData[ i ].handled = true; + } + else if (dladdr(addr, &dli) != 0) { if (dli.dli_fname && dli.dli_fbase) { frameData[ i ].file = dli.dli_fname; + frameData[ i ].addr = addr; frameData[ i ].offset = reinterpret_cast<ptrdiff_t>(addr) - reinterpret_cast<ptrdiff_t>(dli.dli_fbase); } } |