summaryrefslogtreecommitdiff
path: root/indra/llcommon/llexception.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/llexception.cpp')
-rw-r--r--indra/llcommon/llexception.cpp50
1 files changed, 42 insertions, 8 deletions
diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp
index c0154a569f..74b33f1e3b 100644
--- a/indra/llcommon/llexception.cpp
+++ b/indra/llcommon/llexception.cpp
@@ -15,7 +15,12 @@
#include "llexception.h"
// STL headers
// std headers
+#include <iomanip>
+#include <sstream>
#include <typeinfo>
+#if LL_WINDOWS
+#include <excpt.h>
+#endif // LL_WINDOWS
// external library headers
#include <boost/exception/diagnostic_information.hpp>
#include <boost/exception/error_info.hpp>
@@ -29,7 +34,6 @@
// On Windows, header-only implementation causes macro collisions -- use
// prebuilt library
#define BOOST_STACKTRACE_LINK
-#include <excpt.h>
#endif // LL_WINDOWS
#include <boost/stacktrace.hpp>
@@ -94,15 +98,34 @@ void annotate_exception_(boost::exception& exc)
// For windows SEH exception handling we sometimes need a filter that will
// separate C++ exceptions from C SEH exceptions
-static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
+static constexpr U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
+static constexpr U32 STATUS_STACK_FULL = 0xC00000FD;
-U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
+U32 ll_seh_filter(
+ std::string& stacktrace,
+ std::function<U32(U32, struct _EXCEPTION_POINTERS*)> filter,
+ U32 code,
+ struct _EXCEPTION_POINTERS* exception_infop)
{
- const auto stack = to_string(boost::stacktrace::stacktrace());
- LL_WARNS() << "SEH Exception handled (that probably shouldn't be): Code " << code
- << "\n Stack trace: \n"
- << stack << LL_ENDL;
+ // By the time the handler gets control, the stack has been unwound,
+ // so report the stack trace now at filter() time.
+ // Even though stack overflow is a problem we would very much like to
+ // diagnose, calling another function when the stack is already blown only
+ // terminates us faster.
+ if (code == STATUS_STACK_FULL)
+ {
+ stacktrace = "(stack overflow, no traceback)";
+ }
+ else
+ {
+ stacktrace = boost::stacktrace::stacktrace().to_string();
+ }
+
+ return filter(code, exception_infop);
+}
+U32 seh_filter(U32 code, struct _EXCEPTION_POINTERS*)
+{
if (code == STATUS_MSC_EXCEPTION)
{
// C++ exception, go on
@@ -110,9 +133,20 @@ U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
}
else
{
- // handle it
+ // This is a non-C++ exception, e.g. hardware check.
return EXCEPTION_EXECUTE_HANDLER;
}
}
+void seh_rethrow(U32 code, const std::string& stacktrace)
+{
+ std::ostringstream out;
+ out << "Windows exception 0x" << std::hex << code;
+ if (! stacktrace.empty())
+ {
+ out << '\n' << stacktrace;
+ }
+ LLTHROW(Windows_SEH_exception(out.str()));
+}
+
#endif //LL_WINDOWS