diff options
| author | Erik Kundiman <erik@megapahit.org> | 2025-06-03 16:20:27 +0800 | 
|---|---|---|
| committer | Erik Kundiman <erik@megapahit.org> | 2025-06-03 16:20:27 +0800 | 
| commit | 9bae19198fdc7bfb71f900cfe6c1982cb2a80e4f (patch) | |
| tree | 498aadebb88733f10bb0374eef5dee781d985339 | |
| parent | 08d4f307b0c2281f5aa4a11329c6c6e8c625e6ea (diff) | |
Revert "Fix up llexception.h's cross-platform SEH wrapper."
This reverts commit 5ed8df22cd59680a685c4ada7daa5555bf59d4fe.
| -rw-r--r-- | indra/llcommon/always_return.h | 16 | ||||
| -rw-r--r-- | indra/llcommon/llexception.cpp | 24 | ||||
| -rw-r--r-- | indra/llcommon/llexception.h | 104 | ||||
| -rw-r--r-- | indra/llwindow/llwindowwin32.cpp | 2 | ||||
| -rw-r--r-- | indra/test/test.cpp | 2 | 
5 files changed, 59 insertions, 89 deletions
diff --git a/indra/llcommon/always_return.h b/indra/llcommon/always_return.h index b99eb49096..a206471da5 100644 --- a/indra/llcommon/always_return.h +++ b/indra/llcommon/always_return.h @@ -79,22 +79,6 @@ namespace LL          DESIRED mDefault;      }; -    // specialize for AlwaysReturn<void> -    template <> -    struct AlwaysReturn<void> -    { -    public: -        AlwaysReturn() {} - -        // callable returns a type not convertible to DESIRED, return default -        template <typename CALLABLE, typename... ARGS> -        void operator()(CALLABLE&& callable, ARGS&&... args) -        { -            // discard whatever callable(args) returns -            std::forward<CALLABLE>(callable)(std::forward<ARGS>(args)...); -        } -    }; -      /**       * always_return<T>(some_function, some_args...) calls       * some_function(some_args...). It is guaranteed to return a value of type diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp index 107fdc2b2d..74b33f1e3b 100644 --- a/indra/llcommon/llexception.cpp +++ b/indra/llcommon/llexception.cpp @@ -101,36 +101,44 @@ void annotate_exception_(boost::exception& exc)  static constexpr U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific  static constexpr U32 STATUS_STACK_FULL    = 0xC00000FD; -void LL::seh::fill_stacktrace(std::string& stacktrace, U32 code) +U32 ll_seh_filter( +    std::string& stacktrace, +    std::function<U32(U32, struct _EXCEPTION_POINTERS*)> filter, +    U32 code, +    struct _EXCEPTION_POINTERS* exception_infop)  { -    // Sadly, despite its diagnostic importance, trying to capture a -    // stacktrace when the stack is already blown only terminates us faster. +    // 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 = to_string(boost::stacktrace::stacktrace()); +        stacktrace = boost::stacktrace::stacktrace().to_string();      } +     +    return filter(code, exception_infop);  } -U32 LL::seh::common_filter(U32 code, struct _EXCEPTION_POINTERS*) +U32 seh_filter(U32 code, struct _EXCEPTION_POINTERS*)  {      if (code == STATUS_MSC_EXCEPTION)      { -        // C++ exception, don't stop at this handler +        // C++ exception, go on          return EXCEPTION_CONTINUE_SEARCH;      }      else      {          // This is a non-C++ exception, e.g. hardware check. -        // Pass control into the handler block.          return EXCEPTION_EXECUTE_HANDLER;      }  } -void LL::seh::rethrow(U32 code, const std::string& stacktrace) +void seh_rethrow(U32 code, const std::string& stacktrace)  {      std::ostringstream out;      out << "Windows exception 0x" << std::hex << code; diff --git a/indra/llcommon/llexception.h b/indra/llcommon/llexception.h index f58a553eb3..3e50678b44 100644 --- a/indra/llcommon/llexception.h +++ b/indra/llcommon/llexception.h @@ -12,7 +12,6 @@  #if ! defined(LL_LLEXCEPTION_H)  #define LL_LLEXCEPTION_H -#include "always_return.h"  #include <stdexcept>  #include <boost/exception/exception.hpp>  #include <boost/throw_exception.hpp> @@ -107,111 +106,90 @@ void log_unhandled_exception_(const char*, int, const char*, const std::string&)  *   Structured Exception Handling  *****************************************************************************/  // this is used in platform-generic code -- define outside #if LL_WINDOWS -struct Windows_SEH_exception: public LLException +struct Windows_SEH_exception: public std::runtime_error  { -    Windows_SEH_exception(const std::string& what): LLException(what) {} +    Windows_SEH_exception(const std::string& what): std::runtime_error(what) {}  }; -namespace LL -{ -namespace seh -{ -  #if LL_WINDOWS //------------------------------------------------------------- -void fill_stacktrace(std::string& stacktrace, U32 code); - -// wrapper around caller's U32 filter(U32 code, struct _EXCEPTION_POINTERS*) -// filter function: capture a stacktrace, if possible, before forwarding the -// call to the caller's filter() function -template <typename FILTER> -U32 filter_(std::string& stacktrace, FILTER&& filter, -            U32 code, struct _EXCEPTION_POINTERS* exptrs) -{ -    // By the time the handler gets control, the stack has been unwound, -    // so report the stack trace now at filter() time. -    fill_stacktrace(stacktrace, code); -    return std::forward<FILTER>(filter)(code, exptrs); -} +#include <functional> +// triadic variant specifies try(), filter(U32, struct _EXCEPTION_POINTERS*), +// handler(U32, const std::string& stacktrace) +// stacktrace may or may not be available  template <typename TRYCODE, typename FILTER, typename HANDLER> -auto catcher_inner(std::string& stacktrace, -                   TRYCODE&& trycode, FILTER&& filter, HANDLER&& handler) +auto seh_catcher(TRYCODE&& trycode, FILTER&& filter, HANDLER&& handler)  { +    // don't try to construct a std::function at the moment of Structured Exception +    std::function<U32(U32, struct _EXCEPTION_POINTERS*)> +        filter_function(std::forward<FILTER>(filter)); +    std::string stacktrace;      __try      {          return std::forward<TRYCODE>(trycode)();      } -    __except (filter_(stacktrace, -                      std::forward<FILTER>(filter), -                      GetExceptionCode(), GetExceptionInformation())) +    __except (ll_seh_filter( +                  stacktrace, +                  filter_function, +                  GetExceptionCode(), +                  GetExceptionInformation()))      { -        return always_return<decltype(trycode())>( -            std::forward<HANDLER>(handler), GetExceptionCode(), stacktrace); +        return std::forward<HANDLER>(handler)(GetExceptionCode(), stacktrace);      }  } -// triadic variant specifies try(), filter(U32, struct _EXCEPTION_POINTERS*), -// handler(U32, const std::string& stacktrace) -// stacktrace may or may not be available -template <typename TRYCODE, typename FILTER, typename HANDLER> -auto catcher(TRYCODE&& trycode, FILTER&& filter, HANDLER&& handler) -{ -    // Construct and destroy this stacktrace string in the outer function -    // because we can't do either in the function with __try/__except. -    std::string stacktrace; -    return catcher_inner(stacktrace, -                         std::forward<TRYCODE>(trycode), -                         std::forward<FILTER>(filter), -                         std::forward<HANDLER>(handler)); -} - -// common_filter() handles the typical case in which we want our handler -// clause to handle only Structured Exceptions rather than explicitly-thrown -// C++ exceptions -U32 common_filter(U32 code, struct _EXCEPTION_POINTERS*); - -// dyadic variant specifies try(), handler(U32, stacktrace), assumes common_filter() +// dyadic variant specifies try(), handler(U32, stacktrace), assumes default filter  template <typename TRYCODE, typename HANDLER> -auto catcher(TRYCODE&& trycode, HANDLER&& handler) +auto seh_catcher(TRYCODE&& trycode, HANDLER&& handler)  { -    return catcher(std::forward<TRYCODE>(trycode), -                   common_filter, -                   std::forward<HANDLER>(handler)); +    return seh_catcher( +        std::forward<TRYCODE>(trycode), +        seh_filter, +        std::forward<HANDLER>(handler));  }  // monadic variant specifies try(), assumes default filter and handler  template <typename TRYCODE> -auto catcher(TRYCODE&& trycode) +auto seh_catcher(TRYCODE&& trycode)  { -    return catcher(std::forward<TRYCODE>(trycode), rethrow); +    return seh_catcher( +        std::forward<TRYCODE>(trycode), +        seh_filter, +        seh_rethrow);  } -[[noreturn]] void rethrow(U32 code, const std::string& stacktrace); +// SEH exception filtering for use in __try __except +// Separates C++ exceptions from C SEH exceptions +// Todo: might be good idea to do some kind of seh_to_msc_wrapper(function, ARGS&&); +U32 ll_seh_filter( +    std::string& stacktrace, +    std::function<U32(U32, struct _EXCEPTION_POINTERS*)> filter, +    U32 code, +    struct _EXCEPTION_POINTERS* exception_infop); +U32 seh_filter(U32 code, struct _EXCEPTION_POINTERS* exception_infop); +void seh_rethrow(U32 code, const std::string& stacktrace);  #else  // not LL_WINDOWS -----------------------------------------------------  template <typename TRYCODE, typename FILTER, typename HANDLER> -auto catcher(TRYCODE&& trycode, FILTER&&, HANDLER&&) +auto seh_catcher(TRYCODE&& trycode, FILTER&&, HANDLER&&)  {      return std::forward<TRYCODE>(trycode)();  }  template <typename TRYCODE, typename HANDLER> -auto catcher(TRYCODE&& trycode, HANDLER&&) +auto seh_catcher(TRYCODE&& trycode, HANDLER&&)  {      return std::forward<TRYCODE>(trycode)();  }  template <typename TRYCODE> -auto catcher(TRYCODE&& trycode) +auto seh_catcher(TRYCODE&& trycode)  {      return std::forward<TRYCODE>(trycode)();  }  #endif // not LL_WINDOWS ----------------------------------------------------- -} // namespace LL::seh -} // namespace LL -  #endif /* ! defined(LL_LLEXCEPTION_H) */ diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index a781e638ee..97bd789134 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -160,7 +160,7 @@ HGLRC SafeCreateContext(HDC &hdc)  GLuint SafeChoosePixelFormat(HDC &hdc, const PIXELFORMATDESCRIPTOR *ppfd)  { -    return LL::seh::catcher([hdc, ppfd]{ return ChoosePixelFormat(hdc, ppfd); }); +    return seh_catcher(ChoosePixelFormat(hdc, ppfd));  }  //static diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 6e280819df..536c252d97 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -638,7 +638,7 @@ int main(int argc, char **argv)      // a chained_callback subclass must be linked with previous      mycallback->link(); -    LL::seh::catcher( +    seh_catcher(          // __try          [test_group]          {  | 
