summaryrefslogtreecommitdiff
path: root/indra/llcommon/llapp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/llapp.cpp')
-rw-r--r--indra/llcommon/llapp.cpp960
1 files changed, 480 insertions, 480 deletions
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 90d0c28eb1..9729f68d23 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llapp.cpp
* @brief Implementation of the LLApp class.
*
* $LicenseInfo:firstyear=2003&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -70,8 +70,8 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *);
#else
// Called by breakpad exception handler after the minidump has been generated.
bool unix_post_minidump_callback(const char *dump_dir,
- const char *minidump_id,
- void *context, bool succeeded);
+ const char *minidump_id,
+ void *context, bool succeeded);
#endif
# if LL_DARWIN
@@ -94,7 +94,7 @@ LLApp* LLApp::sApplication = NULL;
// Allows the generation of core files for post mortem under gdb
// and disables crashlogger
-BOOL LLApp::sDisableCrashlogger = FALSE;
+BOOL LLApp::sDisableCrashlogger = FALSE;
// Local flag for whether or not to do logging in signal handlers.
//static
@@ -108,222 +108,222 @@ LLAppErrorHandler LLApp::sErrorHandler = NULL;
LLApp::LLApp()
{
- // Set our status to running
- setStatus(APP_STATUS_RUNNING);
+ // Set our status to running
+ setStatus(APP_STATUS_RUNNING);
+
+ LLCommon::initClass();
- LLCommon::initClass();
+ // initialize the options structure. We need to make this an array
+ // because the structured data will not auto-allocate if we
+ // reference an invalid location with the [] operator.
+ mOptions = LLSD::emptyArray();
+ LLSD sd;
+ for(int i = 0; i < PRIORITY_COUNT; ++i)
+ {
+ mOptions.append(sd);
+ }
- // initialize the options structure. We need to make this an array
- // because the structured data will not auto-allocate if we
- // reference an invalid location with the [] operator.
- mOptions = LLSD::emptyArray();
- LLSD sd;
- for(int i = 0; i < PRIORITY_COUNT; ++i)
- {
- mOptions.append(sd);
- }
+ // Make sure we clean up APR when we exit
+ // Don't need to do this if we're cleaning up APR in the destructor
+ //atexit(ll_cleanup_apr);
- // Make sure we clean up APR when we exit
- // Don't need to do this if we're cleaning up APR in the destructor
- //atexit(ll_cleanup_apr);
+ // Set the application to this instance.
+ sApplication = this;
- // Set the application to this instance.
- sApplication = this;
-
- // initialize the buffer to write the minidump filename to
- // (this is used to avoid allocating memory in the crash handler)
- memset(mMinidumpPath, 0, MAX_MINDUMP_PATH_LENGTH);
- mCrashReportPipeStr = L"\\\\.\\pipe\\LLCrashReporterPipe";
+ // initialize the buffer to write the minidump filename to
+ // (this is used to avoid allocating memory in the crash handler)
+ memset(mMinidumpPath, 0, MAX_MINDUMP_PATH_LENGTH);
+ mCrashReportPipeStr = L"\\\\.\\pipe\\LLCrashReporterPipe";
}
LLApp::~LLApp()
{
- // reclaim live file memory
- std::for_each(mLiveFiles.begin(), mLiveFiles.end(), DeletePointer());
- mLiveFiles.clear();
+ // reclaim live file memory
+ std::for_each(mLiveFiles.begin(), mLiveFiles.end(), DeletePointer());
+ mLiveFiles.clear();
- setStopped();
+ setStopped();
- SUBSYSTEM_CLEANUP_DBG(LLCommon);
+ SUBSYSTEM_CLEANUP_DBG(LLCommon);
}
// static
LLApp* LLApp::instance()
{
- return sApplication;
+ return sApplication;
}
LLSD LLApp::getOption(const std::string& name) const
{
- LLSD rv;
- LLSD::array_const_iterator iter = mOptions.beginArray();
- LLSD::array_const_iterator end = mOptions.endArray();
- for(; iter != end; ++iter)
- {
- rv = (*iter)[name];
- if(rv.isDefined()) break;
- }
- return rv;
+ LLSD rv;
+ LLSD::array_const_iterator iter = mOptions.beginArray();
+ LLSD::array_const_iterator end = mOptions.endArray();
+ for(; iter != end; ++iter)
+ {
+ rv = (*iter)[name];
+ if(rv.isDefined()) break;
+ }
+ return rv;
}
bool LLApp::parseCommandOptions(int argc, char** argv)
{
- LLSD commands;
- std::string name;
- std::string value;
- for(int ii = 1; ii < argc; ++ii)
- {
- if(argv[ii][0] != '-')
- {
- LL_INFOS() << "Did not find option identifier while parsing token: "
- << argv[ii] << LL_ENDL;
- return false;
- }
- int offset = 1;
- if(argv[ii][1] == '-') ++offset;
- name.assign(&argv[ii][offset]);
- if(((ii+1) >= argc) || (argv[ii+1][0] == '-'))
- {
- // we found another option after this one or we have
- // reached the end. simply record that this option was
- // found and continue.
- int flag = name.compare("logfile");
- if (0 == flag)
- {
- commands[name] = "log";
- }
- else
- {
- commands[name] = true;
- }
-
- continue;
- }
- ++ii;
- value.assign(argv[ii]);
+ LLSD commands;
+ std::string name;
+ std::string value;
+ for(int ii = 1; ii < argc; ++ii)
+ {
+ if(argv[ii][0] != '-')
+ {
+ LL_INFOS() << "Did not find option identifier while parsing token: "
+ << argv[ii] << LL_ENDL;
+ return false;
+ }
+ int offset = 1;
+ if(argv[ii][1] == '-') ++offset;
+ name.assign(&argv[ii][offset]);
+ if(((ii+1) >= argc) || (argv[ii+1][0] == '-'))
+ {
+ // we found another option after this one or we have
+ // reached the end. simply record that this option was
+ // found and continue.
+ int flag = name.compare("logfile");
+ if (0 == flag)
+ {
+ commands[name] = "log";
+ }
+ else
+ {
+ commands[name] = true;
+ }
+
+ continue;
+ }
+ ++ii;
+ value.assign(argv[ii]);
#if LL_WINDOWS
- //Windows changed command line parsing. Deal with it.
- S32 slen = value.length() - 1;
- S32 start = 0;
- S32 end = slen;
- if (argv[ii][start]=='"')start++;
- if (argv[ii][end]=='"')end--;
- if (start!=0 || end!=slen)
- {
- value = value.substr (start,end);
- }
+ //Windows changed command line parsing. Deal with it.
+ S32 slen = value.length() - 1;
+ S32 start = 0;
+ S32 end = slen;
+ if (argv[ii][start]=='"')start++;
+ if (argv[ii][end]=='"')end--;
+ if (start!=0 || end!=slen)
+ {
+ value = value.substr (start,end);
+ }
#endif
- commands[name] = value;
- }
- setOptionData(PRIORITY_COMMAND_LINE, commands);
- return true;
+ commands[name] = value;
+ }
+ setOptionData(PRIORITY_COMMAND_LINE, commands);
+ return true;
}
bool LLApp::parseCommandOptions(int argc, wchar_t** wargv)
{
- LLSD commands;
- std::string name;
- std::string value;
- for(int ii = 1; ii < argc; ++ii)
- {
- if(wargv[ii][0] != '-')
- {
- LL_INFOS() << "Did not find option identifier while parsing token: "
- << wargv[ii] << LL_ENDL;
- return false;
- }
- int offset = 1;
- if(wargv[ii][1] == '-') ++offset;
+ LLSD commands;
+ std::string name;
+ std::string value;
+ for(int ii = 1; ii < argc; ++ii)
+ {
+ if(wargv[ii][0] != '-')
+ {
+ LL_INFOS() << "Did not find option identifier while parsing token: "
+ << wargv[ii] << LL_ENDL;
+ return false;
+ }
+ int offset = 1;
+ if(wargv[ii][1] == '-') ++offset;
#if LL_WINDOWS
- name.assign(utf16str_to_utf8str(&wargv[ii][offset]));
+ name.assign(utf16str_to_utf8str(&wargv[ii][offset]));
#else
- name.assign(wstring_to_utf8str(&wargv[ii][offset]));
+ name.assign(wstring_to_utf8str(&wargv[ii][offset]));
#endif
- if(((ii+1) >= argc) || (wargv[ii+1][0] == '-'))
- {
- // we found another option after this one or we have
- // reached the end. simply record that this option was
- // found and continue.
- int flag = name.compare("logfile");
- if (0 == flag)
- {
- commands[name] = "log";
- }
- else
- {
- commands[name] = true;
- }
-
- continue;
- }
- ++ii;
+ if(((ii+1) >= argc) || (wargv[ii+1][0] == '-'))
+ {
+ // we found another option after this one or we have
+ // reached the end. simply record that this option was
+ // found and continue.
+ int flag = name.compare("logfile");
+ if (0 == flag)
+ {
+ commands[name] = "log";
+ }
+ else
+ {
+ commands[name] = true;
+ }
+
+ continue;
+ }
+ ++ii;
#if LL_WINDOWS
- value.assign(utf16str_to_utf8str((wargv[ii])));
+ value.assign(utf16str_to_utf8str((wargv[ii])));
#else
- value.assign(wstring_to_utf8str((wargv[ii])));
+ value.assign(wstring_to_utf8str((wargv[ii])));
#endif
#if LL_WINDOWS
- //Windows changed command line parsing. Deal with it.
- S32 slen = value.length() - 1;
- S32 start = 0;
- S32 end = slen;
- if (wargv[ii][start]=='"')start++;
- if (wargv[ii][end]=='"')end--;
- if (start!=0 || end!=slen)
- {
- value = value.substr (start,end);
- }
+ //Windows changed command line parsing. Deal with it.
+ S32 slen = value.length() - 1;
+ S32 start = 0;
+ S32 end = slen;
+ if (wargv[ii][start]=='"')start++;
+ if (wargv[ii][end]=='"')end--;
+ if (start!=0 || end!=slen)
+ {
+ value = value.substr (start,end);
+ }
#endif
- commands[name] = value;
- }
- setOptionData(PRIORITY_COMMAND_LINE, commands);
- return true;
+ commands[name] = value;
+ }
+ setOptionData(PRIORITY_COMMAND_LINE, commands);
+ return true;
}
void LLApp::manageLiveFile(LLLiveFile* livefile)
{
- if(!livefile) return;
- livefile->checkAndReload();
- livefile->addToEventTimer();
- mLiveFiles.push_back(livefile);
+ if(!livefile) return;
+ livefile->checkAndReload();
+ livefile->addToEventTimer();
+ mLiveFiles.push_back(livefile);
}
bool LLApp::setOptionData(OptionPriority level, LLSD data)
{
- if((level < 0)
- || (level >= PRIORITY_COUNT)
- || (data.type() != LLSD::TypeMap))
- {
- return false;
- }
- mOptions[level] = data;
- return true;
+ if((level < 0)
+ || (level >= PRIORITY_COUNT)
+ || (data.type() != LLSD::TypeMap))
+ {
+ return false;
+ }
+ mOptions[level] = data;
+ return true;
}
LLSD LLApp::getOptionData(OptionPriority level)
{
- if((level < 0) || (level >= PRIORITY_COUNT))
- {
- return LLSD();
- }
- return mOptions[level];
+ if((level < 0) || (level >= PRIORITY_COUNT))
+ {
+ return LLSD();
+ }
+ return mOptions[level];
}
void LLApp::stepFrame()
{
- LLFrameTimer::updateFrameTime();
- LLFrameTimer::updateFrameCount();
- LLEventTimer::updateClass();
- mRunner.run();
+ LLFrameTimer::updateFrameTime();
+ LLFrameTimer::updateFrameCount();
+ LLEventTimer::updateClass();
+ mRunner.run();
}
#if LL_WINDOWS
@@ -332,31 +332,31 @@ void LLApp::stepFrame()
//in-depth article on the issue may be found here: http://randomascii.wordpress.com/2012/07/05/when-even-crashing-doesn-work/
void EnableCrashingOnCrashes()
{
- typedef BOOL (WINAPI *tGetPolicy)(LPDWORD lpFlags);
- typedef BOOL (WINAPI *tSetPolicy)(DWORD dwFlags);
- const DWORD EXCEPTION_SWALLOWING = 0x1;
-
- HMODULE kernel32 = LoadLibraryA("kernel32.dll");
- tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32,
- "GetProcessUserModeExceptionPolicy");
- tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32,
- "SetProcessUserModeExceptionPolicy");
- if (pGetPolicy && pSetPolicy)
- {
- DWORD dwFlags;
- if (pGetPolicy(&dwFlags))
- {
- // Turn off the filter
- pSetPolicy(dwFlags & ~EXCEPTION_SWALLOWING);
- }
- }
+ typedef BOOL (WINAPI *tGetPolicy)(LPDWORD lpFlags);
+ typedef BOOL (WINAPI *tSetPolicy)(DWORD dwFlags);
+ const DWORD EXCEPTION_SWALLOWING = 0x1;
+
+ HMODULE kernel32 = LoadLibraryA("kernel32.dll");
+ tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32,
+ "GetProcessUserModeExceptionPolicy");
+ tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32,
+ "SetProcessUserModeExceptionPolicy");
+ if (pGetPolicy && pSetPolicy)
+ {
+ DWORD dwFlags;
+ if (pGetPolicy(&dwFlags))
+ {
+ // Turn off the filter
+ pSetPolicy(dwFlags & ~EXCEPTION_SWALLOWING);
+ }
+ }
}
#endif
void LLApp::setupErrorHandling(bool second_instance)
{
- // Error handling is done by starting up an error handling thread, which just sleeps and
- // occasionally checks to see if the app is in an error state, and sees if it needs to be run.
+ // Error handling is done by starting up an error handling thread, which just sleeps and
+ // occasionally checks to see if the app is in an error state, and sees if it needs to be run.
#if LL_WINDOWS
@@ -377,19 +377,19 @@ void LLApp::setupErrorHandling(bool second_instance)
void LLApp::setErrorHandler(LLAppErrorHandler handler)
{
- LLApp::sErrorHandler = handler;
+ LLApp::sErrorHandler = handler;
}
// static
void LLApp::runErrorHandler()
{
- if (LLApp::sErrorHandler)
- {
- LLApp::sErrorHandler();
- }
+ if (LLApp::sErrorHandler)
+ {
+ LLApp::sErrorHandler();
+ }
- //LL_INFOS() << "App status now STOPPED" << LL_ENDL;
- LLApp::setStopped();
+ //LL_INFOS() << "App status now STOPPED" << LL_ENDL;
+ LLApp::setStopped();
}
namespace
@@ -435,14 +435,14 @@ void LLApp::setStatus(EAppStatus status)
// static
void LLApp::setError()
{
- // set app status to ERROR
- setStatus(APP_STATUS_ERROR);
+ // set app status to ERROR
+ setStatus(APP_STATUS_ERROR);
}
void LLApp::setDebugFileNames(const std::string &path)
{
- mStaticDebugFileName = path + "static_debug_info.log";
- mDynamicDebugFileName = path + "dynamic_debug_info.log";
+ mStaticDebugFileName = path + "static_debug_info.log";
+ mDynamicDebugFileName = path + "dynamic_debug_info.log";
}
void LLApp::writeMiniDump()
@@ -452,64 +452,64 @@ void LLApp::writeMiniDump()
// static
void LLApp::setQuitting()
{
- if (!isExiting())
- {
- // If we're already exiting, we don't want to reset our state back to quitting.
- LL_INFOS() << "Setting app state to QUITTING" << LL_ENDL;
- setStatus(APP_STATUS_QUITTING);
- }
+ if (!isExiting())
+ {
+ // If we're already exiting, we don't want to reset our state back to quitting.
+ LL_INFOS() << "Setting app state to QUITTING" << LL_ENDL;
+ setStatus(APP_STATUS_QUITTING);
+ }
}
// static
void LLApp::setStopped()
{
- setStatus(APP_STATUS_STOPPED);
+ setStatus(APP_STATUS_STOPPED);
}
// static
bool LLApp::isStopped()
{
- return (APP_STATUS_STOPPED == sStatus.get());
+ return (APP_STATUS_STOPPED == sStatus.get());
}
// static
bool LLApp::isRunning()
{
- return (APP_STATUS_RUNNING == sStatus.get());
+ return (APP_STATUS_RUNNING == sStatus.get());
}
// static
bool LLApp::isError()
{
- return (APP_STATUS_ERROR == sStatus.get());
+ return (APP_STATUS_ERROR == sStatus.get());
}
// static
bool LLApp::isQuitting()
{
- return (APP_STATUS_QUITTING == sStatus.get());
+ return (APP_STATUS_QUITTING == sStatus.get());
}
// static
bool LLApp::isExiting()
{
- return isQuitting() || isError();
+ return isQuitting() || isError();
}
void LLApp::disableCrashlogger()
{
- sDisableCrashlogger = TRUE;
+ sDisableCrashlogger = TRUE;
}
// static
bool LLApp::isCrashloggerDisabled()
{
- return (sDisableCrashlogger == TRUE);
+ return (sDisableCrashlogger == TRUE);
}
// static
@@ -518,336 +518,336 @@ int LLApp::getPid()
#if LL_WINDOWS
return GetCurrentProcessId();
#else
- return getpid();
+ return getpid();
#endif
}
#if LL_WINDOWS
LONG WINAPI default_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop)
{
- // Translate the signals/exceptions into cross-platform stuff
- // Windows implementation
+ // Translate the signals/exceptions into cross-platform stuff
+ // Windows implementation
- // Make sure the user sees something to indicate that the app crashed.
- LONG retval;
+ // Make sure the user sees something to indicate that the app crashed.
+ LONG retval;
- if (LLApp::isError())
- {
- LL_WARNS() << "Got another fatal signal while in the error handler, die now!" << LL_ENDL;
- retval = EXCEPTION_EXECUTE_HANDLER;
- return retval;
- }
+ if (LLApp::isError())
+ {
+ LL_WARNS() << "Got another fatal signal while in the error handler, die now!" << LL_ENDL;
+ retval = EXCEPTION_EXECUTE_HANDLER;
+ return retval;
+ }
- // Flag status to error, so thread_error starts its work
- LLApp::setError();
+ // Flag status to error, so thread_error starts its work
+ LLApp::setError();
- // Block in the exception handler until the app has stopped
- // This is pretty sketchy, but appears to work just fine
- while (!LLApp::isStopped())
- {
- ms_sleep(10);
- }
+ // Block in the exception handler until the app has stopped
+ // This is pretty sketchy, but appears to work just fine
+ while (!LLApp::isStopped())
+ {
+ ms_sleep(10);
+ }
- //
- // Generate a minidump if we can.
- //
- // TODO: This needs to be ported over form the viewer-specific
- // LLWinDebug class
+ //
+ // Generate a minidump if we can.
+ //
+ // TODO: This needs to be ported over form the viewer-specific
+ // LLWinDebug class
- //
- // At this point, we always want to exit the app. There's no graceful
- // recovery for an unhandled exception.
- //
- // Just kill the process.
- retval = EXCEPTION_EXECUTE_HANDLER;
- return retval;
+ //
+ // At this point, we always want to exit the app. There's no graceful
+ // recovery for an unhandled exception.
+ //
+ // Just kill the process.
+ retval = EXCEPTION_EXECUTE_HANDLER;
+ return retval;
}
// Win32 doesn't support signals. This is used instead.
-BOOL ConsoleCtrlHandler(DWORD fdwCtrlType)
-{
- switch (fdwCtrlType)
- {
- case CTRL_BREAK_EVENT:
- case CTRL_LOGOFF_EVENT:
- case CTRL_SHUTDOWN_EVENT:
- case CTRL_CLOSE_EVENT: // From end task or the window close button.
- case CTRL_C_EVENT: // from CTRL-C on the keyboard
- // Just set our state to quitting, not error
- if (LLApp::isQuitting() || LLApp::isError())
- {
- // We're already trying to die, just ignore this signal
- if (LLApp::sLogInSignal)
- {
- LL_INFOS() << "Signal handler - Already trying to quit, ignoring signal!" << LL_ENDL;
- }
- return TRUE;
- }
- LLApp::setQuitting();
- return TRUE;
-
- default:
- return FALSE;
- }
-}
+BOOL ConsoleCtrlHandler(DWORD fdwCtrlType)
+{
+ switch (fdwCtrlType)
+ {
+ case CTRL_BREAK_EVENT:
+ case CTRL_LOGOFF_EVENT:
+ case CTRL_SHUTDOWN_EVENT:
+ case CTRL_CLOSE_EVENT: // From end task or the window close button.
+ case CTRL_C_EVENT: // from CTRL-C on the keyboard
+ // Just set our state to quitting, not error
+ if (LLApp::isQuitting() || LLApp::isError())
+ {
+ // We're already trying to die, just ignore this signal
+ if (LLApp::sLogInSignal)
+ {
+ LL_INFOS() << "Signal handler - Already trying to quit, ignoring signal!" << LL_ENDL;
+ }
+ return TRUE;
+ }
+ LLApp::setQuitting();
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
#else //!LL_WINDOWS
void setup_signals()
{
- //
- // Set up signal handlers that may result in program termination
- //
- struct sigaction act;
- act.sa_sigaction = default_unix_signal_handler;
- sigemptyset( &act.sa_mask );
- act.sa_flags = SA_SIGINFO;
+ //
+ // Set up signal handlers that may result in program termination
+ //
+ struct sigaction act;
+ act.sa_sigaction = default_unix_signal_handler;
+ sigemptyset( &act.sa_mask );
+ act.sa_flags = SA_SIGINFO;
- // Synchronous signals
+ // Synchronous signals
# ifndef LL_BUGSPLAT
- sigaction(SIGABRT, &act, NULL);
+ sigaction(SIGABRT, &act, NULL);
# endif
- sigaction(SIGALRM, &act, NULL);
- sigaction(SIGBUS, &act, NULL);
- sigaction(SIGFPE, &act, NULL);
- sigaction(SIGHUP, &act, NULL);
- sigaction(SIGILL, &act, NULL);
- sigaction(SIGPIPE, &act, NULL);
- sigaction(SIGSEGV, &act, NULL);
- sigaction(SIGSYS, &act, NULL);
-
- sigaction(LL_HEARTBEAT_SIGNAL, &act, NULL);
- sigaction(LL_SMACKDOWN_SIGNAL, &act, NULL);
-
- // Asynchronous signals that are normally ignored
+ sigaction(SIGALRM, &act, NULL);
+ sigaction(SIGBUS, &act, NULL);
+ sigaction(SIGFPE, &act, NULL);
+ sigaction(SIGHUP, &act, NULL);
+ sigaction(SIGILL, &act, NULL);
+ sigaction(SIGPIPE, &act, NULL);
+ sigaction(SIGSEGV, &act, NULL);
+ sigaction(SIGSYS, &act, NULL);
+
+ sigaction(LL_HEARTBEAT_SIGNAL, &act, NULL);
+ sigaction(LL_SMACKDOWN_SIGNAL, &act, NULL);
+
+ // Asynchronous signals that are normally ignored
#ifndef LL_IGNORE_SIGCHLD
- sigaction(SIGCHLD, &act, NULL);
+ sigaction(SIGCHLD, &act, NULL);
#endif // LL_IGNORE_SIGCHLD
- sigaction(SIGUSR2, &act, NULL);
+ sigaction(SIGUSR2, &act, NULL);
- // Asynchronous signals that result in attempted graceful exit
- sigaction(SIGHUP, &act, NULL);
- sigaction(SIGTERM, &act, NULL);
- sigaction(SIGINT, &act, NULL);
+ // Asynchronous signals that result in attempted graceful exit
+ sigaction(SIGHUP, &act, NULL);
+ sigaction(SIGTERM, &act, NULL);
+ sigaction(SIGINT, &act, NULL);
+
+ // Asynchronous signals that result in core
+ sigaction(SIGQUIT, &act, NULL);
- // Asynchronous signals that result in core
- sigaction(SIGQUIT, &act, NULL);
-
}
void clear_signals()
{
- struct sigaction act;
- act.sa_handler = SIG_DFL;
- sigemptyset( &act.sa_mask );
- act.sa_flags = SA_SIGINFO;
+ struct sigaction act;
+ act.sa_handler = SIG_DFL;
+ sigemptyset( &act.sa_mask );
+ act.sa_flags = SA_SIGINFO;
- // Synchronous signals
+ // Synchronous signals
# ifndef LL_BUGSPLAT
- sigaction(SIGABRT, &act, NULL);
+ sigaction(SIGABRT, &act, NULL);
# endif
- sigaction(SIGALRM, &act, NULL);
- sigaction(SIGBUS, &act, NULL);
- sigaction(SIGFPE, &act, NULL);
- sigaction(SIGHUP, &act, NULL);
- sigaction(SIGILL, &act, NULL);
- sigaction(SIGPIPE, &act, NULL);
- sigaction(SIGSEGV, &act, NULL);
- sigaction(SIGSYS, &act, NULL);
-
- sigaction(LL_HEARTBEAT_SIGNAL, &act, NULL);
- sigaction(LL_SMACKDOWN_SIGNAL, &act, NULL);
-
- // Asynchronous signals that are normally ignored
+ sigaction(SIGALRM, &act, NULL);
+ sigaction(SIGBUS, &act, NULL);
+ sigaction(SIGFPE, &act, NULL);
+ sigaction(SIGHUP, &act, NULL);
+ sigaction(SIGILL, &act, NULL);
+ sigaction(SIGPIPE, &act, NULL);
+ sigaction(SIGSEGV, &act, NULL);
+ sigaction(SIGSYS, &act, NULL);
+
+ sigaction(LL_HEARTBEAT_SIGNAL, &act, NULL);
+ sigaction(LL_SMACKDOWN_SIGNAL, &act, NULL);
+
+ // Asynchronous signals that are normally ignored
#ifndef LL_IGNORE_SIGCHLD
- sigaction(SIGCHLD, &act, NULL);
+ sigaction(SIGCHLD, &act, NULL);
#endif // LL_IGNORE_SIGCHLD
- // Asynchronous signals that result in attempted graceful exit
- sigaction(SIGHUP, &act, NULL);
- sigaction(SIGTERM, &act, NULL);
- sigaction(SIGINT, &act, NULL);
+ // Asynchronous signals that result in attempted graceful exit
+ sigaction(SIGHUP, &act, NULL);
+ sigaction(SIGTERM, &act, NULL);
+ sigaction(SIGINT, &act, NULL);
- // Asynchronous signals that result in core
- sigaction(SIGUSR2, &act, NULL);
- sigaction(SIGQUIT, &act, NULL);
+ // Asynchronous signals that result in core
+ sigaction(SIGUSR2, &act, NULL);
+ sigaction(SIGQUIT, &act, NULL);
}
void default_unix_signal_handler(int signum, siginfo_t *info, void *)
{
- // Unix implementation of synchronous signal handler
- // This runs in the thread that threw the signal.
- // We do the somewhat sketchy operation of blocking in here until the error handler
- // has gracefully stopped the app.
+ // Unix implementation of synchronous signal handler
+ // This runs in the thread that threw the signal.
+ // We do the somewhat sketchy operation of blocking in here until the error handler
+ // has gracefully stopped the app.
- if (LLApp::sLogInSignal)
- {
- LL_INFOS() << "Signal handler - Got signal " << signum << " - " << apr_signal_description_get(signum) << LL_ENDL;
- }
+ if (LLApp::sLogInSignal)
+ {
+ LL_INFOS() << "Signal handler - Got signal " << signum << " - " << apr_signal_description_get(signum) << LL_ENDL;
+ }
- switch (signum)
- {
- case SIGCHLD:
- if (LLApp::sLogInSignal)
- {
- LL_INFOS() << "Signal handler - Got SIGCHLD from " << info->si_pid << LL_ENDL;
- }
+ switch (signum)
+ {
+ case SIGCHLD:
+ if (LLApp::sLogInSignal)
+ {
+ LL_INFOS() << "Signal handler - Got SIGCHLD from " << info->si_pid << LL_ENDL;
+ }
- return;
- case SIGABRT:
+ return;
+ case SIGABRT:
// Note that this handler is not set for SIGABRT when using Bugsplat
- // Abort just results in termination of the app, no funky error handling.
- if (LLApp::sLogInSignal)
- {
- LL_WARNS() << "Signal handler - Got SIGABRT, terminating" << LL_ENDL;
- }
- clear_signals();
- raise(signum);
- return;
- case SIGINT:
- case SIGHUP:
- case SIGTERM:
- if (LLApp::sLogInSignal)
- {
- LL_WARNS() << "Signal handler - Got SIGINT, HUP, or TERM, exiting gracefully" << LL_ENDL;
- }
- // Graceful exit
- // Just set our state to quitting, not error
- if (LLApp::isQuitting() || LLApp::isError())
- {
- // We're already trying to die, just ignore this signal
- if (LLApp::sLogInSignal)
- {
- LL_INFOS() << "Signal handler - Already trying to quit, ignoring signal!" << LL_ENDL;
- }
- return;
- }
- LLApp::setQuitting();
- return;
- case SIGALRM:
- case SIGPIPE:
- case SIGUSR2:
- default:
- if (signum == LL_SMACKDOWN_SIGNAL ||
- signum == SIGBUS ||
- signum == SIGILL ||
- signum == SIGFPE ||
- signum == SIGSEGV ||
- signum == SIGQUIT)
- {
- if (signum == LL_SMACKDOWN_SIGNAL)
- {
- // Smackdown treated just like any other app termination, for now
- if (LLApp::sLogInSignal)
- {
- LL_WARNS() << "Signal handler - Handling smackdown signal!" << LL_ENDL;
- }
- else
- {
- // Don't log anything, even errors - this is because this signal could happen anywhere.
- LLError::setDefaultLevel(LLError::LEVEL_NONE);
- }
-
- // Change the signal that we reraise to SIGABRT, so we generate a core dump.
- signum = SIGABRT;
- }
-
- if (LLApp::sLogInSignal)
- {
- LL_WARNS() << "Signal handler - Handling fatal signal!" << LL_ENDL;
- }
- if (LLApp::isError())
- {
- // Received second fatal signal while handling first, just die right now
- // Set the signal handlers back to default before handling the signal - this makes the next signal wipe out the app.
- clear_signals();
-
- if (LLApp::sLogInSignal)
- {
- LL_WARNS() << "Signal handler - Got another fatal signal while in the error handler, die now!" << LL_ENDL;
- }
- raise(signum);
- return;
- }
-
- if (LLApp::sLogInSignal)
- {
- LL_WARNS() << "Signal handler - Flagging error status and waiting for shutdown" << LL_ENDL;
- }
-
- if (LLApp::isCrashloggerDisabled()) // Don't gracefully handle any signal, crash and core for a gdb post mortem
- {
- clear_signals();
- LL_WARNS() << "Fatal signal received, not handling the crash here, passing back to operating system" << LL_ENDL;
- raise(signum);
- return;
- }
-
- // Flag status to ERROR
- LLApp::setError();
-
- if (LLApp::sLogInSignal)
- {
- LL_WARNS() << "Signal handler - App is stopped, reraising signal" << LL_ENDL;
- }
- clear_signals();
- raise(signum);
- return;
- } else {
- if (LLApp::sLogInSignal)
- {
- LL_INFOS() << "Signal handler - Unhandled signal " << signum << ", ignoring!" << LL_ENDL;
- }
- }
- }
+ // Abort just results in termination of the app, no funky error handling.
+ if (LLApp::sLogInSignal)
+ {
+ LL_WARNS() << "Signal handler - Got SIGABRT, terminating" << LL_ENDL;
+ }
+ clear_signals();
+ raise(signum);
+ return;
+ case SIGINT:
+ case SIGHUP:
+ case SIGTERM:
+ if (LLApp::sLogInSignal)
+ {
+ LL_WARNS() << "Signal handler - Got SIGINT, HUP, or TERM, exiting gracefully" << LL_ENDL;
+ }
+ // Graceful exit
+ // Just set our state to quitting, not error
+ if (LLApp::isQuitting() || LLApp::isError())
+ {
+ // We're already trying to die, just ignore this signal
+ if (LLApp::sLogInSignal)
+ {
+ LL_INFOS() << "Signal handler - Already trying to quit, ignoring signal!" << LL_ENDL;
+ }
+ return;
+ }
+ LLApp::setQuitting();
+ return;
+ case SIGALRM:
+ case SIGPIPE:
+ case SIGUSR2:
+ default:
+ if (signum == LL_SMACKDOWN_SIGNAL ||
+ signum == SIGBUS ||
+ signum == SIGILL ||
+ signum == SIGFPE ||
+ signum == SIGSEGV ||
+ signum == SIGQUIT)
+ {
+ if (signum == LL_SMACKDOWN_SIGNAL)
+ {
+ // Smackdown treated just like any other app termination, for now
+ if (LLApp::sLogInSignal)
+ {
+ LL_WARNS() << "Signal handler - Handling smackdown signal!" << LL_ENDL;
+ }
+ else
+ {
+ // Don't log anything, even errors - this is because this signal could happen anywhere.
+ LLError::setDefaultLevel(LLError::LEVEL_NONE);
+ }
+
+ // Change the signal that we reraise to SIGABRT, so we generate a core dump.
+ signum = SIGABRT;
+ }
+
+ if (LLApp::sLogInSignal)
+ {
+ LL_WARNS() << "Signal handler - Handling fatal signal!" << LL_ENDL;
+ }
+ if (LLApp::isError())
+ {
+ // Received second fatal signal while handling first, just die right now
+ // Set the signal handlers back to default before handling the signal - this makes the next signal wipe out the app.
+ clear_signals();
+
+ if (LLApp::sLogInSignal)
+ {
+ LL_WARNS() << "Signal handler - Got another fatal signal while in the error handler, die now!" << LL_ENDL;
+ }
+ raise(signum);
+ return;
+ }
+
+ if (LLApp::sLogInSignal)
+ {
+ LL_WARNS() << "Signal handler - Flagging error status and waiting for shutdown" << LL_ENDL;
+ }
+
+ if (LLApp::isCrashloggerDisabled()) // Don't gracefully handle any signal, crash and core for a gdb post mortem
+ {
+ clear_signals();
+ LL_WARNS() << "Fatal signal received, not handling the crash here, passing back to operating system" << LL_ENDL;
+ raise(signum);
+ return;
+ }
+
+ // Flag status to ERROR
+ LLApp::setError();
+
+ if (LLApp::sLogInSignal)
+ {
+ LL_WARNS() << "Signal handler - App is stopped, reraising signal" << LL_ENDL;
+ }
+ clear_signals();
+ raise(signum);
+ return;
+ } else {
+ if (LLApp::sLogInSignal)
+ {
+ LL_INFOS() << "Signal handler - Unhandled signal " << signum << ", ignoring!" << LL_ENDL;
+ }
+ }
+ }
}
#if LL_LINUX
#endif
bool unix_post_minidump_callback(const char *dump_dir,
- const char *minidump_id,
- void *context, bool succeeded)
-{
- // Copy minidump file path into fixed buffer in the app instance to avoid
- // heap allocations in a crash handler.
-
- // path format: <dump_dir>/<minidump_id>.dmp
- auto dirPathLength = strlen(dump_dir);
- auto idLength = strlen(minidump_id);
-
- // The path must not be truncated.
- llassert((dirPathLength + idLength + 5) <= LLApp::MAX_MINDUMP_PATH_LENGTH);
-
- char * path = LLApp::instance()->getMiniDumpFilename();
- auto remaining = LLApp::MAX_MINDUMP_PATH_LENGTH;
- strncpy(path, dump_dir, remaining);
- remaining -= dirPathLength;
- path += dirPathLength;
- if (remaining > 0 && dirPathLength > 0 && path[-1] != '/')
- {
- *path++ = '/';
- --remaining;
- }
- if (remaining > 0)
- {
- strncpy(path, minidump_id, remaining);
- remaining -= idLength;
- path += idLength;
- strncpy(path, ".dmp", remaining);
- }
-
- LL_INFOS("CRASHREPORT") << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << LL_ENDL;
- LLApp::runErrorHandler();
-
+ const char *minidump_id,
+ void *context, bool succeeded)
+{
+ // Copy minidump file path into fixed buffer in the app instance to avoid
+ // heap allocations in a crash handler.
+
+ // path format: <dump_dir>/<minidump_id>.dmp
+ auto dirPathLength = strlen(dump_dir);
+ auto idLength = strlen(minidump_id);
+
+ // The path must not be truncated.
+ llassert((dirPathLength + idLength + 5) <= LLApp::MAX_MINDUMP_PATH_LENGTH);
+
+ char * path = LLApp::instance()->getMiniDumpFilename();
+ auto remaining = LLApp::MAX_MINDUMP_PATH_LENGTH;
+ strncpy(path, dump_dir, remaining);
+ remaining -= dirPathLength;
+ path += dirPathLength;
+ if (remaining > 0 && dirPathLength > 0 && path[-1] != '/')
+ {
+ *path++ = '/';
+ --remaining;
+ }
+ if (remaining > 0)
+ {
+ strncpy(path, minidump_id, remaining);
+ remaining -= idLength;
+ path += idLength;
+ strncpy(path, ".dmp", remaining);
+ }
+
+ LL_INFOS("CRASHREPORT") << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << LL_ENDL;
+ LLApp::runErrorHandler();
+
#ifndef LL_RELEASE_FOR_DOWNLOAD
- clear_signals();
- return false;
+ clear_signals();
+ return false;
#else
- return true;
+ return true;
#endif
}
#endif // !WINDOWS