summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sal/osl/unx/backtraceapi.cxx23
-rw-r--r--sal/osl/w32/backtrace.cxx54
2 files changed, 14 insertions, 63 deletions
diff --git a/sal/osl/unx/backtraceapi.cxx b/sal/osl/unx/backtraceapi.cxx
index ae1670c30b92..93ca94da5ff2 100644
--- a/sal/osl/unx/backtraceapi.cxx
+++ b/sal/osl/unx/backtraceapi.cxx
@@ -36,27 +36,8 @@ struct FreeGuard {
}
OUString osl::detail::backtraceAsString(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 = std::make_unique<void *[]>(maxDepth);
- int n = backtrace(b1.get(), static_cast<int>(maxDepth));
- FreeGuard b2(backtrace_symbols(b1.get(), n));
- b1.reset();
- if (b2.buffer == nullptr) {
- return OUString();
- }
- OUStringBuffer b3;
- for (int i = 0; i != n; ++i) {
- if (i != 0) {
- b3.append("\n");
- }
- b3.append(o3tl::runtimeToOUString(b2.buffer[i]));
- }
- return b3.makeStringAndClear();
+ std::unique_ptr<sal::BacktraceState> backtrace = sal::backtrace_get( maxDepth );
+ return sal::backtrace_to_string( backtrace.get());
}
std::unique_ptr<sal::BacktraceState> sal::backtrace_get(sal_uInt32 maxDepth)
diff --git a/sal/osl/w32/backtrace.cxx b/sal/osl/w32/backtrace.cxx
index 9e31616eaaff..fab3c5043a60 100644
--- a/sal/osl/w32/backtrace.cxx
+++ b/sal/osl/w32/backtrace.cxx
@@ -37,42 +37,8 @@ template<typename T> T clampToULONG(T n) {
OUString osl::detail::backtraceAsString(sal_uInt32 maxDepth)
{
- assert(maxDepth != 0);
- maxDepth = clampToULONG(maxDepth);
-
- OUStringBuffer aBuf;
-
- HANDLE hProcess = GetCurrentProcess();
- SymInitialize( hProcess, nullptr, true );
-
- std::unique_ptr<void*[]> aStack(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:
- sal_uInt32 nFrames = CaptureStackBackTrace( 0, static_cast<ULONG>(maxDepth), aStack.get(), nullptr );
-
- SYMBOL_INFO * pSymbol;
- pSymbol = static_cast<SYMBOL_INFO *>(calloc( sizeof( SYMBOL_INFO ) + 1024 * sizeof( char ), 1 ));
- assert(pSymbol);
- pSymbol->MaxNameLen = 1024 - 1;
- pSymbol->SizeOfStruct = sizeof( SYMBOL_INFO );
-
- for( sal_uInt32 i = 0; i < nFrames; i++ )
- {
- SymFromAddr( hProcess, reinterpret_cast<DWORD64>(aStack[ i ]), nullptr, pSymbol );
- aBuf.append( static_cast<sal_Int32>(nFrames - i - 1) );
- aBuf.append( ": " );
- aBuf.appendAscii( pSymbol->Name );
- aBuf.append( " - 0x" );
- aBuf.append( static_cast<sal_Int64>(pSymbol->Address), 16 );
- aBuf.append( "\n" );
- }
-
- free( pSymbol );
-
- return aBuf.makeStringAndClear();
+ std::unique_ptr<sal::BacktraceState> backtrace = sal::backtrace_get( maxDepth );
+ return sal::backtrace_to_string( backtrace.get());
}
std::unique_ptr<sal::BacktraceState> sal::backtrace_get(sal_uInt32 maxDepth)
@@ -80,9 +46,6 @@ std::unique_ptr<sal::BacktraceState> sal::backtrace_get(sal_uInt32 maxDepth)
assert(maxDepth != 0);
maxDepth = clampToULONG(maxDepth);
- 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
@@ -96,16 +59,23 @@ std::unique_ptr<sal::BacktraceState> sal::backtrace_get(sal_uInt32 maxDepth)
OUString sal::backtrace_to_string(BacktraceState* backtraceState)
{
- OUStringBuffer aBuf;
-
+ HANDLE hProcess = GetCurrentProcess();
+ // https://docs.microsoft.com/en-us/windows/win32/api/dbghelp/nf-dbghelp-syminitialize
+ // says to not initialize more than once. This still leaks for some
+ // reason if called often enough.
+ static bool needsInit = true;
+ if( needsInit )
+ SymInitialize( hProcess, nullptr, true );
+ else
+ SymRefreshModuleList( hProcess );
SYMBOL_INFO * pSymbol;
pSymbol = static_cast<SYMBOL_INFO *>(calloc( sizeof( SYMBOL_INFO ) + 1024 * sizeof( char ), 1 ));
assert(pSymbol);
pSymbol->MaxNameLen = 1024 - 1;
pSymbol->SizeOfStruct = sizeof( SYMBOL_INFO );
- HANDLE hProcess = GetCurrentProcess();
auto nFrames = backtraceState->nDepth;
+ OUStringBuffer aBuf;
for( int i = 0; i < nFrames; i++ )
{
SymFromAddr( hProcess, reinterpret_cast<DWORD64>(backtraceState->buffer[ i ]), nullptr, pSymbol );