summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/llcoros.cpp22
-rw-r--r--indra/llcommon/llexception.cpp25
-rw-r--r--indra/llcommon/llexception.h10
-rw-r--r--indra/llcommon/llsingleton.cpp2
-rw-r--r--indra/llcommon/lluriparser.cpp87
-rw-r--r--indra/llcommon/lluriparser.h1
6 files changed, 101 insertions, 46 deletions
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index 262929006d..23419a52a7 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -56,10 +56,6 @@
#include "stringize.h"
#include "llexception.h"
-#if LL_WINDOWS
-#include <excpt.h>
-#endif
-
// static
LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller)
{
@@ -253,29 +249,13 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl
#if LL_WINDOWS
-static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
-
-U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
-{
- if (code == STATUS_MSC_EXCEPTION)
- {
- // C++ exception, go on
- return EXCEPTION_CONTINUE_SEARCH;
- }
- else
- {
- // handle it
- return EXCEPTION_EXECUTE_HANDLER;
- }
-}
-
void LLCoros::winlevel(const callable_t& callable)
{
__try
{
callable();
}
- __except (exception_filter(GetExceptionCode(), GetExceptionInformation()))
+ __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation()))
{
// convert to C++ styled exception
// Note: it might be better to use _se_set_translator
diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp
index 5ce8958687..b584b0ff8b 100644
--- a/indra/llcommon/llexception.cpp
+++ b/indra/llcommon/llexception.cpp
@@ -24,11 +24,14 @@
// `_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
+#include <excpt.h>
#endif // LL_WINDOWS
+
#include <boost/stacktrace.hpp>
// other Linden headers
#include "llerror.h"
@@ -85,3 +88,25 @@ void annotate_exception_(boost::exception& exc)
// Anyway, which of us is really going to examine more than 100 frames?
exc << errinfo_stacktrace(boost::stacktrace::stacktrace(1, 100));
}
+
+#if LL_WINDOWS
+
+// 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
+
+U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
+{
+ if (code == STATUS_MSC_EXCEPTION)
+ {
+ // C++ exception, go on
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+ else
+ {
+ // handle it
+ return EXCEPTION_EXECUTE_HANDLER;
+ }
+}
+
+#endif //LL_WINDOWS
diff --git a/indra/llcommon/llexception.h b/indra/llcommon/llexception.h
index 422dd8810a..375bea4a57 100644
--- a/indra/llcommon/llexception.h
+++ b/indra/llcommon/llexception.h
@@ -102,4 +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&);
+
+#if 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);
+
+#endif //LL_WINDOWS
+
#endif /* ! defined(LL_LLEXCEPTION_H) */
diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp
index 83a4b64e8f..ad933154c2 100644
--- a/indra/llcommon/llsingleton.cpp
+++ b/indra/llcommon/llsingleton.cpp
@@ -388,7 +388,7 @@ LLSingletonBase::vec_t LLSingletonBase::dep_sort()
// extracts just the first (key) element from each sorted_iterator, then
// uses vec_t's range constructor... but frankly this is more
// straightforward, as long as we remember the above reserve() call!
- for (const SingletonDeps::sorted_iterator::value_type& pair : sdeps.sort())
+ for (const SingletonDeps::sorted_iterator::value_type pair : sdeps.sort())
{
ret.push_back(pair.first);
}
diff --git a/indra/llcommon/lluriparser.cpp b/indra/llcommon/lluriparser.cpp
index c275b90120..e4f229dd16 100644
--- a/indra/llcommon/lluriparser.cpp
+++ b/indra/llcommon/lluriparser.cpp
@@ -29,10 +29,13 @@
#include "linden_common.h"
#include "lluriparser.h"
+#if LL_DARWIN
+#include <signal.h>
+#include <setjmp.h>
+#endif
+
LLUriParser::LLUriParser(const std::string& u) : mTmpScheme(false), mNormalizedTmp(false), mRes(0)
{
- mState.uri = &mUri;
-
if (u.find("://") == std::string::npos)
{
mNormalizedUri = "http://";
@@ -51,7 +54,7 @@ LLUriParser::~LLUriParser()
S32 LLUriParser::parse()
{
- mRes = uriParseUriA(&mState, mNormalizedUri.c_str());
+ mRes = uriParseSingleUriA(&mUri, mNormalizedUri.c_str(), NULL);
return mRes;
}
@@ -158,31 +161,69 @@ void LLUriParser::extractParts()
}
}
+#if LL_DARWIN
+typedef void(*sighandler_t)(int);
+jmp_buf return_to_normalize;
+void uri_signal_handler(int signal)
+{
+ // Apparently signal handler throwing an exception doesn't work.
+ // This is ugly and unsafe due to not unwinding content of uriparser library,
+ // but unless we have a way to catch this as NSexception, jump appears to be the only option.
+ longjmp(return_to_normalize, 1 /*setjmp will return this value*/);
+}
+#endif
+
S32 LLUriParser::normalize()
{
mNormalizedTmp = mTmpScheme;
if (!mRes)
{
- mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST);
-
- if (!mRes)
- {
- S32 chars_required;
- mRes = uriToStringCharsRequiredA(&mUri, &chars_required);
-
- if (!mRes)
- {
- chars_required++;
- std::vector<char> label_buf(chars_required);
- mRes = uriToStringA(&label_buf[0], &mUri, chars_required, NULL);
-
- if (!mRes)
- {
- mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0];
- mTmpScheme = false;
- }
- }
- }
+#if LL_DARWIN
+ sighandler_t last_handler;
+ last_handler = signal(SIGILL, &uri_signal_handler); // illegal instruction
+ if (setjmp(return_to_normalize))
+ {
+ // Issue: external library crashed via signal
+ // If you encountered this, please try to figure out what's wrong:
+ // 1. Verify that library's input is 'sane'
+ // 2. Check if we have an NSexception to work with (unlikely)
+ // 3. See if passing same string causes exception to repeat
+ //
+ // Crash happens at uriNormalizeSyntaxExA
+ // Warning!!! This does not properly unwind stack,
+ // if this can be handled by NSexception, it needs to be remade
+ llassert(0);
+
+ LL_WARNS() << "Uriparser crashed with SIGILL, while processing: " << mNormalizedUri << LL_ENDL;
+ signal(SIGILL, last_handler);
+ return 1;
+ }
+#endif
+
+ mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST);
+
+#if LL_DARWIN
+ signal(SIGILL, last_handler);
+#endif
+
+ if (!mRes)
+ {
+ S32 chars_required;
+ mRes = uriToStringCharsRequiredA(&mUri, &chars_required);
+
+ if (!mRes)
+ {
+ chars_required++;
+ std::vector<char> label_buf(chars_required);
+ mRes = uriToStringA(&label_buf[0], &mUri, chars_required, NULL);
+
+ if (!mRes)
+ {
+ mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0];
+ mTmpScheme = false;
+ }
+ }
+ }
}
if(mTmpScheme)
diff --git a/indra/llcommon/lluriparser.h b/indra/llcommon/lluriparser.h
index cfbf54f3c8..92626b9054 100644
--- a/indra/llcommon/lluriparser.h
+++ b/indra/llcommon/lluriparser.h
@@ -76,7 +76,6 @@ private:
std::string mFragment;
std::string mNormalizedUri;
- UriParserStateA mState;
UriUriA mUri;
S32 mRes;