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.cpp180
1 files changed, 46 insertions, 134 deletions
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 9729f68d23..c1dce97632 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -52,15 +52,7 @@
//
// Signal handling
-//
-// Windows uses structured exceptions, so it's handled a bit differently.
-//
-#if LL_WINDOWS
-#include "windows.h"
-
-LONG WINAPI default_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop);
-BOOL ConsoleCtrlHandler(DWORD fdwCtrlType);
-#else
+#ifndef LL_WINDOWS
# include <signal.h>
# include <unistd.h> // for fork()
void setup_signals();
@@ -87,18 +79,14 @@ S32 LL_HEARTBEAT_SIGNAL = SIGUSR2;
S32 LL_SMACKDOWN_SIGNAL = (SIGRTMAX >= 0) ? (SIGRTMAX-1) : SIGUSR1;
S32 LL_HEARTBEAT_SIGNAL = (SIGRTMAX >= 0) ? (SIGRTMAX-0) : SIGUSR2;
# endif // LL_DARWIN
-#endif // LL_WINDOWS
+#endif // !LL_WINDOWS
// the static application instance
LLApp* LLApp::sApplication = NULL;
// Allows the generation of core files for post mortem under gdb
// and disables crashlogger
-BOOL LLApp::sDisableCrashlogger = FALSE;
-
-// Local flag for whether or not to do logging in signal handlers.
-//static
-BOOL LLApp::sLogInSignal = FALSE;
+bool LLApp::sDisableCrashlogger = false;
// static
// Keeps track of application status
@@ -207,9 +195,9 @@ bool LLApp::parseCommandOptions(int argc, char** argv)
#if LL_WINDOWS
//Windows changed command line parsing. Deal with it.
- S32 slen = value.length() - 1;
- S32 start = 0;
- S32 end = slen;
+ size_t slen = value.length() - 1;
+ size_t start = 0;
+ size_t end = slen;
if (argv[ii][start]=='"')start++;
if (argv[ii][end]=='"')end--;
if (start!=0 || end!=slen)
@@ -234,7 +222,7 @@ bool LLApp::parseCommandOptions(int argc, wchar_t** wargv)
if(wargv[ii][0] != '-')
{
LL_INFOS() << "Did not find option identifier while parsing token: "
- << wargv[ii] << LL_ENDL;
+ << (intptr_t)wargv[ii] << LL_ENDL;
return false;
}
int offset = 1;
@@ -272,9 +260,9 @@ bool LLApp::parseCommandOptions(int argc, wchar_t** wargv)
#if LL_WINDOWS
//Windows changed command line parsing. Deal with it.
- S32 slen = value.length() - 1;
- S32 start = 0;
- S32 end = slen;
+ size_t slen = value.length() - 1;
+ size_t start = 0;
+ size_t end = slen;
if (wargv[ii][start]=='"')start++;
if (wargv[ii][end]=='"')end--;
if (start!=0 || end!=slen)
@@ -322,37 +310,10 @@ void LLApp::stepFrame()
{
LLFrameTimer::updateFrameTime();
LLFrameTimer::updateFrameCount();
- LLEventTimer::updateClass();
+ LLCallbackList::instance().callFunctions();
mRunner.run();
}
-#if LL_WINDOWS
-//The following code is needed for 32-bit apps on 64-bit windows to keep it from eating
-//crashes. It is a lovely undocumented 'feature' in SP1 of Windows 7. An excellent
-//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);
- }
- }
-}
-#endif
-
void LLApp::setupErrorHandling(bool second_instance)
{
// Error handling is done by starting up an error handling thread, which just sleeps and
@@ -408,6 +369,9 @@ static std::map<LLApp::EAppStatus, const char*> statusDesc
// static
void LLApp::setStatus(EAppStatus status)
{
+ auto status_it = statusDesc.find(status);
+ std::string status_text = status_it != statusDesc.end() ? std::string(status_it->second) : std::to_string(status);
+ LL_INFOS() << "status: " << status_text << LL_ENDL;
// notify everyone waiting on sStatus any time its value changes
sStatus.set_all(status);
@@ -416,18 +380,7 @@ void LLApp::setStatus(EAppStatus status)
if (! LLEventPumps::wasDeleted())
{
// notify interested parties of status change
- LLSD statsd;
- auto found = statusDesc.find(status);
- if (found != statusDesc.end())
- {
- statsd = found->second;
- }
- else
- {
- // unknown status? at least report value
- statsd = LLSD::Integer(status);
- }
- LLEventPumps::instance().obtain("LLApp").post(llsd::map("status", statsd));
+ LLEventPumps::instance().obtain("LLApp").post(llsd::map("status", status_text));
}
}
@@ -503,13 +456,13 @@ bool LLApp::isExiting()
void LLApp::disableCrashlogger()
{
- sDisableCrashlogger = TRUE;
+ sDisableCrashlogger = true;
}
// static
bool LLApp::isCrashloggerDisabled()
{
- return (sDisableCrashlogger == TRUE);
+ return sDisableCrashlogger;
}
// static
@@ -522,77 +475,34 @@ int LLApp::getPid()
#endif
}
-#if LL_WINDOWS
-LONG WINAPI default_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop)
+// static
+void LLApp::notifyOutOfDiskSpace()
{
- // Translate the signals/exceptions into cross-platform stuff
- // Windows implementation
+ static const U32Seconds min_interval = U32Seconds(60);
+ static U32Seconds min_time_to_send = U32Seconds(0);
+ U32Seconds now = LLTimer::getTotalTime();
+ if (now < min_time_to_send)
+ return;
- // Make sure the user sees something to indicate that the app crashed.
- LONG retval;
+ min_time_to_send = now + min_interval;
- if (LLApp::isError())
+ if (LLApp* app = instance())
{
- LL_WARNS() << "Got another fatal signal while in the error handler, die now!" << LL_ENDL;
- retval = EXCEPTION_EXECUTE_HANDLER;
- return retval;
+ app->sendOutOfDiskSpaceNotification();
}
-
- // 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())
+ else
{
- ms_sleep(10);
+ LL_WARNS() << "No app instance" << LL_ENDL;
}
-
- //
- // 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;
}
-// Win32 doesn't support signals. This is used instead.
-BOOL ConsoleCtrlHandler(DWORD fdwCtrlType)
+// virtual
+void LLApp::sendOutOfDiskSpaceNotification()
{
- 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;
- }
+ LL_WARNS() << "Should never be called" << LL_ENDL; // Should be overridden
}
-#else //!LL_WINDOWS
-
+#ifndef LL_WINDOWS
void setup_signals()
{
//
@@ -682,6 +592,10 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
// We do the somewhat sketchy operation of blocking in here until the error handler
// has gracefully stopped the app.
+ // FIXME(brad) - we are using this handler for asynchronous signals as well, so sLogInSignal is currently
+ // disabled for safety. we need to find a way to selectively reenable it when it is safe.
+ // see issue secondlife/viewer#2566
+
if (LLApp::sLogInSignal)
{
LL_INFOS() << "Signal handler - Got signal " << signum << " - " << apr_signal_description_get(signum) << LL_ENDL;
@@ -691,9 +605,10 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
switch (signum)
{
case SIGCHLD:
+ case SIGHUP:
if (LLApp::sLogInSignal)
{
- LL_INFOS() << "Signal handler - Got SIGCHLD from " << info->si_pid << LL_ENDL;
+ LL_INFOS() << "Signal handler - Got SIGCHLD or SIGHUP from " << info->si_pid << LL_ENDL;
}
return;
@@ -708,11 +623,10 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
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;
+ LL_WARNS() << "Signal handler - Got SIGINT, or TERM, exiting gracefully" << LL_ENDL;
}
// Graceful exit
// Just set our state to quitting, not error
@@ -759,6 +673,7 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
{
LL_WARNS() << "Signal handler - Handling fatal signal!" << LL_ENDL;
}
+
if (LLApp::isError())
{
// Received second fatal signal while handling first, just die right now
@@ -796,18 +711,15 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
clear_signals();
raise(signum);
return;
- } else {
- if (LLApp::sLogInSignal)
- {
- LL_INFOS() << "Signal handler - Unhandled signal " << signum << ", ignoring!" << LL_ENDL;
- }
+ }
+
+ 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)