summaryrefslogtreecommitdiff
path: root/sal/osl/w32
diff options
context:
space:
mode:
Diffstat (limited to 'sal/osl/w32')
-rw-r--r--sal/osl/w32/backtrace.cxx54
1 files changed, 12 insertions, 42 deletions
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 );