diff options
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/CMakeLists.txt | 5 | ||||
-rw-r--r-- | indra/llcommon/always_return.h | 16 | ||||
-rw-r--r-- | indra/llcommon/llapr.cpp | 2 | ||||
-rw-r--r-- | indra/llcommon/llexception.cpp | 44 | ||||
-rw-r--r-- | indra/llcommon/llexception.h | 114 | ||||
-rw-r--r-- | indra/llcommon/llmemory.h | 2 | ||||
-rw-r--r-- | indra/llcommon/llwin32headers.h | 1 |
7 files changed, 22 insertions, 162 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index ac35bec368..6c1e1ef64a 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -303,7 +303,10 @@ if (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu) OR (${LIN target_include_directories(llcommon PUBLIC ${LIBS_PREBUILT_DIR}/include) endif () -target_compile_options(${PROJECT_NAME} PUBLIC -Wno-deprecated-declarations) +if (NOT WINDOWS) + target_compile_options(${PROJECT_NAME} PUBLIC -Wno-deprecated-declarations) +endif () + if (CMAKE_CXX_COMPILER_ID MATCHES GNU) set_source_files_properties( llapp.cpp 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/llapr.cpp b/indra/llcommon/llapr.cpp index 01763c49aa..04aba817f8 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -230,7 +230,7 @@ bool LLVolatileAPRPool::isFull() bool _ll_apr_warn_status(apr_status_t status, const char* file, int line) { if(APR_SUCCESS == status) return false; -#if !LL_LINUX +#if !LL_LINUX && !__FreeBSD__ char buf[MAX_STRING]; /* Flawfinder: ignore */ apr_strerror(status, buf, sizeof(buf)); LL_WARNS("APR") << "APR: " << file << ":" << line << " " << buf << LL_ENDL; diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp index 107fdc2b2d..c0154a569f 100644 --- a/indra/llcommon/llexception.cpp +++ b/indra/llcommon/llexception.cpp @@ -15,12 +15,7 @@ #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> @@ -34,6 +29,7 @@ // 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> @@ -98,47 +94,25 @@ 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 constexpr U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific -static constexpr U32 STATUS_STACK_FULL = 0xC00000FD; +static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific -void LL::seh::fill_stacktrace(std::string& stacktrace, U32 code) +U32 msc_exception_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. - if (code == STATUS_STACK_FULL) - { - stacktrace = "(stack overflow, no traceback)"; - } - else - { - stacktrace = to_string(boost::stacktrace::stacktrace()); - } -} + 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; -U32 LL::seh::common_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. + // handle it return EXCEPTION_EXECUTE_HANDLER; } } -void LL::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 diff --git a/indra/llcommon/llexception.h b/indra/llcommon/llexception.h index f58a553eb3..68e609444e 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> @@ -103,115 +102,14 @@ void crash_on_unhandled_exception_(const char*, int, const char*, const std::str log_unhandled_exception_(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, CONTEXT) 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 -{ - Windows_SEH_exception(const std::string& what): LLException(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); -} - -template <typename TRYCODE, typename FILTER, typename HANDLER> -auto catcher_inner(std::string& stacktrace, - TRYCODE&& trycode, FILTER&& filter, HANDLER&& handler) -{ - __try - { - return std::forward<TRYCODE>(trycode)(); - } - __except (filter_(stacktrace, - std::forward<FILTER>(filter), - GetExceptionCode(), GetExceptionInformation())) - { - return always_return<decltype(trycode())>( - 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() -template <typename TRYCODE, typename HANDLER> -auto catcher(TRYCODE&& trycode, HANDLER&& handler) -{ - return catcher(std::forward<TRYCODE>(trycode), - common_filter, - std::forward<HANDLER>(handler)); -} - -// monadic variant specifies try(), assumes default filter and handler -template <typename TRYCODE> -auto catcher(TRYCODE&& trycode) -{ - return catcher(std::forward<TRYCODE>(trycode), rethrow); -} - -[[noreturn]] void rethrow(U32 code, const std::string& stacktrace); - -#else // not LL_WINDOWS ----------------------------------------------------- - -template <typename TRYCODE, typename FILTER, typename HANDLER> -auto catcher(TRYCODE&& trycode, FILTER&&, HANDLER&&) -{ - return std::forward<TRYCODE>(trycode)(); -} - -template <typename TRYCODE, typename HANDLER> -auto catcher(TRYCODE&& trycode, HANDLER&&) -{ - return std::forward<TRYCODE>(trycode)(); -} - -template <typename TRYCODE> -auto catcher(TRYCODE&& trycode) -{ - return std::forward<TRYCODE>(trycode)(); -} +#if LL_WINDOWS -#endif // not LL_WINDOWS ----------------------------------------------------- +// 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 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop); -} // namespace LL::seh -} // namespace LL +#endif //LL_WINDOWS #endif /* ! defined(LL_LLEXCEPTION_H) */ diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 4a9359f8e2..d5802b9d95 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -71,7 +71,7 @@ LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment); #define ll_assert_aligned(ptr,alignment) #endif -#if defined(__i386__) || defined(__x86_64__) +#if defined(__i386__) || defined(__x86_64__) || _M_X64 #include <xmmintrin.h> #else #include <sse2neon.h> diff --git a/indra/llcommon/llwin32headers.h b/indra/llcommon/llwin32headers.h index df433deb7a..32139821d5 100644 --- a/indra/llcommon/llwin32headers.h +++ b/indra/llcommon/llwin32headers.h @@ -29,6 +29,7 @@ #ifdef LL_WINDOWS #include <windows.h> // Does not include winsock.h because WIN32_LEAN_AND_MEAN is defined +#include <ws2tcpip.h> #include <winsock2.h> // Requires windows.h #endif |