Kaydet (Commit) b6a69585 authored tarafından Stephan Bergmann's avatar Stephan Bergmann

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/34080Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarStephan Bergmann <sbergman@redhat.com>
üst 6851074c
......@@ -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)
......
......@@ -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);
} }
......
......@@ -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);
}
}
......
......@@ -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) {
......
......@@ -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 ));
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment