diff options
| author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2021-04-30 03:04:06 +0300 | 
|---|---|---|
| committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2021-04-30 03:04:06 +0300 | 
| commit | e00edbeb4a7edfe4f190ac7bf2197aa8240e50c6 (patch) | |
| tree | 25db350e573224fc2900c1e760f7cf429c599abe /indra/llcommon | |
| parent | 3ad10e3075840b442f3a8f4593b4b4f10bad48e0 (diff) | |
| parent | ce65bc2f13409d75dbc6502c970030cc5ed2e5ad (diff) | |
Merge branch 'master' into DRTVWR-522-maint
# Conflicts:
#	doc/contributions.txt
Diffstat (limited to 'indra/llcommon')
| -rw-r--r-- | indra/llcommon/llcoros.cpp | 22 | ||||
| -rw-r--r-- | indra/llcommon/llexception.cpp | 25 | ||||
| -rw-r--r-- | indra/llcommon/llexception.h | 10 | ||||
| -rw-r--r-- | indra/llcommon/llsingleton.cpp | 2 | ||||
| -rw-r--r-- | indra/llcommon/llsys.cpp | 28 | ||||
| -rw-r--r-- | indra/llcommon/lluriparser.cpp | 87 | ||||
| -rw-r--r-- | indra/llcommon/lluriparser.h | 1 | 
7 files changed, 111 insertions, 64 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/llsys.cpp b/indra/llcommon/llsys.cpp index f7461422f7..079d297b80 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -55,6 +55,7 @@  #include <boost/utility/enable_if.hpp>  #include <boost/type_traits/is_integral.hpp>  #include <boost/type_traits/is_float.hpp> +#include "llfasttimer.h"  using namespace llsd; @@ -892,8 +893,12 @@ LLMemoryInfo& LLMemoryInfo::refresh()  	return *this;  } +static LLTrace::BlockTimerStatHandle FTM_MEMINFO_LOAD_STATS("MemInfo Load Stats"); +  LLSD LLMemoryInfo::loadStatsMap()  { +	LL_RECORD_BLOCK_TIME(FTM_MEMINFO_LOAD_STATS); +  	// This implementation is derived from stream() code (as of 2011-06-29).  	Stats stats; @@ -915,24 +920,11 @@ LLSD LLMemoryInfo::loadStatsMap()  	stats.add("Total Virtual KB",   state.ullTotalVirtual/div);  	stats.add("Avail Virtual KB",   state.ullAvailVirtual/div); -	PERFORMANCE_INFORMATION perf; -	perf.cb = sizeof(perf); -	GetPerformanceInfo(&perf, sizeof(perf)); - -	SIZE_T pagekb(perf.PageSize/1024); -	stats.add("CommitTotal KB",     perf.CommitTotal * pagekb); -	stats.add("CommitLimit KB",     perf.CommitLimit * pagekb); -	stats.add("CommitPeak KB",      perf.CommitPeak * pagekb); -	stats.add("PhysicalTotal KB",   perf.PhysicalTotal * pagekb); -	stats.add("PhysicalAvail KB",   perf.PhysicalAvailable * pagekb); -	stats.add("SystemCache KB",     perf.SystemCache * pagekb); -	stats.add("KernelTotal KB",     perf.KernelTotal * pagekb); -	stats.add("KernelPaged KB",     perf.KernelPaged * pagekb); -	stats.add("KernelNonpaged KB",  perf.KernelNonpaged * pagekb); -	stats.add("PageSize KB",        pagekb); -	stats.add("HandleCount",        perf.HandleCount); -	stats.add("ProcessCount",       perf.ProcessCount); -	stats.add("ThreadCount",        perf.ThreadCount); +	// SL-12122 - Call to GetPerformanceInfo() was removed here. Took +	// on order of 10 ms, causing unacceptable frame time spike every +	// second, and results were never used. If this is needed in the +	// future, must find a way to avoid frame time impact (e.g. move +	// to another thread, call much less often).  	PROCESS_MEMORY_COUNTERS_EX pmem;  	pmem.cb = sizeof(pmem); 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; | 
