include/sal/log.hxx | 50 ++++++++++++++++++------------------------ sal/inc/backtraceasstring.hxx | 3 +- sal/osl/all/log.cxx | 29 +++++------------------- sal/osl/unx/backtraceapi.cxx | 17 ++++++++------ sal/osl/w32/backtrace.cxx | 23 +++++++++++++++---- sal/util/sal.map | 1 6 files changed, 59 insertions(+), 64 deletions(-)
New commits: commit b6a69585b00867005820c1dd94e10e0e6b545e2a Author: Stephan Bergmann <[email protected]> Date: Thu Feb 9 13:19:11 2017 +0100 Fold sal_detail_log_backtrace into sal_detail_log ...the latter is LO-privately exported from sal, so it should be OK to add one more parameter to it. Change-Id: If6bf3458433aac2cc8b4e0cbd1602306051a777b Reviewed-on: https://gerrit.libreoffice.org/34080 Tested-by: Jenkins <[email protected]> Reviewed-by: Stephan Bergmann <[email protected]> diff --git a/include/sal/log.hxx b/include/sal/log.hxx index b383fd0..a21f80b 100644 --- a/include/sal/log.hxx +++ b/include/sal/log.hxx @@ -28,20 +28,16 @@ extern "C" SAL_DLLPUBLIC void SAL_CALL sal_detail_log( enum sal_detail_LogLevel level, char const * area, char const * where, - char const * message); - -extern "C" SAL_DLLPUBLIC void SAL_CALL sal_detail_log_backtrace( - enum sal_detail_LogLevel level, char const * area, char const * where, - char const * message, int maxNoStackFramesToDisplay); + char const * message, sal_uInt32 backtraceDepth); extern "C" SAL_DLLPUBLIC int SAL_CALL sal_detail_log_report( enum sal_detail_LogLevel level, char const * area); namespace sal { namespace detail { -inline void SAL_CALL log( +inline void log( sal_detail_LogLevel level, char const * area, char const * where, - std::ostringstream const & stream) + std::ostringstream const & stream, sal_uInt32 backtraceDepth) { // An alternative would be to have sal_detail_log take a std::ostringstream // pointer (via a C void pointer); the advantage would be smaller client @@ -51,15 +47,7 @@ inline void SAL_CALL log( // on the C++ ABI; as a compromise, the ".str().c_str()" part has been moved // to this inline function so that it is potentially only emitted once per // dynamic library: - sal_detail_log(level, area, where, stream.str().c_str()); -} - -inline void SAL_CALL log_backtrace( - sal_detail_LogLevel level, char const * area, char const * where, - std::ostringstream const & stream, int maxNoStackFramesToDisplay) -{ - sal_detail_log_backtrace( - level, area, where, stream.str().c_str(), maxNoStackFramesToDisplay); + sal_detail_log(level, area, where, stream.str().c_str(), backtraceDepth); } // Special handling of the common case where the message consists of just a @@ -134,12 +122,13 @@ inline char const * unwrapStream(SAL_UNUSED_PARAMETER StreamIgnore const &) { ::sal_detail_log( \ (level), (area), (where), \ ::sal::detail::unwrapStream( \ - ::sal::detail::StreamStart() << stream)); \ + ::sal::detail::StreamStart() << stream), \ + 0); \ } else { \ ::std::ostringstream sal_detail_stream; \ sal_detail_stream << stream; \ ::sal::detail::log( \ - (level), (area), (where), sal_detail_stream); \ + (level), (area), (where), sal_detail_stream, 0); \ } \ } \ } while (false) @@ -351,28 +340,33 @@ inline char const * unwrapStream(SAL_UNUSED_PARAMETER StreamIgnore const &) { SAL_LOG_TRUE, ::SAL_DETAIL_LOG_LEVEL_DEBUG, NULL, NULL, stream) /** - Produce temporary debugging output from stream along with a - stack trace of the calling location. This macro is meant to - be used only while working on code and should never exist - in production code. + Produce temporary debugging output from stream along with a backtrace of the + calling location. + + This macro is meant to be used only while working on code and should never + exist in production code. + + @param backtraceDepth a sal_uInt32 value indicating the maximum backtrace + depth; zero means no backtrace See @ref sal_log "basic logging functionality" for details. */ -#define SAL_DEBUG_BACKTRACE(stream, maxNoStackFramesToDisplay) \ +#define SAL_DEBUG_BACKTRACE(stream, backtraceDepth) \ do { \ - if (sizeof ::sal::detail::getResult(::sal::detail::StreamStart() << stream) == 1) \ + if (sizeof ::sal::detail::getResult( \ + ::sal::detail::StreamStart() << stream) == 1) \ { \ - ::sal_detail_log_backtrace( \ + ::sal_detail_log( \ ::SAL_DETAIL_LOG_LEVEL_DEBUG, NULL, NULL, \ ::sal::detail::unwrapStream( \ ::sal::detail::StreamStart() << stream), \ - maxNoStackFramesToDisplay); \ + backtraceDepth); \ } else { \ ::std::ostringstream sal_detail_stream; \ sal_detail_stream << stream; \ - ::sal::detail::log_backtrace( \ + ::sal::detail::log( \ ::SAL_DETAIL_LOG_LEVEL_DEBUG, NULL, NULL, sal_detail_stream, \ - maxNoStackFramesToDisplay); \ + backtraceDepth); \ } \ } while (false) diff --git a/sal/inc/backtraceasstring.hxx b/sal/inc/backtraceasstring.hxx index d15065a..cd9ce49 100644 --- a/sal/inc/backtraceasstring.hxx +++ b/sal/inc/backtraceasstring.hxx @@ -13,11 +13,12 @@ #include <sal/config.h> #include <rtl/ustring.hxx> +#include <sal/types.h> namespace osl { namespace detail { /// Build a debugging backtrace from current PC location. -OUString backtraceAsString(int maxNoStackFramesToDisplay); +OUString backtraceAsString(sal_uInt32 maxDepth); } } diff --git a/sal/osl/all/log.cxx b/sal/osl/all/log.cxx index 7a6c307..774e7e8 100644 --- a/sal/osl/all/log.cxx +++ b/sal/osl/all/log.cxx @@ -192,7 +192,7 @@ bool isDebug(sal_detail_LogLevel level) { void log( sal_detail_LogLevel level, char const * area, char const * where, - char const * message) + char const * message, sal_uInt32 backtraceDepth) { std::ostringstream s; #if !defined ANDROID @@ -218,6 +218,9 @@ void log( } s << message; + if (backtraceDepth != 0) { + s << " at:\n" << osl::detail::backtraceAsString(backtraceDepth); + } s << '\n'; #if defined ANDROID @@ -273,32 +276,14 @@ void log( #endif } -void log_backtrace( - sal_detail_LogLevel level, char const * area, char const * where, - char const * message, int maxNoStackFramesToDisplay) -{ - OUString buff = OUString::createFromAscii(message) + " at:\n" - + osl::detail::backtraceAsString(maxNoStackFramesToDisplay); - log(level, area, where, buff.toUtf8().getStr()); -} - } void sal_detail_log( sal_detail_LogLevel level, char const * area, char const * where, - char const * message) -{ - if (sal_detail_log_report(level, area)) { - log(level, area, where, message); - } -} - -void sal_detail_log_backtrace( - sal_detail_LogLevel level, char const * area, char const * where, - char const * message, int maxNoStackFramesToDisplay) + char const * message, sal_uInt32 backtraceDepth) { if (sal_detail_log_report(level, area)) { - log_backtrace(level, area, where, message, maxNoStackFramesToDisplay); + log(level, area, where, message, backtraceDepth); } } @@ -317,7 +302,7 @@ void sal_detail_logFormat( } else if (n >= len) { std::strcpy(buf + len - 1, "..."); } - log(level, area, where, buf); + log(level, area, where, buf, 0); va_end(args); } } diff --git a/sal/osl/unx/backtraceapi.cxx b/sal/osl/unx/backtraceapi.cxx index 267a331..91be8d5 100644 --- a/sal/osl/unx/backtraceapi.cxx +++ b/sal/osl/unx/backtraceapi.cxx @@ -11,11 +11,13 @@ #include <cassert> #include <cstdlib> +#include <limits> #include <memory> #include <o3tl/runtimetooustring.hxx> #include <rtl/ustrbuf.hxx> #include <rtl/ustring.hxx> +#include <sal/types.h> #include "backtrace.h" #include "backtraceasstring.hxx" @@ -32,14 +34,15 @@ struct FreeGuard { } -OUString osl::detail::backtraceAsString(int maxNoStackFramesToDisplay) -{ - assert(maxNoStackFramesToDisplay >= 0); - if (maxNoStackFramesToDisplay == 0) { - return OUString(); +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::unique_ptr<void *[]>(new void *[maxNoStackFramesToDisplay]); - int n = backtrace(b1.get(), maxNoStackFramesToDisplay); + auto b1 = std::unique_ptr<void *[]>(new void *[maxDepth]); + int n = backtrace(b1.get(), static_cast<int>(maxDepth)); FreeGuard b2(backtrace_symbols(b1.get(), n)); b1.reset(); if (b2.buffer == nullptr) { diff --git a/sal/osl/w32/backtrace.cxx b/sal/osl/w32/backtrace.cxx index 78d9e0a..b559c5e 100644 --- a/sal/osl/w32/backtrace.cxx +++ b/sal/osl/w32/backtrace.cxx @@ -9,7 +9,8 @@ #include <sal/config.h> -#include "backtraceasstring.hxx" +#include <limits> +#include <memory> #include <windows.h> #include <process.h> @@ -18,17 +19,29 @@ #include <DbgHelp.h> #include <rtl/ustrbuf.hxx> -#include <memory> -OUString osl::detail::backtraceAsString(int maxNoStackFramesToDisplay) +#include "backtraceasstring.hxx" + +OUString osl::detail::backtraceAsString(sal_uInt32 maxDepth) { + assert(maxDepth != 0); + auto const maxUlong = std::numeric_limits<ULONG>::max(); + if (maxDepth > maxUlong) { + maxDepth = static_cast<sal_uInt32>(maxUlong); + } + OUStringBuffer aBuf; HANDLE hProcess = GetCurrentProcess(); SymInitialize( hProcess, nullptr, true ); - std::unique_ptr<void*[]> aStack(new void*[ maxNoStackFramesToDisplay ]); - sal_uInt32 nFrames = CaptureStackBackTrace( 0, maxNoStackFramesToDisplay, aStack.get(), nullptr ); + std::unique_ptr<void*[]> aStack(new void*[ maxDepth ]); + // <https://msdn.microsoft.com/en-us/library/windows/desktop/ + // bb204633(v=vs.85).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 )); diff --git a/sal/util/sal.map b/sal/util/sal.map index b99d524..b04487e 100644 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -730,7 +730,6 @@ PRIVATE_1.2 { # LibreOffice 3.5 PRIVATE_1.3 { # LibreOffice 5.4 global: - sal_detail_log_backtrace; sal_detail_log_report; } PRIVATE_1.2; _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
