summaryrefslogtreecommitdiff
path: root/sal
diff options
context:
space:
mode:
Diffstat (limited to 'sal')
-rw-r--r--sal/osl/unx/backtraceapi.cxx30
-rw-r--r--sal/osl/w32/backtrace.cxx51
-rw-r--r--sal/util/sal.map6
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*;