From 680934812598d2c9116303f3245e7a9d60ff58bf Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Tue, 3 Dec 2013 17:06:06 -0800 Subject: Creating a cleaner branch --- indra/llcommon/llapp.cpp | 250 ++++++++++++++++++++++----------------- indra/llcommon/llapp.h | 50 ++------ indra/llcommon/llerrorthread.cpp | 71 ----------- 3 files changed, 151 insertions(+), 220 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 67a98d5fb8..d228f0d830 100755 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -46,7 +46,6 @@ #include "llstl.h" // for DeletePointer() #include "llstring.h" #include "lleventtimer.h" - #include "google_breakpad/exception_handler.h" // @@ -55,6 +54,8 @@ // 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); bool windows_post_minidump_callback(const wchar_t* dump_path, @@ -71,7 +72,10 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *); #if LL_LINUX #include "google_breakpad/minidump_descriptor.h" -bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc, void* context, bool succeeded); +//SPATTERS this is static in my other version not sure why I changed it review. +bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc, + void* context, + bool succeeded); #else // Called by breakpad exception handler after the minidump has been generated. bool unix_post_minidump_callback(const char *dump_dir, @@ -109,11 +113,6 @@ BOOL LLApp::sLogInSignal = FALSE; LLApp::EAppStatus LLApp::sStatus = LLApp::APP_STATUS_STOPPED; // Keeps track of application status LLAppErrorHandler LLApp::sErrorHandler = NULL; BOOL LLApp::sErrorThreadRunning = FALSE; -#if !LL_WINDOWS -LLApp::child_map LLApp::sChildMap; -LLAtomicU32* LLApp::sSigChildCount = NULL; -LLAppChildCallback LLApp::sDefaultChildCallback = NULL; -#endif LLApp::LLApp() : mThreadErrorp(NULL) @@ -128,11 +127,6 @@ void LLApp::commonCtor() LLCommon::initClass(); -#if !LL_WINDOWS - // This must be initialized before the error handler. - sSigChildCount = new LLAtomicU32(0); -#endif - // 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. @@ -149,12 +143,13 @@ void LLApp::commonCtor() // Set the application to this instance. sApplication = this; - + mExceptionHandler = 0; // initialize the buffer to write the minidump filename to // (this is used to avoid allocating memory in the crash handler) - memset(minidump_path, 0, MAX_MINDUMP_PATH_LENGTH); + memset(mMinidumpPath, 0, MAX_MINDUMP_PATH_LENGTH); + mCrashReportPipeStr = L"\\\\.\\pipe\\LLCrashReporterPipe"; } LLApp::LLApp(LLErrorThread *error_thread) : @@ -166,10 +161,6 @@ LLApp::LLApp(LLErrorThread *error_thread) : LLApp::~LLApp() { -#if !LL_WINDOWS - delete sSigChildCount; - sSigChildCount = NULL; -#endif // reclaim live file memory std::for_each(mLiveFiles.begin(), mLiveFiles.end(), DeletePointer()); @@ -244,6 +235,20 @@ bool LLApp::parseCommandOptions(int argc, char** argv) } ++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); + } +#endif + commands[name] = value; } setOptionData(PRIORITY_COMMAND_LINE, commands); @@ -288,6 +293,32 @@ void LLApp::stepFrame() 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() { @@ -295,7 +326,10 @@ void LLApp::setupErrorHandling() // occasionally checks to see if the app is in an error state, and sees if it needs to be run. #if LL_WINDOWS + #if LL_SEND_CRASH_REPORTS + EnableCrashingOnCrashes(); //SPATTERS review + // This sets a callback to handle w32 signals to the console window. // The viewer shouldn't be affected, sicne its a windowed app. SetConsoleCtrlHandler( (PHANDLER_ROUTINE) ConsoleCtrlHandler, TRUE); @@ -304,8 +338,50 @@ void LLApp::setupErrorHandling() if(mExceptionHandler == 0) { llwarns << "adding breakpad exception handler" << llendl; - mExceptionHandler = new google_breakpad::ExceptionHandler( - L"C:\\Temp\\", 0, windows_post_minidump_callback, 0, google_breakpad::ExceptionHandler::HANDLER_ALL); + + std::wostringstream ws; + ws << mCrashReportPipeStr << getPid(); + std::wstring wpipe_name = ws.str(); + std::string ptmp = std::string(wpipe_name.begin(), wpipe_name.end()); + + ::Sleep(3000); //HACK hopefully a static wait won't blow up in my face before google fixes their implementation. +std::cout << "SPATTERS getting here" << std::endl; + + //HACK this for loop is ueless. Breakpad dumbly returns success when the OOP handler isn't initialized. + for (int retries=0;retries<5;++retries) + { + mExceptionHandler = new google_breakpad::ExceptionHandler( + std::wstring(mDumpPath.begin(),mDumpPath.end()), + NULL, //No filter + windows_post_minidump_callback, + 0, + google_breakpad::ExceptionHandler::HANDLER_ALL, + MiniDumpNormal, //Generate a 'normal' minidump. + (WCHAR *)wpipe_name.c_str(), + NULL); //No custom client info. + if (mExceptionHandler) + { + break; + } + else + { + ::Sleep(100); //Wait a tick and try again. + } + } + if (!mExceptionHandler) + { + llwarns << "Failed to initialize OOP exception handler. Defaulting to In Process handling" << llendl; + mExceptionHandler = new google_breakpad::ExceptionHandler( + std::wstring(mDumpPath.begin(),mDumpPath.end()), //Dump path + 0, //dump filename + windows_post_minidump_callback, + 0, + google_breakpad::ExceptionHandler::HANDLER_ALL); + } + if (mExceptionHandler) + { + mExceptionHandler->set_handle_debug_exceptions(true); + } } #endif #else @@ -355,14 +431,18 @@ void LLApp::setupErrorHandling() if(installHandler && (mExceptionHandler == 0)) { - std::string dumpPath = "/tmp/"; - mExceptionHandler = new google_breakpad::ExceptionHandler(dumpPath, 0, &unix_post_minidump_callback, 0, true, 0); + mExceptionHandler = new google_breakpad::ExceptionHandler(mDumpPath, 0, &unix_post_minidump_callback, 0, true, 0); } #elif LL_LINUX if(installHandler && (mExceptionHandler == 0)) { - google_breakpad::MinidumpDescriptor desc("/tmp"); - new google_breakpad::ExceptionHandler(desc, 0, &unix_minidump_callback, 0, true, 0); + if (mDumpPath.empty()) + { + mDumpPath = "/tmp"; + } + google_breakpad::MinidumpDescriptor desc(mDumpPath); + //SPATTERS mExceptionHandler = new google_breakpad::ExceptionHandler(desc, 0, unix_minidump_callback, 0, true, 0); + mExceptionHandler = new google_breakpad::ExceptionHandler(desc, NULL, unix_minidump_callback, NULL, true, -1); } #endif @@ -418,19 +498,35 @@ void LLApp::setError() void LLApp::setMiniDumpDir(const std::string &path) { + if (path.empty()) + { + mDumpPath = "/tmp"; + } + else + { + mDumpPath = path; + } + if(mExceptionHandler == 0) return; #ifdef LL_WINDOWS wchar_t buffer[MAX_MINDUMP_PATH_LENGTH]; - mbstowcs(buffer, path.c_str(), MAX_MINDUMP_PATH_LENGTH); + mbstowcs(buffer, mDumpPath.c_str(), MAX_MINDUMP_PATH_LENGTH); mExceptionHandler->set_dump_path(std::wstring(buffer)); #elif LL_LINUX - google_breakpad::MinidumpDescriptor desc(path); + //google_breakpad::MinidumpDescriptor desc("/tmp"); //path works in debug fails in production inside breakpad lib so linux gets a little less stack reporting until it is patched. + google_breakpad::MinidumpDescriptor desc(mDumpPath); //path works in debug fails in production inside breakpad lib so linux gets a little less stack reporting until it is patched. mExceptionHandler->set_minidump_descriptor(desc); #else - mExceptionHandler->set_dump_path(path); + mExceptionHandler->set_dump_path(mDumpPath); #endif } +void LLApp::setDebugFileNames(const std::string &path) +{ + mStaticDebugFileName = path + "static_debug_info.log"; + mDynamicDebugFileName = path + "dynamic_debug_info.log"; +} + void LLApp::writeMiniDump() { if(mExceptionHandler == 0) return; @@ -507,34 +603,11 @@ bool LLApp::isCrashloggerDisabled() return (sDisableCrashlogger == TRUE); } -#if !LL_WINDOWS -// static -U32 LLApp::getSigChildCount() -{ - if (sSigChildCount) - { - return U32(*sSigChildCount); - } - return 0; -} - -// static -void LLApp::incSigChildCount() -{ - if (sSigChildCount) - { - (*sSigChildCount)++; - } -} - -#endif - - // static int LLApp::getPid() { #if LL_WINDOWS - return 0; + return GetCurrentProcessId(); #else return getpid(); #endif @@ -610,43 +683,6 @@ BOOL ConsoleCtrlHandler(DWORD fdwCtrlType) } #else //!LL_WINDOWS -void LLApp::setChildCallback(pid_t pid, LLAppChildCallback callback) -{ - LLChildInfo child_info; - child_info.mCallback = callback; - LLApp::sChildMap[pid] = child_info; -} - -void LLApp::setDefaultChildCallback(LLAppChildCallback callback) -{ - LLApp::sDefaultChildCallback = callback; -} - -pid_t LLApp::fork() -{ - fflush(NULL); // flush all buffers before the child inherits them - pid_t pid = ::fork(); - if( pid < 0 ) - { - int system_error = errno; - llwarns << "Unable to fork! Operating system error code: " - << system_error << llendl; - } - else if (pid == 0) - { - // Sleep a bit to allow the parent to set up child callbacks. - ms_sleep(10); - - // We need to disable signal handling, because we don't have a - // signal handling thread anymore. - setupErrorHandling(); - } - else - { - llinfos << "Forked child process " << pid << llendl; - } - return pid; -} void setup_signals() { @@ -747,19 +783,6 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *) llinfos << "Signal handler - Got SIGCHLD from " << info->si_pid << llendl; } - // Check result code for all child procs for which we've - // registered callbacks THIS WILL NOT WORK IF SIGCHLD IS SENT - // w/o killing the child (Go, launcher!) - // TODO: Now that we're using SIGACTION, we can actually - // implement the launcher behavior to determine who sent the - // SIGCHLD even if it doesn't result in child termination - if (LLApp::sChildMap.count(info->si_pid)) - { - LLApp::sChildMap[info->si_pid].mGotSigChild = TRUE; - } - - LLApp::incSigChildCount(); - return; case SIGABRT: // Abort just results in termination of the app, no funky error handling. @@ -880,21 +903,26 @@ bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_ // heap allocations in a crash handler. // path format: /.dmp - int dirPathLength = strlen(minidump_desc.path()); + + //HACK: *path points to the buffer in getMiniDumpFilename which has already allocated space + //to avoid doing allocation during crash. + char * path = LLApp::instance()->getMiniDumpFilename(); + int dir_path_len = strlen(path); // The path must not be truncated. - llassert((dirPathLength + 5) <= LLApp::MAX_MINDUMP_PATH_LENGTH); + S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH - dir_path_len; + + llassert( (remaining - strlen(minidump_desc.path())) > 5); - char * path = LLApp::instance()->getMiniDumpFilename(); - S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH; - strncpy(path, minidump_desc.path(), remaining); - remaining -= dirPathLength; - path += dirPathLength; - if (remaining > 0 && dirPathLength > 0 && path[-1] != '/') + path += dir_path_len; + + if (dir_path_len > 0 && path[-1] != '/') { *path++ = '/'; --remaining; } + + strncpy(path, minidump_desc.path(), remaining); llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl; LLApp::runErrorHandler(); @@ -942,7 +970,7 @@ bool unix_post_minidump_callback(const char *dump_dir, strncpy(path, ".dmp", remaining); } - llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl; + llinfos << "generated minidump: " << path << llendl; LLApp::runErrorHandler(); #ifndef LL_RELEASE_FOR_DOWNLOAD @@ -962,7 +990,9 @@ bool windows_post_minidump_callback(const wchar_t* dump_path, MDRawAssertionInfo* assertion, bool succeeded) { + llinfos << "SPATTERS got to here." << llendl; char * path = LLApp::instance()->getMiniDumpFilename(); + std::cout << "SPATTERS path is " << path << std::endl; S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH; size_t bytesUsed; diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index afa06df23e..f90e722803 100755 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -27,6 +27,7 @@ #ifndef LL_LLAPP_H #define LL_LLAPP_H +//#define LL_SEND_CRASH_REPORTS 1 /*SPATTERS*/ #include #include "llrun.h" #include "llsd.h" @@ -42,7 +43,6 @@ class LLLiveFile; #endif typedef void (*LLAppErrorHandler)(); -typedef void (*LLAppChildCallback)(int pid, bool exited, int status); #if !LL_WINDOWS extern S32 LL_SMACKDOWN_SIGNAL; @@ -51,13 +51,6 @@ extern S32 LL_HEARTBEAT_SIGNAL; // Clear all of the signal handlers (which we want to do for the child process when we fork void clear_signals(); -class LLChildInfo -{ -public: - LLChildInfo() : mGotSigChild(FALSE), mCallback(NULL) {} - BOOL mGotSigChild; - LLAppChildCallback mCallback; -}; #endif namespace google_breakpad { @@ -206,10 +199,6 @@ public: static bool isQuitting(); static bool isError(); static bool isExiting(); // Either quitting or error (app is exiting, cleanly or not) -#if !LL_WINDOWS - static U32 getSigChildCount(); - static void incSigChildCount(); -#endif static int getPid(); /** @name Error handling methods */ @@ -238,32 +227,16 @@ public: // change the directory where Breakpad minidump files are written to void setMiniDumpDir(const std::string &path); + void setDebugFileNames(const std::string &path); // Return the Google Breakpad minidump filename after a crash. - char *getMiniDumpFilename() { return minidump_path; } + char *getMiniDumpFilename() { return mMinidumpPath; } + std::string* getStaticDebugFile() { return &mStaticDebugFileName; } + std::string* getDynamicDebugFile() { return &mDynamicDebugFileName; } // Write out a Google Breakpad minidump file. void writeMiniDump(); -#if !LL_WINDOWS - // - // Child process handling (Unix only for now) - // - // Set a callback to be run on exit of a child process - // WARNING! This callback is run from the signal handler due to - // Linux threading requiring waitpid() to be called from the thread that spawned the process. - // At some point I will make this more behaved, but I'm not going to fix this right now - djs - void setChildCallback(pid_t pid, LLAppChildCallback callback); - - // The child callback to run if no specific handler is set - void setDefaultChildCallback(LLAppChildCallback callback); - - // Fork and do the proper signal handling/error handling mojo - // *NOTE: You need to make sure your signal handling callback is - // correct after you fork, because not all threads are duplicated - // when you fork! - pid_t fork(); -#endif /** * @brief Get a reference to the application runner @@ -286,13 +259,9 @@ protected: static EAppStatus sStatus; // Reflects current application status static BOOL sErrorThreadRunning; // Set while the error thread is running static BOOL sDisableCrashlogger; // Let the OS handle crashes for us. + std::wstring mCrashReportPipeStr; //Name of pipe to use for crash reporting. -#if !LL_WINDOWS - static LLAtomicU32* sSigChildCount; // Number of SIGCHLDs received. - typedef std::map child_map; // Map key is a PID - static child_map sChildMap; - static LLAppChildCallback sDefaultChildCallback; -#endif + std::string mDumpPath; //output path for google breakpad. Dependency workaround. /** * @brief This method is called once a frame to do once a frame tasks. @@ -303,7 +272,10 @@ private: void startErrorThread(); // Contains the filename of the minidump file after a crash. - char minidump_path[MAX_MINDUMP_PATH_LENGTH]; + char mMinidumpPath[MAX_MINDUMP_PATH_LENGTH]; + + std::string mStaticDebugFileName; + std::string mDynamicDebugFileName; // *NOTE: On Windows, we need a routine to reset the structured // exception handler when some evil driver has taken it over for diff --git a/indra/llcommon/llerrorthread.cpp b/indra/llcommon/llerrorthread.cpp index 950fcd6e83..ebfbe19ff7 100755 --- a/indra/llcommon/llerrorthread.cpp +++ b/indra/llcommon/llerrorthread.cpp @@ -109,79 +109,8 @@ void LLErrorThread::run() llinfos << "thread_error - Waiting for an error" << llendl; S32 counter = 0; -#if !LL_WINDOWS - U32 last_sig_child_count = 0; -#endif while (! (LLApp::isError() || LLApp::isStopped())) { -#if !LL_WINDOWS - // Check whether or not the main thread had a sig child we haven't handled. - U32 current_sig_child_count = LLApp::getSigChildCount(); - if (last_sig_child_count != current_sig_child_count) - { - int status = 0; - pid_t child_pid = 0; - last_sig_child_count = current_sig_child_count; - if (LLApp::sLogInSignal) - { - llinfos << "thread_error handling SIGCHLD #" << current_sig_child_count << llendl; - } - for (LLApp::child_map::iterator iter = LLApp::sChildMap.begin(); iter != LLApp::sChildMap.end();) - { - child_pid = iter->first; - LLChildInfo &child_info = iter->second; - // check the status of *all* children, in case we missed a signal - if (0 != waitpid(child_pid, &status, WNOHANG)) - { - bool exited = false; - int exit_status = -1; - get_child_status(status, exit_status, exited, LLApp::sLogInSignal); - - if (child_info.mCallback) - { - if (LLApp::sLogInSignal) - { - llinfos << "Signal handler - Running child callback" << llendl; - } - child_info.mCallback(child_pid, exited, status); - } - LLApp::sChildMap.erase(iter++); - } - else - { - // Child didn't terminate, yet we got a sigchild somewhere... - if (child_info.mGotSigChild && child_info.mCallback) - { - child_info.mCallback(child_pid, false, 0); - } - child_info.mGotSigChild = FALSE; - iter++; - } - } - - // check the status of *all* children, in case we missed a signal - // Same as above, but use the default child callback - while(0 < (child_pid = waitpid( -1, &status, WNOHANG ))) - { - if (0 != waitpid(child_pid, &status, WNOHANG)) - { - bool exited = false; - int exit_status = -1; - get_child_status(status, exit_status, exited, LLApp::sLogInSignal); - if (LLApp::sDefaultChildCallback) - { - if (LLApp::sLogInSignal) - { - llinfos << "Signal handler - Running default child callback" << llendl; - } - LLApp::sDefaultChildCallback(child_pid, true, status); - } - } - } - } - - -#endif ms_sleep(10); counter++; } -- cgit v1.2.3 From ce2cd00cc516dbff712956875d4565b8d26e44ca Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Wed, 4 Dec 2013 19:57:11 -0800 Subject: Removed debugging code. --- indra/llcommon/llapp.cpp | 9 ++------- indra/llcommon/llapp.h | 1 - 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index d228f0d830..b219f66a29 100755 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -72,8 +72,7 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *); #if LL_LINUX #include "google_breakpad/minidump_descriptor.h" -//SPATTERS this is static in my other version not sure why I changed it review. -bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc, +static bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc, void* context, bool succeeded); #else @@ -328,7 +327,7 @@ void LLApp::setupErrorHandling() #if LL_WINDOWS #if LL_SEND_CRASH_REPORTS - EnableCrashingOnCrashes(); //SPATTERS review + EnableCrashingOnCrashes(); // This sets a callback to handle w32 signals to the console window. // The viewer shouldn't be affected, sicne its a windowed app. @@ -345,7 +344,6 @@ void LLApp::setupErrorHandling() std::string ptmp = std::string(wpipe_name.begin(), wpipe_name.end()); ::Sleep(3000); //HACK hopefully a static wait won't blow up in my face before google fixes their implementation. -std::cout << "SPATTERS getting here" << std::endl; //HACK this for loop is ueless. Breakpad dumbly returns success when the OOP handler isn't initialized. for (int retries=0;retries<5;++retries) @@ -441,7 +439,6 @@ std::cout << "SPATTERS getting here" << std::endl; mDumpPath = "/tmp"; } google_breakpad::MinidumpDescriptor desc(mDumpPath); - //SPATTERS mExceptionHandler = new google_breakpad::ExceptionHandler(desc, 0, unix_minidump_callback, 0, true, 0); mExceptionHandler = new google_breakpad::ExceptionHandler(desc, NULL, unix_minidump_callback, NULL, true, -1); } #endif @@ -990,9 +987,7 @@ bool windows_post_minidump_callback(const wchar_t* dump_path, MDRawAssertionInfo* assertion, bool succeeded) { - llinfos << "SPATTERS got to here." << llendl; char * path = LLApp::instance()->getMiniDumpFilename(); - std::cout << "SPATTERS path is " << path << std::endl; S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH; size_t bytesUsed; diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index f90e722803..c86625b6eb 100755 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -27,7 +27,6 @@ #ifndef LL_LLAPP_H #define LL_LLAPP_H -//#define LL_SEND_CRASH_REPORTS 1 /*SPATTERS*/ #include #include "llrun.h" #include "llsd.h" -- cgit v1.2.3 From ea7e6a5174f1bdfc51ada864736d354706534d8b Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Tue, 14 Jan 2014 15:28:35 -0800 Subject: Some cleanup of string to wstring conversion and vice versa. --- indra/llcommon/llapp.cpp | 33 +++++++++------------ indra/llcommon/stringize.h | 51 ++++++++++++++++++++++++++++++--- indra/llcommon/tests/stringize_test.cpp | 20 +++++++++++++ 3 files changed, 80 insertions(+), 24 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index b219f66a29..e75e741db8 100755 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -47,6 +47,7 @@ #include "llstring.h" #include "lleventtimer.h" #include "google_breakpad/exception_handler.h" +#include "stringize.h" // // Signal handling @@ -338,10 +339,7 @@ void LLApp::setupErrorHandling() { llwarns << "adding breakpad exception handler" << llendl; - std::wostringstream ws; - ws << mCrashReportPipeStr << getPid(); - std::wstring wpipe_name = ws.str(); - std::string ptmp = std::string(wpipe_name.begin(), wpipe_name.end()); + const std::wstring wpipe_name(wstringize(getPid()); ::Sleep(3000); //HACK hopefully a static wait won't blow up in my face before google fixes their implementation. @@ -349,13 +347,13 @@ void LLApp::setupErrorHandling() for (int retries=0;retries<5;++retries) { mExceptionHandler = new google_breakpad::ExceptionHandler( - std::wstring(mDumpPath.begin(),mDumpPath.end()), + wstringize(mDumpPath), NULL, //No filter windows_post_minidump_callback, 0, google_breakpad::ExceptionHandler::HANDLER_ALL, MiniDumpNormal, //Generate a 'normal' minidump. - (WCHAR *)wpipe_name.c_str(), + strinize(wpipe_name).c_str(), NULL); //No custom client info. if (mExceptionHandler) { @@ -370,7 +368,7 @@ void LLApp::setupErrorHandling() { llwarns << "Failed to initialize OOP exception handler. Defaulting to In Process handling" << llendl; mExceptionHandler = new google_breakpad::ExceptionHandler( - std::wstring(mDumpPath.begin(),mDumpPath.end()), //Dump path + wstringize(mDumpPath), 0, //dump filename windows_post_minidump_callback, 0, @@ -900,26 +898,21 @@ bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_ // heap allocations in a crash handler. // path format: /.dmp - - //HACK: *path points to the buffer in getMiniDumpFilename which has already allocated space - //to avoid doing allocation during crash. - char * path = LLApp::instance()->getMiniDumpFilename(); - int dir_path_len = strlen(path); + int dirPathLength = strlen(minidump_desc.path()); // The path must not be truncated. - S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH - dir_path_len; - - llassert( (remaining - strlen(minidump_desc.path())) > 5); + llassert((dirPathLength + 5) <= LLApp::MAX_MINDUMP_PATH_LENGTH); - path += dir_path_len; - - if (dir_path_len > 0 && path[-1] != '/') + char * path = LLApp::instance()->getMiniDumpFilename(); + S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH; + strncpy(path, minidump_desc.path(), remaining); + remaining -= dirPathLength; + path += dirPathLength; + if (remaining > 0 && dirPathLength > 0 && path[-1] != '/') { *path++ = '/'; --remaining; } - - strncpy(path, minidump_desc.path(), remaining); llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl; LLApp::runErrorHandler(); diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h index 72f2e58ce1..acae74b584 100755 --- a/indra/llcommon/stringize.h +++ b/indra/llcommon/stringize.h @@ -31,20 +31,63 @@ #include #include +#include /** - * stringize(item) encapsulates an idiom we use constantly, using + * gstringize(item) encapsulates an idiom we use constantly, using * operator<<(std::ostringstream&, TYPE) followed by std::ostringstream::str() + * or their wstring equivalents * to render a string expressing some item. */ -template -std::string stringize(const T& item) +template +std::basic_string gstringize(const T& item) { - std::ostringstream out; + std::basic_ostringstream out; out << item; return out.str(); } +/** + *partial specialization of stringize for handling wstring + *TODO: we should have similar specializations for wchar_t[] but not until it is needed. + */ +inline std::string stringize(const std::wstring& item) +{ + llwarns << "WARNING: Possible narrowing" << llendl; + + std::string s; + + s = wstring_to_utf8str(item); + return gstringize(s); +} + +/** + * Specialization of gstringize for std::string return types + */ +template +std::string stringize(const T& item) +{ + return gstringize(item); +} + +/** + * Specialization for generating wstring from string. + * Both a convenience function and saves a miniscule amount of overhead. + */ +inline std::wstring wstringize(const std::string& item) +{ + return gstringize(item.c_str()); +} + +/** + * Specialization of gstringize for std::wstring return types + */ +template +std::wstring wstringize(const T& item) +{ + return gstringize(item); +} + /** * stringize_f(functor) */ diff --git a/indra/llcommon/tests/stringize_test.cpp b/indra/llcommon/tests/stringize_test.cpp index 3d34f23998..3e4ca548e5 100755 --- a/indra/llcommon/tests/stringize_test.cpp +++ b/indra/llcommon/tests/stringize_test.cpp @@ -67,6 +67,8 @@ namespace tut llsd["i"] = i; llsd["d"] = d; llsd["abc"] = abc; + def = L"def ghi"; + } char c; @@ -76,6 +78,7 @@ namespace tut float f; double d; std::string abc; + std::wstring def; LLSD llsd; }; typedef test_group stringize_group; @@ -92,6 +95,7 @@ namespace tut ensure_equals(stringize(f), "3.14159"); ensure_equals(stringize(d), "3.14159"); ensure_equals(stringize(abc), "abc def"); + ensure_equals(stringize(def), "def ghi"); //Will generate llwarns due to narrowing. ensure_equals(stringize(llsd), "{'abc':'abc def','d':r3.14159,'i':i34}"); } @@ -101,4 +105,20 @@ namespace tut ensure_equals(STRINGIZE("c is " << c), "c is c"); ensure_equals(STRINGIZE(std::setprecision(4) << d), "3.142"); } + + template<> template<> + void stringize_object::test<3>() + { + //Tests rely on validity of wstring_to_utf8str() + ensure_equals(wstring_to_utf8str(wstringize(c)), wstring_to_utf8str(L"c")); + ensure_equals(wstring_to_utf8str(wstringize(s)), wstring_to_utf8str(L"17")); + ensure_equals(wstring_to_utf8str(wstringize(i)), wstring_to_utf8str(L"34")); + ensure_equals(wstring_to_utf8str(wstringize(l)), wstring_to_utf8str(L"68")); + ensure_equals(wstring_to_utf8str(wstringize(f)), wstring_to_utf8str(L"3.14159")); + ensure_equals(wstring_to_utf8str(wstringize(d)), wstring_to_utf8str(L"3.14159")); + ensure_equals(wstring_to_utf8str(wstringize(abc)), wstring_to_utf8str(L"abc def")); + ensure_equals(wstring_to_utf8str(wstringize(abc)), wstring_to_utf8str(wstringize(abc.c_str()))); + ensure_equals(wstring_to_utf8str(wstringize(def)), wstring_to_utf8str(L"def ghi")); + // ensure_equals(wstring_to_utf8str(wstringize(llsd)), wstring_to_utf8str(L"{'abc':'abc def','d':r3.14159,'i':i34}")); + } } // namespace tut -- cgit v1.2.3 From 00aa2fee6d3841788d7146e5d6d66d0bceff9c3f Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Wed, 15 Jan 2014 21:24:55 -0800 Subject: Fixes from Windows build including utf-16 to utf-8 conversions. --- indra/llcommon/llstring.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index f9702868c8..16a19e7021 100755 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -518,10 +518,13 @@ LL_COMMON_API S32 wchar_to_utf8chars(llwchar inchar, char* outchars); LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str, S32 len); LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str); - LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str, S32 len); LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str); +#if LL_WINDOWS +inline std::string wstring_to_utf8str(const llutf16string &utf16str) { return utf16str_to_utf8str(utf16str);} +#endif + // Length of this UTF32 string in bytes when transformed to UTF8 LL_COMMON_API S32 wstring_utf8_length(const LLWString& wstr); -- cgit v1.2.3 From d9b09804910ae47ab4cecdd2cdd6fa2490fa748e Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Thu, 16 Jan 2014 10:37:10 -0800 Subject: Fixed syntax issue that was wrapped in #if that didn't get hit until we got to teamcity. oops. --- indra/llcommon/llapp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index e75e741db8..3312f6e3b0 100755 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -353,7 +353,7 @@ void LLApp::setupErrorHandling() 0, google_breakpad::ExceptionHandler::HANDLER_ALL, MiniDumpNormal, //Generate a 'normal' minidump. - strinize(wpipe_name).c_str(), + stringize(wpipe_name).c_str(), NULL); //No custom client info. if (mExceptionHandler) { -- cgit v1.2.3 From 033f0e8ccee111d20a0af5f39909d7b8e76717ac Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Thu, 16 Jan 2014 13:46:08 -0800 Subject: What passess in MSVC may not pass in Teamcity. --- indra/llcommon/llapp.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 3312f6e3b0..cb06a6a8da 100755 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -339,7 +339,8 @@ void LLApp::setupErrorHandling() { llwarns << "adding breakpad exception handler" << llendl; - const std::wstring wpipe_name(wstringize(getPid()); + const std::wstring wpipe_name(wstringize(getPid())); + const std::string pipe_name(stringize(wpipe_name)); ::Sleep(3000); //HACK hopefully a static wait won't blow up in my face before google fixes their implementation. @@ -353,7 +354,7 @@ void LLApp::setupErrorHandling() 0, google_breakpad::ExceptionHandler::HANDLER_ALL, MiniDumpNormal, //Generate a 'normal' minidump. - stringize(wpipe_name).c_str(), + pipe_name.c_str(), NULL); //No custom client info. if (mExceptionHandler) { -- cgit v1.2.3 From ace79d97198aeaf8fae0b65fdfa9613b2b3627a6 Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Tue, 21 Jan 2014 17:59:39 -0800 Subject: Heavy-handed attempt at fixing crashandloop hang. --- indra/llcommon/llerror.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index d2af004cde..cc42bef0c9 100755 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -1197,14 +1197,15 @@ namespace LLError #endif void crashAndLoop(const std::string& message) { - // Now, we go kaboom! - int* make_me_crash = NULL; - - *make_me_crash = 0; - while(true) { // Loop forever, in case the crash didn't work? + + // Now, we go kaboom! + int* make_me_crash = NULL; + + *make_me_crash = 0; + } // this is an attempt to let Coverity and other semantic scanners know that this function won't be returning ever. -- cgit v1.2.3 From d223687fb8f82cc9ede21942a6c7e5c5a4d1ed3d Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Wed, 22 Jan 2014 10:21:29 -0800 Subject: char vs wchar_t FIGHT --- indra/llcommon/llapp.cpp | 2 +- indra/llcommon/llapp.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index cb06a6a8da..dabed2ba7c 100755 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -354,7 +354,7 @@ void LLApp::setupErrorHandling() 0, google_breakpad::ExceptionHandler::HANDLER_ALL, MiniDumpNormal, //Generate a 'normal' minidump. - pipe_name.c_str(), + wpipe_name.c_str(), NULL); //No custom client info. if (mExceptionHandler) { diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index c86625b6eb..3349444332 100755 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -31,7 +31,7 @@ #include "llrun.h" #include "llsd.h" #include "lloptioninterface.h" - +#define LL_SEND_CRASH_REPORTS 1 // Forward declarations template class LLAtomic32; typedef LLAtomic32 LLAtomicU32; -- cgit v1.2.3 From efc41f95bb1dd79248f9bc6b2389b35d15ba5c49 Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Wed, 22 Jan 2014 10:23:50 -0800 Subject: Removed debug line. --- indra/llcommon/llapp.h | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index 3349444332..828965b1fa 100755 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -31,7 +31,6 @@ #include "llrun.h" #include "llsd.h" #include "lloptioninterface.h" -#define LL_SEND_CRASH_REPORTS 1 // Forward declarations template class LLAtomic32; typedef LLAtomic32 LLAtomicU32; -- cgit v1.2.3 From 33b0ae6ebf8a085a8795a9e5b02455fb7ebf0e6f Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Thu, 23 Jan 2014 17:04:33 -0800 Subject: Debugging changes. fixed broken pipe. --- indra/llcommon/llapp.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index dabed2ba7c..7ef4e7fb92 100755 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -339,16 +339,17 @@ void LLApp::setupErrorHandling() { llwarns << "adding breakpad exception handler" << llendl; - const std::wstring wpipe_name(wstringize(getPid())); - const std::string pipe_name(stringize(wpipe_name)); + std::wstring wpipe_name; + wpipe_name = mCrashReportPipeStr + wstringize(getPid()); ::Sleep(3000); //HACK hopefully a static wait won't blow up in my face before google fixes their implementation. + const std::wstring wdump_path(wstringize(mDumpPath)); //HACK this for loop is ueless. Breakpad dumbly returns success when the OOP handler isn't initialized. for (int retries=0;retries<5;++retries) { mExceptionHandler = new google_breakpad::ExceptionHandler( - wstringize(mDumpPath), + wdump_path, NULL, //No filter windows_post_minidump_callback, 0, -- cgit v1.2.3 From 262f8b84737587fd5c2de38c34ff7a5594cca174 Mon Sep 17 00:00:00 2001 From: obscurestar Date: Sun, 26 Jan 2014 02:56:23 -0800 Subject: Was not using correct name for results of file search. --- indra/llcommon/llapp.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 7ef4e7fb92..2c5da5d2a7 100755 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -900,21 +900,26 @@ bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_ // heap allocations in a crash handler. // path format: /.dmp - int dirPathLength = strlen(minidump_desc.path()); + + //HACK: *path points to the buffer in getMiniDumpFilename which has already allocated space + //to avoid doing allocation during crash. + char * path = LLApp::instance()->getMiniDumpFilename(); + int dir_path_len = strlen(path); // The path must not be truncated. - llassert((dirPathLength + 5) <= LLApp::MAX_MINDUMP_PATH_LENGTH); + S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH - dir_path_len; + + llassert( (remaining - strlen(minidump_desc.path())) > 5); - char * path = LLApp::instance()->getMiniDumpFilename(); - S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH; - strncpy(path, minidump_desc.path(), remaining); - remaining -= dirPathLength; - path += dirPathLength; - if (remaining > 0 && dirPathLength > 0 && path[-1] != '/') + path += dir_path_len; + + if (dir_path_len > 0 && path[-1] != '/') { *path++ = '/'; --remaining; } + + strncpy(path, minidump_desc.path(), remaining); llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl; LLApp::runErrorHandler(); -- cgit v1.2.3 From 352d32934c1ca539ef7b4b53c9842b9cce48b01a Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Sun, 26 Jan 2014 09:57:33 -0800 Subject: Merged. --- indra/llcommon/llapp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 2c5da5d2a7..016d2c3526 100755 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -349,7 +349,7 @@ void LLApp::setupErrorHandling() for (int retries=0;retries<5;++retries) { mExceptionHandler = new google_breakpad::ExceptionHandler( - wdump_path, + L"", //wdump_path, NULL, //No filter windows_post_minidump_callback, 0, -- cgit v1.2.3 From 307290bdbc22943383792c2f347331b805700eb3 Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Sun, 26 Jan 2014 10:02:44 -0800 Subject: Debug removal. --- indra/llcommon/llapp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 016d2c3526..0966137071 100755 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -349,7 +349,7 @@ void LLApp::setupErrorHandling() for (int retries=0;retries<5;++retries) { mExceptionHandler = new google_breakpad::ExceptionHandler( - L"", //wdump_path, + /wdump_path, NULL, //No filter windows_post_minidump_callback, 0, -- cgit v1.2.3 From 57d7cbb8375ca59bcb3d3643e4013b88e8883822 Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Sun, 26 Jan 2014 17:30:02 -0800 Subject: typo. Yay. --- indra/llcommon/llapp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 0966137071..2c5da5d2a7 100755 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -349,7 +349,7 @@ void LLApp::setupErrorHandling() for (int retries=0;retries<5;++retries) { mExceptionHandler = new google_breakpad::ExceptionHandler( - /wdump_path, + wdump_path, NULL, //No filter windows_post_minidump_callback, 0, -- cgit v1.2.3 From d2bb4dae980a887a30b206875d8f9419901ed66a Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Fri, 7 Mar 2014 14:58:22 -0800 Subject: Fixes for crash reporter startup race condition, crash reporter CPU use, Secondlife.log filehandle, XP Crash. --- indra/llcommon/llapp.cpp | 25 +++++++++++-------------- indra/llcommon/llfile.cpp | 31 +++++++++++++++++++++++++++++++ indra/llcommon/llfile.h | 2 ++ 3 files changed, 44 insertions(+), 14 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 2c5da5d2a7..5c8fff051f 100755 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -342,12 +342,13 @@ void LLApp::setupErrorHandling() std::wstring wpipe_name; wpipe_name = mCrashReportPipeStr + wstringize(getPid()); - ::Sleep(3000); //HACK hopefully a static wait won't blow up in my face before google fixes their implementation. const std::wstring wdump_path(wstringize(mDumpPath)); - //HACK this for loop is ueless. Breakpad dumbly returns success when the OOP handler isn't initialized. - for (int retries=0;retries<5;++retries) + int retries = 30; + for (; retries > 0; --retries) { + if (mExceptionHandler != 0) delete mExceptionHandler; + mExceptionHandler = new google_breakpad::ExceptionHandler( wdump_path, NULL, //No filter @@ -357,25 +358,20 @@ void LLApp::setupErrorHandling() MiniDumpNormal, //Generate a 'normal' minidump. wpipe_name.c_str(), NULL); //No custom client info. - if (mExceptionHandler) + if (mExceptionHandler->IsOutOfProcess()) { + LL_INFOS("CRASHREPORT") << "Successfully attached to Out of Process exception handler." << LL_ENDL; break; } else { + LL_WARNS("CRASHREPORT") << "Unable to attach to Out of Process exception handler. " << retries << " retries remaining." << LL_ENDL; ::Sleep(100); //Wait a tick and try again. } } - if (!mExceptionHandler) - { - llwarns << "Failed to initialize OOP exception handler. Defaulting to In Process handling" << llendl; - mExceptionHandler = new google_breakpad::ExceptionHandler( - wstringize(mDumpPath), - 0, //dump filename - windows_post_minidump_callback, - 0, - google_breakpad::ExceptionHandler::HANDLER_ALL); - } + + if (retries == 0) LL_WARNS("CRASHREPORT") << "Unable to attach to Out of Process exception handler." << LL_ENDL; + if (mExceptionHandler) { mExceptionHandler->set_handle_debug_exceptions(true); @@ -991,6 +987,7 @@ bool windows_post_minidump_callback(const wchar_t* dump_path, S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH; size_t bytesUsed; + LL_INFOS("MINIDUMPCALLBACK") << "Dump file was generated." << LL_ENDL; bytesUsed = wcstombs(path, dump_path, static_cast(remaining)); remaining -= bytesUsed; path += bytesUsed; diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index c3a0f0bfe0..761d7f430c 100755 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -265,6 +265,37 @@ int LLFile::rename(const std::string& filename, const std::string& newname) return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc); } +bool LLFile::copy(const std::string from, const std::string to) +{ + bool copied = false; + LLFILE* in = LLFile::fopen(from, "rb"); /* Flawfinder: ignore */ + if (in) + { + LLFILE* out = LLFile::fopen(to, "wb"); /* Flawfinder: ignore */ + if (out) + { + char buf[16384]; /* Flawfinder: ignore */ + size_t readbytes; + bool write_ok = true; + while(write_ok && (readbytes = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */ + { + if (fwrite(buf, 1, readbytes, out) != readbytes) + { + LL_WARNS("LLFile") << "Short write" << LL_ENDL; + write_ok = false; + } + } + if ( write_ok ) + { + copied = true; + } + fclose(out); + } + fclose(in); + } + return copied; +} + int LLFile::stat(const std::string& filename, llstat* filestatus) { #if LL_WINDOWS diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index d59e68367e..f56b22bf9a 100755 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -75,6 +75,8 @@ public: static int rmdir(const std::string& filename); static int remove(const std::string& filename); static int rename(const std::string& filename,const std::string& newname); + static bool copy(const std::string from, const std::string to); + static int stat(const std::string& filename,llstat* file_status); static bool isdir(const std::string& filename); static bool isfile(const std::string& filename); -- cgit v1.2.3 From 8d5b933ad0c1b96778d0460f142ceadaf4be11fb Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Thu, 13 Mar 2014 23:33:12 +0000 Subject: Probable fix for linux hang. --- indra/llcommon/llerror.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index dd36eca8ba..853f279c95 100755 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -1197,15 +1197,14 @@ namespace LLError #endif void crashAndLoop(const std::string& message) { + // Now, we go kaboom! + int* make_me_crash = NULL; + + *make_me_crash = 0; + while(true) { // Loop forever, in case the crash didn't work? - - // Now, we go kaboom! - int* make_me_crash = NULL; - - *make_me_crash = 0; - } // this is an attempt to let Coverity and other semantic scanners know that this function won't be returning ever. -- cgit v1.2.3