summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2016-08-17 15:40:03 -0400
committerNat Goodspeed <nat@lindenlab.com>2016-08-17 15:40:03 -0400
commit993f54f6e91d78a9c2e1389ad878d6bd46e9be5b (patch)
tree138fb7e1213ab0100b4662d30c4f60921e920f37
parentdb4f13e7bcfc7ef61f750152494f1e52ad5a9080 (diff)
MAINT-5011: Try to enrich catch (...) logging throughout viewer.
Turns out we have a surprising number of catch (...) clauses in the viewer code base. If all we currently do is LL_ERRS() << "unknown exception" << LL_ENDL; then call CRASH_ON_UNHANDLED_EXCEPTION() instead. If what we do is LL_WARNS() << "unknown exception" << LL_ENDL; then call LOG_UNHANDLED_EXCEPTION() instead. Since many places need LOG_UNHANDLED_EXCEPTION() and nobody catches LLContinueError yet, eliminate LLContinueError& parameter from LOG_UNHANDLED_EXCEPTION(). This permits us to use the same log message as CRASH_ON_UNHANDLED_EXCEPTION(), just with a different severity level. Where a catch (...) clause actually provides contextual information, or makes an error string, add boost::current_exception_diagnostic_information() to try to figure out actual exception class and message.
-rw-r--r--indra/llcommon/llexception.cpp29
-rw-r--r--indra/llcommon/llexception.h9
-rw-r--r--indra/llkdu/llimagej2ckdu.cpp13
-rw-r--r--indra/llmessage/llavatarnamecache.cpp3
-rw-r--r--indra/llmessage/llcoproceduremanager.cpp4
-rw-r--r--indra/newview/llaccountingcostmanager.cpp3
-rw-r--r--indra/newview/llappcorehttp.cpp2
-rw-r--r--indra/newview/llsecapi.cpp1
-rw-r--r--indra/newview/llsechandler_basic.cpp10
-rw-r--r--indra/viewer_components/login/lllogin.cpp3
10 files changed, 51 insertions, 26 deletions
diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp
index f48509b2aa..9a6dfee3f1 100644
--- a/indra/llcommon/llexception.cpp
+++ b/indra/llcommon/llexception.cpp
@@ -21,21 +21,28 @@
// other Linden headers
#include "llerror.h"
+namespace {
+// used by crash_on_unhandled_exception_() and log_unhandled_exception_()
+void log_unhandled_exception_(LLError::ELevel level,
+ const char* file, int line, const char* pretty_function)
+{
+ // log same message but allow caller-specified severity level
+ // lllog() is the macro underlying LL_ERRS(), LL_WARNS() et al.
+ lllog(level, false) << file << "(" << line << "): Unhandled exception caught in "
+ << pretty_function
+ << ":\n" << boost::current_exception_diagnostic_information() << LL_ENDL;
+}
+}
+
void crash_on_unhandled_exception_(const char* file, int line, const char* pretty_function)
{
- // LL_ERRS() terminates, but also propagates message into crash dump.
- LL_ERRS() << file << "(" << line << "): Unhandled exception caught in " << pretty_function
- << ":\n" << boost::current_exception_diagnostic_information() << LL_ENDL;
+ // LL_ERRS() terminates and propagates message into crash dump.
+ log_unhandled_exception_(LLError::LEVEL_ERROR, file, line, pretty_function);
}
-void log_unhandled_exception_(const char* file, int line, const char* pretty_function,
- const LLContinueError& e)
+void log_unhandled_exception_(const char* file, int line, const char* pretty_function)
{
// Use LL_WARNS() because we seriously do not expect this to happen
- // routinely, but we DO expect to return from this function. Deriving your
- // exception from LLContinueError implies that such an exception should
- // NOT be fatal to the viewer, only to its current task.
- LL_WARNS() << file << "(" << line << "): Unhandled " << typeid(e).name()
- << " exception caught in " << pretty_function
- << ":\n" << boost::current_exception_diagnostic_information() << LL_ENDL;
+ // routinely, but we DO expect to return from this function.
+ log_unhandled_exception_(LLError::LEVEL_WARN, file, line, pretty_function);
}
diff --git a/indra/llcommon/llexception.h b/indra/llcommon/llexception.h
index e9e25ae689..2a0f5e79eb 100644
--- a/indra/llcommon/llexception.h
+++ b/indra/llcommon/llexception.h
@@ -74,9 +74,10 @@ struct LLContinueError: public LLException
crash_on_unhandled_exception_(__FILE__, __LINE__, __PRETTY_FUNCTION__)
void crash_on_unhandled_exception_(const char*, int, const char*);
-/// Call this from a catch (const LLContinueError&) clause
-#define LOG_UNHANDLED_EXCEPTION(EXC) \
- log_unhandled_exception_(__FILE__, __LINE__, __PRETTY_FUNCTION__, EXC)
-void log_unhandled_exception_(const char*, int, const char*, const LLContinueError&);
+/// Call this from a catch (const LLContinueError&) clause, or from a catch
+/// (...) clause in which you do NOT want the viewer to crash.
+#define LOG_UNHANDLED_EXCEPTION() \
+ log_unhandled_exception_(__FILE__, __LINE__, __PRETTY_FUNCTION__)
+void log_unhandled_exception_(const char*, int, const char*);
#endif /* ! defined(LL_LLEXCEPTION_H) */
diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index e6ed6b2202..341c47a268 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -35,6 +35,7 @@
#include "kdu_block_coding.h"
#include "llexception.h"
+#include <boost/exception/diagnostic_information.hpp>
namespace {
struct KDUError: public LLException
@@ -400,7 +401,8 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
}
catch (...)
{
- base.setLastError("Unknown J2C error");
+ base.setLastError("Unknown J2C error: " +
+ boost::current_exception_diagnostic_information());
return false;
}
@@ -498,7 +500,8 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
}
catch (...)
{
- base.setLastError( "Unknown J2C error" );
+ base.setLastError("Unknown J2C error: " +
+ boost::current_exception_diagnostic_information());
base.decodeFailed();
cleanupCodeStream();
return true; // done
@@ -689,7 +692,8 @@ bool LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
}
catch( ... )
{
- base.setLastError( "Unknown J2C error" );
+ base.setLastError("Unknown J2C error: " +
+ boost::current_exception_diagnostic_information());
return false;
}
@@ -713,7 +717,8 @@ bool LLImageJ2CKDU::getMetadata(LLImageJ2C &base)
}
catch (...)
{
- base.setLastError( "Unknown J2C error" );
+ base.setLastError("Unknown J2C error: " +
+ boost::current_exception_diagnostic_information());
return false;
}
}
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 1ca5f58ae2..2dbbc80741 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -43,6 +43,7 @@
#include "llcoros.h"
#include "lleventcoro.h"
#include "llcorehttputil.h"
+#include "llexception.h"
#include <map>
#include <set>
@@ -237,7 +238,7 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU
}
catch (...)
{
- LL_WARNS() << "Caught unknown exception." << LL_ENDL;
+ LOG_UNHANDLED_EXCEPTION();
}
}
diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp
index d4c0788b7d..4b1be5b0ff 100644
--- a/indra/llmessage/llcoproceduremanager.cpp
+++ b/indra/llmessage/llcoproceduremanager.cpp
@@ -28,6 +28,7 @@
#include "linden_common.h"
#include "llcoproceduremanager.h"
#include <boost/assign.hpp>
+#include <boost/exception/diagnostic_information.hpp>
//=========================================================================
// Map of pool sizes for known pools
@@ -395,7 +396,8 @@ void LLCoprocedurePool::coprocedureInvokerCoro(LLCoreHttpUtil::HttpCoroutineAdap
}
catch (...)
{
- LL_WARNS() << "A non std::exception was thrown from " << coproc->mName << " with id=" << coproc->mId << "." << " in pool \"" << mPoolName << "\"" << LL_ENDL;
+ LL_WARNS() << "A non std::exception was thrown from " << coproc->mName << " with id=" << coproc->mId << "." << " in pool \"" << mPoolName << "\"\n"
+ << boost::current_exception_diagnostic_information() << LL_ENDL;
}
LL_INFOS() << "Finished coprocedure(" << coproc->mName << ")" << " in pool \"" << mPoolName << "\"" << LL_ENDL;
diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp
index 92a5413adb..a4a54cf8fb 100644
--- a/indra/newview/llaccountingcostmanager.cpp
+++ b/indra/newview/llaccountingcostmanager.cpp
@@ -31,6 +31,7 @@
#include "llcoros.h"
#include "lleventcoro.h"
#include "llcorehttputil.h"
+#include "llexception.h"
#include <algorithm>
#include <iterator>
@@ -160,7 +161,7 @@ void LLAccountingCostManager::accountingCostCoro(std::string url,
}
catch (...)
{
- LL_WARNS() << "Caught unknown exception." << LL_ENDL;
+ LOG_UNHANDLED_EXCEPTION();
}
mPendingObjectQuota.clear();
diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp
index dbcae57de7..7ec041c02e 100644
--- a/indra/newview/llappcorehttp.cpp
+++ b/indra/newview/llappcorehttp.cpp
@@ -30,6 +30,7 @@
#include "llappviewer.h"
#include "llviewercontrol.h"
+#include "llexception.h"
#include <openssl/x509_vfy.h>
#include <openssl/ssl.h>
@@ -551,6 +552,7 @@ LLCore::HttpStatus LLAppCoreHttp::sslVerify(const std::string &url,
}
catch (...)
{
+ LOG_UNHANDLED_EXCEPTION();
// any other odd error, we just handle as a connect error.
result = LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_SSL_CONNECT_ERROR);
}
diff --git a/indra/newview/llsecapi.cpp b/indra/newview/llsecapi.cpp
index 933f7bb16e..6ca1e63417 100644
--- a/indra/newview/llsecapi.cpp
+++ b/indra/newview/llsecapi.cpp
@@ -121,6 +121,7 @@ LLSD LLCredential::getLoginParams()
}
catch (...)
{
+ LOG_UNHANDLED_EXCEPTION();
// we could have corrupt data, so simply return a null login param if so
LL_WARNS("AppInit") << "Invalid credential" << LL_ENDL;
}
diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp
index 183a625382..54396cb9a4 100644
--- a/indra/newview/llsechandler_basic.cpp
+++ b/indra/newview/llsechandler_basic.cpp
@@ -38,6 +38,7 @@
#include "llexception.h"
#include <vector>
#include <ios>
+#include <boost/exception/diagnostic_information.hpp>
#include <openssl/ossl_typ.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
@@ -618,7 +619,8 @@ void LLBasicCertificateStore::load_from_file(const std::string& filename)
}
catch (...)
{
- LL_WARNS("SECAPI") << "Failure creating certificate from the certificate store file." << LL_ENDL;
+ LL_WARNS("SECAPI") << "Failure creating certificate from the certificate store file: "
+ << boost::current_exception_diagnostic_information() << LL_ENDL;
}
X509_free(cert_x509);
cert_x509 = NULL;
@@ -1365,7 +1367,8 @@ void LLSecAPIBasicHandler::_writeProtectedData()
}
catch (...)
{
- LL_WARNS() << "LLProtectedDataException(Error writing Protected Data Store)" << LL_ENDL;
+ LL_WARNS() << "LLProtectedDataException(Error writing Protected Data Store): "
+ << boost::current_exception_diagnostic_information() << LL_ENDL;
// it's good practice to clean up any secure information on error
// (even though this file isn't really secure. Perhaps in the future
// it may be, however.
@@ -1394,7 +1397,8 @@ void LLSecAPIBasicHandler::_writeProtectedData()
catch (...)
{
LL_WARNS() << "LLProtectedDataException(Error renaming '" << tmp_filename
- << "' to '" << mProtectedDataFilename << "')" << LL_ENDL;
+ << "' to '" << mProtectedDataFilename << "'): "
+ << boost::current_exception_diagnostic_information() << LL_ENDL;
// it's good practice to clean up any secure information on error
// (even though this file isn't really secure. Perhaps in the future
// it may be, however.
diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp
index 53d4acc9e0..14503c9c5a 100644
--- a/indra/viewer_components/login/lllogin.cpp
+++ b/indra/viewer_components/login/lllogin.cpp
@@ -42,6 +42,7 @@
#include "llevents.h"
#include "lleventfilter.h"
#include "lleventcoro.h"
+#include "llexception.h"
//*********************
// LLLogin
@@ -269,7 +270,7 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)
sendProgressEvent("offline", "fail.login", error_response);
}
catch (...) {
- LL_ERRS() << "login exception caught" << LL_ENDL;
+ CRASH_ON_UNHANDLED_EXCEPTION();
}
}