From 9ef702db1149b6961a4c9b158bf203007c0d3a92 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 18 Nov 2019 20:22:45 -0500 Subject: DRTVWR-476: Enrich LLExceptions thrown by LLTHROW() with stack trace. The LLTHROW() abstraction allows us to enrich the subject exception with a boost::stacktrace -- without having to propagate the boost/stacktrace.hpp header throughout the code base. To my delight, our existing use of boost::current_exception_diagnostic_information() already reports the newly added boost::stacktrace information -- we don't have to query it specifically! --- indra/llcommon/llexception.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'indra/llcommon/llexception.cpp') diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp index b32ec2c9c9..c0483e8927 100644 --- a/indra/llcommon/llexception.cpp +++ b/indra/llcommon/llexception.cpp @@ -18,10 +18,23 @@ #include // external library headers #include +#include +// On Mac, got: +// #error "Boost.Stacktrace requires `_Unwind_Backtrace` function. Define +// `_GNU_SOURCE` macro or `BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED` if +// _Unwind_Backtrace is available without `_GNU_SOURCE`." +#define BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED +#include // other Linden headers #include "llerror.h" #include "llerrorcontrol.h" +// used to attach and extract stacktrace information to/from boost::exception, +// see https://www.boost.org/doc/libs/release/doc/html/stacktrace/getting_started.html#stacktrace.getting_started.exceptions_with_stacktrace +// apparently the struct passed as the first template param needs no definition? +typedef boost::error_info + errinfo_stacktrace; + namespace { // used by crash_on_unhandled_exception_() and log_unhandled_exception_() void log_unhandled_exception_(LLError::ELevel level, @@ -53,3 +66,17 @@ void log_unhandled_exception_(const char* file, int line, const char* pretty_fun // routinely, but we DO expect to return from this function. log_unhandled_exception_(LLError::LEVEL_WARN, file, line, pretty_function, context); } + +void annotate_exception_(boost::exception& exc) +{ + // https://www.boost.org/doc/libs/release/libs/exception/doc/tutorial_transporting_data.html + // "Adding of Arbitrary Data to Active Exception Objects" + // Given a boost::exception&, we can add boost::error_info items to it + // without knowing its leaf type. + // The stacktrace constructor that lets us skip a level -- and why would + // we always include annotate_exception_()? -- also requires a max depth. + // For the nullary constructor, the stacktrace class declaration itself + // passes static_cast(-1), but that's kind of dubious. + // Anyway, which of us is really going to examine more than 100 frames? + exc << errinfo_stacktrace(boost::stacktrace::stacktrace(1, 100)); +} -- cgit v1.2.3 From 79f3bda1a5570041d0db4d12c8bdb7482d194437 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 11 Dec 2019 16:36:08 -0500 Subject: DRTVWR-476: On Windows, use prebuilt Boost.Stacktrace. --- indra/llcommon/llexception.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/llcommon/llexception.cpp') diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp index c0483e8927..5ce8958687 100644 --- a/indra/llcommon/llexception.cpp +++ b/indra/llcommon/llexception.cpp @@ -24,6 +24,11 @@ // `_GNU_SOURCE` macro or `BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED` if // _Unwind_Backtrace is available without `_GNU_SOURCE`." #define BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED +#if LL_WINDOWS +// On Windows, header-only implementation causes macro collisions -- use +// prebuilt library +#define BOOST_STACKTRACE_LINK +#endif // LL_WINDOWS #include // other Linden headers #include "llerror.h" -- cgit v1.2.3