diff options
Diffstat (limited to 'sal')
-rw-r--r-- | sal/osl/unx/backtraceapi.cxx | 30 | ||||
-rw-r--r-- | sal/osl/w32/backtrace.cxx | 51 | ||||
-rw-r--r-- | sal/util/sal.map | 6 |
3 files changed, 87 insertions, 0 deletions
diff --git a/sal/osl/unx/backtraceapi.cxx b/sal/osl/unx/backtraceapi.cxx index 91be8d5d40c4..4838474be36c 100644 --- a/sal/osl/unx/backtraceapi.cxx +++ b/sal/osl/unx/backtraceapi.cxx @@ -18,6 +18,7 @@ #include <rtl/ustrbuf.hxx> #include <rtl/ustring.hxx> #include <sal/types.h> +#include <sal/backtrace.hxx> #include "backtrace.h" #include "backtraceasstring.hxx" @@ -58,4 +59,33 @@ OUString osl::detail::backtraceAsString(sal_uInt32 maxDepth) { return b3.makeStringAndClear(); } +std::unique_ptr<BacktraceState> sal_backtrace_get(sal_uInt32 maxDepth) +{ + assert(maxDepth != 0); + auto const maxInt = static_cast<unsigned int>( + std::numeric_limits<int>::max()); + if (maxDepth > maxInt) { + maxDepth = static_cast<sal_uInt32>(maxInt); + } + auto b1 = new void *[maxDepth]; + int n = backtrace(b1, static_cast<int>(maxDepth)); + return std::unique_ptr<BacktraceState>(new BacktraceState{ b1, n }); +} + +OUString sal_backtrace_to_string(BacktraceState* backtraceState) +{ + FreeGuard b2(backtrace_symbols(backtraceState->buffer, backtraceState->nDepth)); + if (b2.buffer == nullptr) { + return OUString(); + } + OUStringBuffer b3; + for (int i = 0; i != backtraceState->nDepth; ++i) { + if (i != 0) { + b3.append("\n"); + } + b3.append(o3tl::runtimeToOUString(b2.buffer[i])); + } + return b3.makeStringAndClear(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/osl/w32/backtrace.cxx b/sal/osl/w32/backtrace.cxx index a8a4cf445e9f..230adca4a2f8 100644 --- a/sal/osl/w32/backtrace.cxx +++ b/sal/osl/w32/backtrace.cxx @@ -19,6 +19,7 @@ #include <DbgHelp.h> #include <rtl/ustrbuf.hxx> +#include <sal/backtrace.hxx> #include "backtraceasstring.hxx" @@ -64,4 +65,54 @@ OUString osl::detail::backtraceAsString(sal_uInt32 maxDepth) return aBuf.makeStringAndClear(); } +std::unique_ptr<BacktraceState> sal_backtrace_get(sal_uInt32 maxDepth) +{ + assert(maxDepth != 0); + auto const maxUlong = std::numeric_limits<ULONG>::max(); + if (maxDepth > maxUlong) { + maxDepth = static_cast<sal_uInt32>(maxUlong); + } + + HANDLE hProcess = GetCurrentProcess(); + SymInitialize( hProcess, nullptr, true ); + + auto pStack = new void *[maxDepth]; + // https://msdn.microsoft.com/en-us/library/windows/desktop/bb204633.aspx + // "CaptureStackBackTrace function" claims that you "can capture up to + // MAXUSHORT frames", and on Windows Server 2003 and Windows XP it even + // "must be less than 63", but assume that a too large input value is + // clamped internally, instead of resulting in an error: + int nFrames = CaptureStackBackTrace( 0, static_cast<ULONG>(maxDepth), pStack, nullptr ); + + return std::unique_ptr<BacktraceState>(new BacktraceState{ pStack, nFrames }); +} + +OUString sal_backtrace_to_string(BacktraceState* backtraceState) +{ + OUStringBuffer aBuf; + + SYMBOL_INFO * pSymbol; + pSymbol = static_cast<SYMBOL_INFO *>(calloc( sizeof( SYMBOL_INFO ) + 1024 * sizeof( char ), 1 )); + pSymbol->MaxNameLen = 1024 - 1; + pSymbol->SizeOfStruct = sizeof( SYMBOL_INFO ); + HANDLE hProcess = GetCurrentProcess(); + + auto nFrames = backtraceState->nDepth; + for( int i = 0; i < nFrames; i++ ) + { + SymFromAddr( hProcess, reinterpret_cast<DWORD64>(backtraceState->buffer[ i ]), nullptr, pSymbol ); + aBuf.append( (sal_Int32)(nFrames - i - 1) ); + aBuf.append( ": " ); + aBuf.appendAscii( pSymbol->Name ); + aBuf.append( " - 0x" ); + aBuf.append( (sal_Int64)pSymbol->Address, 16 ); + aBuf.append( "\n" ); + } + + free( pSymbol ); + + return aBuf.makeStringAndClear(); +} + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/util/sal.map b/sal/util/sal.map index b04487e4d548..e9195a1434f8 100644 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -733,6 +733,12 @@ PRIVATE_1.3 { # LibreOffice 5.4 sal_detail_log_report; } PRIVATE_1.2; +PRIVATE_1.4 { # LibreOffice 6.0 + global: + _Z17sal_backtrace_getj; + _Z23sal_backtrace_to_stringP14BacktraceState; +} PRIVATE_1.3; + PRIVATE_textenc.1 { # LibreOffice 3.6 global: _ZN3sal6detail7textenc20convertCharToUnicode*; |