summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/CMakeLists.txt5
-rw-r--r--indra/llcommon/llapp.cpp23
-rw-r--r--indra/llcommon/llerror.cpp33
-rw-r--r--indra/llcommon/llerrorcontrol.h3
-rw-r--r--indra/llcommon/llpreprocessor.h2
-rw-r--r--indra/llcommon/stringize.h52
-rw-r--r--indra/llcommon/tests/wrapllerrs.h14
7 files changed, 84 insertions, 48 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index d9eb13d65a..8977acb873 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -255,6 +255,11 @@ set(llcommon_HEADER_FILES
set_source_files_properties(${llcommon_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
+if (DEFINED ENV{BUGSPLAT_DB})
+ set_source_files_properties(llapp.cpp
+ PROPERTIES COMPILE_DEFINITIONS "LL_BUGSPLAT")
+endif (DEFINED ENV{BUGSPLAT_DB})
+
list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
if(LLCOMMON_LINK_SHARED)
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 6cc9e804d4..421af3006e 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -392,7 +392,7 @@ void LLApp::setupErrorHandling(bool second_instance)
#if LL_WINDOWS
-#if LL_SEND_CRASH_REPORTS
+#if LL_SEND_CRASH_REPORTS && ! defined(LL_BUGSPLAT)
EnableCrashingOnCrashes();
// This sets a callback to handle w32 signals to the console window.
@@ -454,8 +454,15 @@ void LLApp::setupErrorHandling(bool second_instance)
mExceptionHandler->set_handle_debug_exceptions(true);
}
}
-#endif
-#else
+#endif // LL_SEND_CRASH_REPORTS && ! defined(LL_BUGSPLAT)
+#else // ! LL_WINDOWS
+
+#if defined(LL_BUGSPLAT)
+ // Don't install our own signal handlers -- BugSplat needs to hook them,
+ // or it's completely ineffectual.
+ bool installHandler = false;
+
+#else // ! LL_BUGSPLAT
//
// Start up signal handling.
//
@@ -463,9 +470,11 @@ void LLApp::setupErrorHandling(bool second_instance)
// thread, asynchronous signals can be delivered to any thread (in theory)
//
setup_signals();
-
+
// Add google breakpad exception handler configured for Darwin/Linux.
bool installHandler = true;
+#endif // ! LL_BUGSPLAT
+
#if LL_DARWIN
// For the special case of Darwin, we do not want to install the handler if
// the process is being debugged as the app will exit with value ABRT (6) if
@@ -498,7 +507,7 @@ void LLApp::setupErrorHandling(bool second_instance)
// installing the handler.
installHandler = true;
}
- #endif
+ #endif // ! LL_RELEASE_FOR_DOWNLOAD
if(installHandler && (mExceptionHandler == 0))
{
@@ -514,9 +523,9 @@ void LLApp::setupErrorHandling(bool second_instance)
google_breakpad::MinidumpDescriptor desc(mDumpPath);
mExceptionHandler = new google_breakpad::ExceptionHandler(desc, NULL, unix_minidump_callback, NULL, true, -1);
}
-#endif
+#endif // LL_LINUX
-#endif
+#endif // ! LL_WINDOWS
startErrorThread();
}
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 29de79dc64..64b957b188 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -367,6 +367,7 @@ namespace
public:
std::ostringstream messageStream;
bool messageStreamInUse;
+ std::string mFatalMessage;
void addCallSite(LLError::CallSite&);
void invalidateCallSites();
@@ -660,11 +661,16 @@ namespace LLError
s->mCrashFunction = f;
}
- FatalFunction getFatalFunction()
- {
+ FatalFunction getFatalFunction()
+ {
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
- return s->mCrashFunction;
- }
+ return s->mCrashFunction;
+ }
+
+ std::string getFatalMessage()
+ {
+ return Globals::getInstance()->mFatalMessage;
+ }
void setTimeFunction(TimeFunction f)
{
@@ -1184,7 +1190,7 @@ namespace LLError
{
writeToRecorders(site, "error", true, true, true, false, false);
}
-
+
std::ostringstream message_stream;
if (site.mPrintOnce)
@@ -1209,14 +1215,19 @@ namespace LLError
s->mUniqueLogMessages[message] = 1;
}
}
-
+
message_stream << message;
-
- writeToRecorders(site, message_stream.str());
-
- if (site.mLevel == LEVEL_ERROR && s->mCrashFunction)
+ std::string message_line(message_stream.str());
+
+ writeToRecorders(site, message_line);
+
+ if (site.mLevel == LEVEL_ERROR)
{
- s->mCrashFunction(message_stream.str());
+ g->mFatalMessage = message_line;
+ if (s->mCrashFunction)
+ {
+ s->mCrashFunction(message_line);
+ }
}
}
}
diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h
index caf2ba72c2..ddbcdc94a0 100644
--- a/indra/llcommon/llerrorcontrol.h
+++ b/indra/llcommon/llerrorcontrol.h
@@ -102,6 +102,9 @@ namespace LLError
LL_COMMON_API FatalFunction getFatalFunction();
// Retrieve the previously-set FatalFunction
+ LL_COMMON_API std::string getFatalMessage();
+ // Retrieve the message last passed to FatalFunction, if any
+
/// temporarily override the FatalFunction for the duration of a
/// particular scope, e.g. for unit tests
class LL_COMMON_API OverrideFatalFunction
diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index 2879038c36..ef015fdce4 100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
@@ -198,6 +198,8 @@
#define LL_TO_STRING_HELPER(x) #x
#define LL_TO_STRING(x) LL_TO_STRING_HELPER(x)
+#define LL_TO_WSTRING_HELPER(x) L#x
+#define LL_TO_WSTRING(x) LL_TO_WSTRING_HELPER(x)
#define LL_FILE_LINENO_MSG(msg) __FILE__ "(" LL_TO_STRING(__LINE__) ") : " msg
#define LL_GLUE_IMPL(x, y) x##y
#define LL_GLUE_TOKENS(x, y) LL_GLUE_IMPL(x, y)
diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h
index a5a90d7297..38dd198ad3 100644
--- a/indra/llcommon/stringize.h
+++ b/indra/llcommon/stringize.h
@@ -30,7 +30,6 @@
#define LL_STRINGIZE_H
#include <sstream>
-#include <boost/phoenix/phoenix.hpp>
#include <llstring.h>
/**
@@ -53,12 +52,7 @@ std::basic_string<CHARTYPE> gstringize(const T& item)
*/
inline std::string stringize(const std::wstring& item)
{
- LL_WARNS() << "WARNING: Possible narrowing" << LL_ENDL;
-
- std::string s;
-
- s = wstring_to_utf8str(item);
- return gstringize<char>(s);
+ return wstring_to_utf8str(item);
}
/**
@@ -76,7 +70,10 @@ std::string stringize(const T& item)
*/
inline std::wstring wstringize(const std::string& item)
{
- return gstringize<wchar_t>(item.c_str());
+ // utf8str_to_wstring() returns LLWString, which isn't necessarily the
+ // same as std::wstring
+ LLWString s(utf8str_to_wstring(item));
+ return std::wstring(s.begin(), s.end());
}
/**
@@ -91,10 +88,10 @@ std::wstring wstringize(const T& item)
/**
* stringize_f(functor)
*/
-template <typename Functor>
-std::string stringize_f(Functor const & f)
+template <typename CHARTYPE, typename Functor>
+std::basic_string<CHARTYPE> stringize_f(Functor const & f)
{
- std::ostringstream out;
+ std::basic_ostringstream<CHARTYPE> out;
f(out);
return out.str();
}
@@ -108,31 +105,37 @@ std::string stringize_f(Functor const & f)
* return out.str();
* @endcode
*/
-#define STRINGIZE(EXPRESSION) (stringize_f(boost::phoenix::placeholders::arg1 << EXPRESSION))
+#define STRINGIZE(EXPRESSION) (stringize_f<char>([&](std::ostream& out){ out << EXPRESSION; }))
+/**
+ * WSTRINGIZE() is the wstring equivalent of STRINGIZE()
+ */
+#define WSTRINGIZE(EXPRESSION) (stringize_f<wchar_t>([&](std::wostream& out){ out << EXPRESSION; }))
/**
* destringize(str)
* defined for symmetry with stringize
- * *NOTE - this has distinct behavior from boost::lexical_cast<T> regarding
+ * @NOTE - this has distinct behavior from boost::lexical_cast<T> regarding
* leading/trailing whitespace and handling of bad_lexical_cast exceptions
+ * @NOTE - no need for dewstringize(), since passing std::wstring will Do The
+ * Right Thing
*/
-template <typename T>
-T destringize(std::string const & str)
+template <typename T, typename CHARTYPE>
+T destringize(std::basic_string<CHARTYPE> const & str)
{
- T val;
- std::istringstream in(str);
- in >> val;
+ T val;
+ std::basic_istringstream<CHARTYPE> in(str);
+ in >> val;
return val;
}
/**
* destringize_f(str, functor)
*/
-template <typename Functor>
-void destringize_f(std::string const & str, Functor const & f)
+template <typename CHARTYPE, typename Functor>
+void destringize_f(std::basic_string<CHARTYPE> const & str, Functor const & f)
{
- std::istringstream in(str);
+ std::basic_istringstream<CHARTYPE> in(str);
f(in);
}
@@ -143,8 +146,11 @@ void destringize_f(std::string const & str, Functor const & f)
* std::istringstream in(str);
* in >> item1 >> item2 >> item3 ... ;
* @endcode
+ * @NOTE - once we get generic lambdas, we shouldn't need DEWSTRINGIZE() any
+ * more since DESTRINGIZE() should do the right thing with a std::wstring. But
+ * until then, the lambda we pass must accept the right std::basic_istream.
*/
-#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), (boost::phoenix::placeholders::arg1 >> EXPRESSION)))
-
+#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::istream& in){in >> EXPRESSION;}))
+#define DEWSTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::wistream& in){in >> EXPRESSION;}))
#endif /* ! defined(LL_STRINGIZE_H) */
diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h
index 9a4bbbd630..08fbf19b1c 100644
--- a/indra/llcommon/tests/wrapllerrs.h
+++ b/indra/llcommon/tests/wrapllerrs.h
@@ -109,6 +109,12 @@ public:
mMessages.push_back(message);
}
+ friend inline
+ std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log)
+ {
+ return log.streamto(out);
+ }
+
/// Don't assume the message we want is necessarily the LAST log message
/// emitted by the underlying code; search backwards through all messages
/// for the sought string.
@@ -126,7 +132,7 @@ public:
throw tut::failure(STRINGIZE("failed to find '" << search
<< "' in captured log messages:\n"
- << boost::ref(*this)));
+ << *this));
}
std::ostream& streamto(std::ostream& out) const
@@ -200,10 +206,4 @@ private:
LLError::RecorderPtr mRecorder;
};
-inline
-std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log)
-{
- return log.streamto(out);
-}
-
#endif /* ! defined(LL_WRAPLLERRS_H) */