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/newview/CMakeLists.txt | 2 + indra/newview/llappviewer.cpp | 324 ++++++++++++++++---------------- indra/newview/llappviewer.h | 8 +- indra/newview/llappviewerlinux.cpp | 114 ++++++----- indra/newview/llappviewerlinux.h | 2 +- indra/newview/llappviewermacosx-objc.h | 36 ++++ indra/newview/llappviewermacosx-objc.mm | 73 +++++++ indra/newview/llappviewermacosx.cpp | 183 +++++------------- indra/newview/llappviewermacosx.h | 2 +- indra/newview/llappviewerwin32.cpp | 109 +++++++++-- indra/newview/llappviewerwin32.h | 4 +- indra/newview/llstartup.cpp | 3 +- 12 files changed, 492 insertions(+), 368 deletions(-) create mode 100644 indra/newview/llappviewermacosx-objc.h create mode 100644 indra/newview/llappviewermacosx-objc.mm mode change 100755 => 100644 indra/newview/llappviewerwin32.cpp mode change 100755 => 100644 indra/newview/llappviewerwin32.h (limited to 'indra/newview') diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 1fea6dea9f..3877d0b31f 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1280,6 +1280,8 @@ set_source_files_properties( if (DARWIN) LIST(APPEND viewer_SOURCE_FILES llappviewermacosx.cpp) + LIST(APPEND viewer_SOURCE_FILES llappviewermacosx-objc.mm) + LIST(APPEND viewer_SOURCE_FILES llappviewermacosx-objc.h) LIST(APPEND viewer_SOURCE_FILES llfilepicker_mac.mm) LIST(APPEND viewer_HEADER_FILES llfilepicker_mac.h) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 539d186441..eaced99c13 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -689,9 +689,26 @@ LLAppViewer::LLAppViewer() : llerrs << "Oh no! An instance of LLAppViewer already exists! LLAppViewer is sort of like a singleton." << llendl; } - setupErrorHandling(); + mDumpPath =""; + + // Need to do this initialization before we do anything else, since anything + // that touches files should really go through the lldir API + gDirUtilp->initAppDirs("SecondLife"); + // + // IMPORTANT! Do NOT put anything that will write + // into the log files during normal startup until AFTER + // we run the "program crashed last time" error handler below. + // sInstance = this; + gLoggedInTime.stop(); + + initLoggingAndGetLastDuration(); + + processMarkerFiles(); + // + // OK to write stuff to logs now, we've now crash reported if necessary + // LLLoginInstance::instance().setUpdaterService(mUpdater.get()); LLLoginInstance::instance().setPlatformInfo(gPlatform, getOSInfo().getOSVersionString()); @@ -707,7 +724,7 @@ LLAppViewer::~LLAppViewer() destroyMainloopTimeout(); // If we got to this destructor somehow, the app didn't hang. - removeMarkerFile(); + removeMarkerFiles(); } class LLUITranslationBridge : public LLTranslationBridge @@ -721,13 +738,11 @@ public: bool LLAppViewer::init() { + setupErrorHandling(); + // // Start of the application // - // IMPORTANT! Do NOT put anything that will write - // into the log files during normal startup until AFTER - // we run the "program crashed last time" error handler below. - // LLFastTimer::reset(); @@ -745,21 +760,15 @@ bool LLAppViewer::init() //initialize particle index pool LLVOPartGroup::initClass(); - // Need to do this initialization before we do anything else, since anything - // that touches files should really go through the lldir API - gDirUtilp->initAppDirs("SecondLife"); // set skin search path to default, will be overridden later // this allows simple skinned file lookups to work gDirUtilp->setSkinFolder("default", "en"); initLoggingAndGetLastDuration(); - processMarkerFiles(); - // // OK to write stuff to logs now, we've now crash reported if necessary // - init_default_trans_args(); if (!initConfiguration()) @@ -772,11 +781,13 @@ bool LLAppViewer::init() LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize")); LLPrivateMemoryPoolManager::initClass((BOOL)gSavedSettings.getBOOL("MemoryPrivatePoolEnabled"), (U32)gSavedSettings.getU32("MemoryPrivatePoolSize")*1024*1024) ; - - // write Google Breakpad minidump files to our log directory - std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); - logdir += gDirUtilp->getDirDelimiter(); + // write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues. + std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); + mDumpPath = logdir; setMiniDumpDir(logdir); + logdir += gDirUtilp->getDirDelimiter(); + setDebugFileNames(logdir); + // Although initLoggingAndGetLastDuration() is the right place to mess with // setFatalFunction(), we can't query gSavedSettings until after @@ -1928,9 +1939,8 @@ bool LLAppViewer::cleanup() llinfos << "Purging all cache files on exit" << llendflush; gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*"); } - - removeMarkerFile(); // Any crashes from here on we'll just have to ignore + removeDumpDir(); writeDebugInfo(); LLLocationHistory::getInstance()->save(); @@ -2086,6 +2096,8 @@ bool LLAppViewer::cleanup() ll_close_fail_log(); + removeMarkerFiles(); + MEM_TRACK_RELEASE llinfos << "Goodbye!" << llendflush; @@ -2579,7 +2591,7 @@ bool LLAppViewer::initConfiguration() } if (clp.hasOption("logevents")) { - LLViewerEventRecorder::instance().setEventLoggingOn(); + LLViewerEventRecorder::instance().setEventLoggingOn(); } std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel")); @@ -2661,8 +2673,8 @@ bool LLAppViewer::initConfiguration() if(start_slurl.getType() == LLSLURL::LOCATION) { LLGridManager::getInstance()->setGridChoice(start_slurl.getGrid()); - } - } + } + } //RN: if we received a URL, hand it off to the existing instance. // don't call anotherInstanceRunning() when doing URL handoff, as @@ -2704,38 +2716,6 @@ bool LLAppViewer::initConfiguration() mYieldTime = gSavedSettings.getS32("YieldTime"); - // Read skin/branding settings if specified. - //if (! gDirUtilp->getSkinDir().empty() ) - //{ - // std::string skin_def_file = gDirUtilp->findSkinnedFilename("skin.xml"); - // LLXmlTree skin_def_tree; - - // if (!skin_def_tree.parseFile(skin_def_file)) - // { - // llerrs << "Failed to parse skin definition." << llendl; - // } - - //} - -#if LL_DARWIN - -#if __ppc__ - // If the CPU doesn't have Altivec (i.e. it's not at least a G4), don't go any further. - // Only test PowerPC - all Intel Macs have SSE. - if(!gSysCPU.hasAltivec()) - { - std::ostringstream msg; - msg << LLTrans::getString("MBRequiresAltiVec"); - OSMessageBox( - msg.str(), - LLStringUtil::null, - OSMB_OK); - removeMarkerFile(); - return false; - } -#endif - -#endif // LL_DARWIN // Display splash screen. Must be after above check for previous // crash as this dialog is always frontmost. @@ -2806,10 +2786,6 @@ bool LLAppViewer::initConfiguration() disable_voice->setValue(LLSD(TRUE), DO_NOT_PERSIST); } } - else - { - checkForCrash(); - } // NextLoginLocation is set from the command line option std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" ); @@ -3113,19 +3089,6 @@ void LLAppViewer::initUpdater() updater_pump.listen("notify_update", ¬ify_update); } -void LLAppViewer::checkForCrash(void) -{ -#if LL_SEND_CRASH_REPORTS - if (gLastExecEvent == LAST_EXEC_FROZE) - { - llinfos << "Last execution froze, sending a crash report." << llendl; - - bool report_freeze = true; - handleCrashReporting(report_freeze); - } -#endif // LL_SEND_CRASH_REPORTS -} - // // This function decides whether the client machine meets the minimum requirements to // run in a maximized window, per the consensus of davep, boa and nyx on 3/30/2011. @@ -3252,12 +3215,21 @@ bool LLAppViewer::initWindow() return true; } -void LLAppViewer::writeDebugInfo() +void LLAppViewer::writeDebugInfo(bool isStatic) { - std::string debug_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"debug_info.log"); - llinfos << "Opening debug file " << debug_filename << llendl; - llofstream out_file(debug_filename); - LLSDSerialize::toPrettyXML(gDebugInfo, out_file); + //Try to do the minimum when writing data during a crash. + std::string* debug_filename; + debug_filename = ( isStatic + ? getStaticDebugFile() + : getDynamicDebugFile() ); + + llinfos << "Opening debug file " << *debug_filename << llendl; + llofstream out_file(*debug_filename); + + isStatic ? LLSDSerialize::toPrettyXML(gDebugInfo, out_file) + : LLSDSerialize::toPrettyXML(gDebugInfo["Dynamic"], out_file); + + out_file.close(); } @@ -3309,6 +3281,10 @@ void LLAppViewer::removeCacheFiles(const std::string& file_mask) void LLAppViewer::writeSystemInfo() { + + if (! gDebugInfo.has("Dynamic") ) + gDebugInfo["Dynamic"] = LLSD::emptyMap(); + gDebugInfo["SLLog"] = LLError::logFileName(); gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel(); @@ -3373,15 +3349,62 @@ void LLAppViewer::writeSystemInfo() LL_INFOS("SystemInfo") << "OS: " << getOSInfo().getOSStringSimple() << LL_ENDL; LL_INFOS("SystemInfo") << "OS info: " << getOSInfo() << LL_ENDL; + gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile"); + gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName(); + gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath(); + gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin(); + gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall"); + gDebugInfo["StartupState"] = LLStartUp::getStartupStateString(); + writeDebugInfo(); // Save out debug_info.log early, in case of crash. } +#ifdef LL_WINDOWS +//For whatever reason, in Windows when using OOP server for breakpad, the callback to get the +//name of the dump file is not getting triggered by the breakpad library. Unfortunately they +//also didn't see fit to provide a simple query request across the pipe to get this name either. +//Since we are putting our output in a runtime generated directory and we know the header data in +//the dump format, we can however use the following hack to identify our file. +//SPATTERS TODO make this a member function. +void getFileList() +{ + std::stringstream filenames; + + typedef std::vector vec; + std::string pathname = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,""); + vec file_vec = gDirUtilp->getFilesInDir(pathname); + for(vec::const_iterator iter=file_vec.begin(); iter!=file_vec.end(); ++iter) + { + filenames << *iter << " "; + if ( ( iter->length() > 30 ) && (iter->rfind(".log") != (iter->length()-4) ) ) + { + std::string fullname = pathname + *iter; + std::ifstream fdat( fullname.c_str(), std::ifstream::binary); + if (fdat) + { + char buf[5]; + fdat.read(buf,4); + fdat.close(); + if (!strncmp(buf,"MDMP",4)) + { + gDebugInfo["Dynamic"]["MinidumpPath"] = fullname; + } + } + } + } + filenames << std::endl; + gDebugInfo["Dynamic"]["DumpDirContents"] = filenames.str(); +} +#endif + void LLAppViewer::handleViewerCrash() { llinfos << "Handle viewer crash entry." << llendl; llinfos << "Last render pool type: " << LLPipeline::sCurRenderPoolType << llendl ; + std::cout << "SPATTERS I am here." << std::endl; + LLMemory::logMemoryInfo(true) ; //print out recorded call stacks if there are any. @@ -3411,73 +3434,51 @@ void LLAppViewer::handleViewerCrash() std::string crashHostUrl = gSavedSettings.get("CrashHostUrl"); if(crashHostUrl != "") { - gDebugInfo["CrashHostUrl"] = crashHostUrl; + gDebugInfo["Dynamic"]["CrashHostUrl"] = crashHostUrl; } - //We already do this in writeSystemInfo(), but we do it again here to make /sure/ we have a version - //to check against no matter what - gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel(); - - gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor(); - gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor(); - gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::getPatch(); - gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::getBuild(); - LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if ( parcel && parcel->getMusicURL()[0]) { - gDebugInfo["ParcelMusicURL"] = parcel->getMusicURL(); + gDebugInfo["Dynamic"]["ParcelMusicURL"] = parcel->getMusicURL(); } if ( parcel && parcel->getMediaURL()[0]) { - gDebugInfo["ParcelMediaURL"] = parcel->getMediaURL(); + gDebugInfo["Dynamic"]["ParcelMediaURL"] = parcel->getMediaURL(); } - gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile"); - gDebugInfo["CAFilename"] = gDirUtilp->getCAFile(); - gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName(); - gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath(); - gDebugInfo["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds()); - gDebugInfo["StartupState"] = LLStartUp::getStartupStateString(); - gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer) LLMemory::getCurrentRSS() >> 10; - gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin(); - gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall"); - - char *minidump_file = pApp->getMiniDumpFilename(); - if(minidump_file && minidump_file[0] != 0) - { - gDebugInfo["MinidumpPath"] = minidump_file; - } + gDebugInfo["Dynamic"]["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds()); + gDebugInfo["Dynamic"]["RAMInfo"]["Allocated"] = (LLSD::Integer) LLMemory::getCurrentRSS() >> 10; if(gLogoutInProgress) { - gDebugInfo["LastExecEvent"] = LAST_EXEC_LOGOUT_CRASH; + gDebugInfo["Dynamic"]["LastExecEvent"] = LAST_EXEC_LOGOUT_CRASH; } else { - gDebugInfo["LastExecEvent"] = gLLErrorActivated ? LAST_EXEC_LLERROR_CRASH : LAST_EXEC_OTHER_CRASH; + gDebugInfo["Dynamic"]["LastExecEvent"] = gLLErrorActivated ? LAST_EXEC_LLERROR_CRASH : LAST_EXEC_OTHER_CRASH; } if(gAgent.getRegion()) { - gDebugInfo["CurrentSimHost"] = gAgent.getRegionHost().getHostName(); - gDebugInfo["CurrentRegion"] = gAgent.getRegion()->getName(); + gDebugInfo["Dynamic"]["CurrentSimHost"] = gAgent.getRegionHost().getHostName(); + gDebugInfo["Dynamic"]["CurrentRegion"] = gAgent.getRegion()->getName(); const LLVector3& loc = gAgent.getPositionAgent(); - gDebugInfo["CurrentLocationX"] = loc.mV[0]; - gDebugInfo["CurrentLocationY"] = loc.mV[1]; - gDebugInfo["CurrentLocationZ"] = loc.mV[2]; + gDebugInfo["Dynamic"]["CurrentLocationX"] = loc.mV[0]; + gDebugInfo["Dynamic"]["CurrentLocationY"] = loc.mV[1]; + gDebugInfo["Dynamic"]["CurrentLocationZ"] = loc.mV[2]; } if(LLAppViewer::instance()->mMainloopTimeout) { - gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); + gDebugInfo["Dynamic"]["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); } // The crash is being handled here so set this value to false. // Otherwise the crash logger will think this crash was a freeze. - gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)false; + gDebugInfo["Dynamic"]["CrashNotHandled"] = (LLSD::Boolean)false; //Write out the crash status file //Use marker file style setup, as that's the simplest, especially since @@ -3505,10 +3506,24 @@ void LLAppViewer::handleViewerCrash() LL_WARNS("MarkerFile") << "No gDirUtilp with which to create error marker file name" << LL_ENDL; } + + char *minidump_file = pApp->getMiniDumpFilename(); + + std::cout << "SPATTERS minidump name is " << minidump_file << std::endl; + if(minidump_file && minidump_file[0] != 0) + { + gDebugInfo["Dynamic"]["MinidumpPath"] = minidump_file; + } +#ifdef LL_WINDOWS + getFileList(); +#endif + gDebugInfo["Dynamic"]["SPATTERS1"] = "Where my output?"; + gDebugInfo["Dynamic"]["CrashType"]="crash"; + if (gMessageSystem && gDirUtilp) { std::string filename; - filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "stats.log"); + filename = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "stats.log"); llofstream file(filename, llofstream::binary); if(file.good()) { @@ -3524,29 +3539,13 @@ void LLAppViewer::handleViewerCrash() gMessageSystem->stopLogging(); } - if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo); + if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo["Dynamic"]); // Close the debug file - pApp->writeDebugInfo(); + pApp->writeDebugInfo(false); //false answers the isStatic question with the least overhead. LLError::logToFile(""); - - // Remove the marker file, since otherwise we'll spawn a process that'll keep it locked - if(gDebugInfo["LastExecEvent"].asInteger() == LAST_EXEC_LOGOUT_CRASH) - { - pApp->removeMarkerFile(true); - } - else - { - pApp->removeMarkerFile(false); - } - -#if LL_SEND_CRASH_REPORTS - // Call to pure virtual, handled by platform specific llappviewer instance. - pApp->handleCrashReporting(); -#endif - - return; + pApp->removeMarkerFiles(); } // static @@ -3743,33 +3742,30 @@ void LLAppViewer::processMarkerFiles() } } -void LLAppViewer::removeMarkerFile(bool leave_logout_marker) +void LLAppViewer::removeMarkerFiles() { if (!mSecondInstance) { - LL_DEBUGS("MarkerFile") << (leave_logout_marker?"leave":"remove") <<" logout" << LL_ENDL; if (mMarkerFile.getFileHandle()) { - LL_DEBUGS("MarkerFile") << "removing exec marker '"<getExpandedFilename(LL_PATH_DUMP, ""); + gDirUtilp->deleteDirAndContents(dump_dir); +} + void LLAppViewer::forceQuit() { LLApp::setQuitting(); @@ -3795,7 +3799,7 @@ void LLAppViewer::fastQuit(S32 error_code) // figure out the error code S32 final_error_code = error_code ? error_code : (S32)isError(); // this isn't a crash - removeMarkerFile(); + removeMarkerFiles(); // get outta here _exit(final_error_code); } @@ -4973,20 +4977,26 @@ void LLAppViewer::sendLogoutRequest() { //Set internal status variables and marker files before actually starting the logout process gLogoutInProgress = TRUE; - mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME); - - LLAPRFile outfile ; - mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB); - if (mLogoutMarkerFile.getFileHandle()) + if (!mSecondInstance) { - LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << LL_ENDL; - recordMarkerVersion(outfile); + mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME); + + mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB); + if (mLogoutMarkerFile.getFileHandle()) + { + LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << LL_ENDL; + recordMarkerVersion(mLogoutMarkerFile); + } + else + { + LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL; + } } else { - LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL; - } - + LL_INFOS("MarkerFile") << "Did not logout marker file because this is a second instance" << LL_ENDL; + } + LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_LogoutRequest); msg->nextBlockFast(_PREHASH_AgentData); @@ -5464,7 +5474,7 @@ void LLAppViewer::launchUpdater() LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << " " << LLAppViewer::sUpdaterInfo->mParams.str() << LL_ENDL; //Explicitly remove the marker file, otherwise we pass the lock onto the child process and things get weird. - LLAppViewer::instance()->removeMarkerFile(); // In case updater fails + LLAppViewer::instance()->removeMarkerFiles(); // In case updater fails // *NOTE:Mani The updater is spawned as the last thing before the WinMain exit. // see LLAppViewerWin32.cpp diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 3ae8a78845..72e317566c 100755 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -46,7 +46,6 @@ class LLViewerJoystick; extern LLFastTimer::DeclareTimer FTM_FRAME; - class LLAppViewer : public LLApp { public: @@ -82,7 +81,7 @@ public: bool quitRequested() { return mQuitRequested; } bool logoutRequestSent() { return mLogoutRequestSent; } - void writeDebugInfo(); + void writeDebugInfo(bool isStatic=true); const LLOSInfo& getOSInfo() const { return mSysOSInfo; } @@ -91,7 +90,7 @@ public: virtual bool restoreErrorTrap() = 0; // Require platform specific override to reset error handling mechanism. // return false if the error trap needed restoration. - virtual void handleCrashReporting(bool reportFreeze = false) = 0; // What to do with crash report? + virtual void initCrashReporting(bool reportFreeze = false) = 0; // What to do with crash report? static void handleViewerCrash(); // Hey! The viewer crashed. Do this, soon. void checkForCrash(); @@ -119,8 +118,9 @@ public: void loadNameCache(); void saveNameCache(); - void removeMarkerFile(bool leave_logout_marker = false); + void removeMarkerFiles(); + void removeDumpDir(); // LLAppViewer testing helpers. // *NOTE: These will potentially crash the viewer. Only for debugging. virtual void forceErrorLLError(); diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index b16bb573e1..11fcf0018e 100755 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -58,12 +58,15 @@ namespace void (*gOldTerminateHandler)() = NULL; } + static void exceptionTerminateHandler() { // reinstall default terminate() handler in case we re-terminate. if (gOldTerminateHandler) std::set_terminate(gOldTerminateHandler); // treat this like a regular viewer crash, with nice stacktrace etc. - LLAppViewer::handleViewerCrash(); + long *null_ptr; + null_ptr = 0; + *null_ptr = 0xDEADBEEF; //Force an exception that will trigger breakpad. // we've probably been killed-off before now, but... gOldTerminateHandler(); // call old terminate() handler } @@ -127,7 +130,17 @@ bool LLAppViewerLinux::init() // really early in app startup! if (!g_thread_supported ()) g_thread_init (NULL); - return LLAppViewer::init(); + bool success = LLAppViewer::init(); + +#if LL_SEND_CRASH_REPORTS + if (success) + { + LLAppViewer* pApp = LLAppViewer::instance(); + pApp->initCrashReporting(); + } +#endif + + return success; } bool LLAppViewerLinux::restoreErrorTrap() @@ -319,7 +332,7 @@ bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url) } #endif // LL_DBUS_ENABLED -void LLAppViewerLinux::handleCrashReporting(bool reportFreeze) +void LLAppViewerLinux::initCrashReporting(bool reportFreeze) { std::string cmd =gDirUtilp->getExecutableDir(); cmd += gDirUtilp->getDirDelimiter(); @@ -331,69 +344,52 @@ void LLAppViewerLinux::handleCrashReporting(bool reportFreeze) # error Unknown platform #endif - if(reportFreeze) - { - char* const cmdargv[] = - {(char*)cmd.c_str(), - (char*)"-previous", - NULL}; - - fflush(NULL); // flush all buffers before the child inherits them - pid_t pid = fork(); - if (pid == 0) - { // child - execv(cmd.c_str(), cmdargv); /* Flawfinder: Ignore */ - llwarns << "execv failure when trying to start " << cmd << llendl; - _exit(1); // avoid atexit() - } else { - if (pid > 0) - { - // wait for child proc to die - int childExitStatus; - waitpid(pid, &childExitStatus, 0); - } else { - llwarns << "fork failure." << llendl; - } - } - } + std::stringstream pid_str; + pid_str << LLApp::getPid(); + std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); + std::string appname = gDirUtilp->getExecutableFilename(); + // launch the actual crash logger + const char * cmdargv[] = + {cmd.c_str(), + "-user", + (char*)LLGridManager::getInstance()->getGridId().c_str(), + "-name", + LLAppViewer::instance()->getSecondLifeTitle().c_str(), + "-pid", + pid_str.str().c_str(), + "-dumpdir", + logdir.c_str(), + "-procname", + appname.c_str(), + NULL}; + fflush(NULL); + + pid_t pid = fork(); + if (pid == 0) + { // child + execv(cmd.c_str(), (char* const*) cmdargv); /* Flawfinder: ignore */ + llwarns << "execv failure when trying to start " << cmd << llendl; + _exit(1); // avoid atexit() + } else { - // launch the actual crash logger - const char * cmdargv[] = - {cmd.c_str(), - "-user", - (char*)LLGridManager::getInstance()->getGridId().c_str(), - "-name", - LLAppViewer::instance()->getSecondLifeTitle().c_str(), - NULL}; - fflush(NULL); - pid_t pid = fork(); - if (pid == 0) - { // child - execv(cmd.c_str(), (char* const*) cmdargv); /* Flawfinder: ignore */ - llwarns << "execv failure when trying to start " << cmd << llendl; - _exit(1); // avoid atexit() + if (pid > 0) + { + // DO NOT wait for child proc to die; we want + // the logger to outlive us while we quit to + // free up the screen/keyboard/etc. + ////int childExitStatus; + ////waitpid(pid, &childExitStatus, 0); } else { - if (pid > 0) - { - // DO NOT wait for child proc to die; we want - // the logger to outlive us while we quit to - // free up the screen/keyboard/etc. - ////int childExitStatus; - ////waitpid(pid, &childExitStatus, 0); - } - else - { - llwarns << "fork failure." << llendl; - } + llwarns << "fork failure." << llendl; } - // Sometimes signals don't seem to quit the viewer. Also, we may - // have been called explicitly instead of from a signal handler. - // Make sure we exit so as to not totally confuse the user. - _exit(1); // avoid atexit(), else we may re-crash in dtors. } + // Sometimes signals don't seem to quit the viewer. Also, we may + // have been called explicitly instead of from a signal handler. + // Make sure we exit so as to not totally confuse the user. + //_exit(1); // avoid atexit(), else we may re-crash in dtors. } bool LLAppViewerLinux::beingDebugged() diff --git a/indra/newview/llappviewerlinux.h b/indra/newview/llappviewerlinux.h index fb77600c10..0289c43043 100755 --- a/indra/newview/llappviewerlinux.h +++ b/indra/newview/llappviewerlinux.h @@ -61,7 +61,7 @@ protected: virtual bool beingDebugged(); virtual bool restoreErrorTrap(); - virtual void handleCrashReporting(bool reportFreeze); + virtual void initCrashReporting(bool reportFreeze); virtual void initLoggingAndGetLastDuration(); virtual bool initParseCommandLine(LLCommandLineParser& clp); diff --git a/indra/newview/llappviewermacosx-objc.h b/indra/newview/llappviewermacosx-objc.h new file mode 100644 index 0000000000..c6dcec8e34 --- /dev/null +++ b/indra/newview/llappviewermacosx-objc.h @@ -0,0 +1,36 @@ +/** + * @file llappviewermacosx.h + * @brief The LLAppViewerMacOSX class declaration + * + * $LicenseInfo:firstyear=2007&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$ + */ + +#ifndef LL_LLAPPVIEWERMACOSX_OBJC_H +#define LL_LLAPPVIEWERMACOSX_OBJC_H + +#include +#include + +//Why? Because BOOL +void launchApplication(const std::string* app_name, const std::vector* args); + +#endif // LL_LLAPPVIEWERMACOSX_OBJC_H diff --git a/indra/newview/llappviewermacosx-objc.mm b/indra/newview/llappviewermacosx-objc.mm new file mode 100644 index 0000000000..17301847e8 --- /dev/null +++ b/indra/newview/llappviewermacosx-objc.mm @@ -0,0 +1,73 @@ +/** + * @file llappviewermacosx-objc.mm + * @brief Functions related to LLAppViewerMacOSX that must be expressed in obj-c + * + * $LicenseInfo:firstyear=2007&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$ + */ + +#if !defined LL_DARWIN + #error "Use only with Mac OS X" +#endif + +#import +#include + +#include "llappviewermacosx-objc.h" + +void launchApplication(const std::string* app_name, const std::vector* args) +{ + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + if (app_name->empty()) return; + + NSMutableString* app_name_ns = [NSMutableString stringWithString:[[NSBundle mainBundle] resourcePath]]; //Path to resource dir + [app_name_ns appendFormat:@"/%@", [NSString stringWithCString:app_name->c_str() + encoding:[NSString defaultCStringEncoding]]]; + + NSMutableArray *args_ns = nil; + args_ns = [[NSMutableArray alloc] init]; + + for (int i=0; i < args->size(); ++i) + { + NSLog(@"Adding string %s", (*args)[i].c_str()); + [args_ns addObject: + [NSString stringWithCString:(*args)[i].c_str() + encoding:[NSString defaultCStringEncoding]]]; + } + + NSTask *task = [[NSTask alloc] init]; + NSBundle *bundle = [NSBundle bundleWithPath:[[NSWorkspace sharedWorkspace] fullPathForApplication:app_name_ns]]; + [task setLaunchPath:[bundle executablePath]]; + [task setArguments:args_ns]; + [task launch]; + +// NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; +// NSURL *url = [NSURL fileURLWithPath:[workspace fullPathForApplication:app_name_ns]]; +// +// NSError *error = nil; +// [workspace launchApplicationAtURL:url options:0 configuration:[NSDictionary dictionaryWithObject:args_ns forKey:NSWorkspaceLaunchConfigurationArguments] error:&error]; + //TODO Handle error + + [pool release]; + return; +} diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 2723f0b90d..c6d45cf4d6 100755 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -32,6 +32,9 @@ #define LL_CARBON_CRASH_HANDLER 1 +#include "llwindowmacosx.h" +#include "llappviewermacosx-objc.h" + #include "llappviewermacosx.h" #include "llwindowmacosx-objc.h" #include "llcommandlineparser.h" @@ -45,6 +48,9 @@ #ifdef LL_CARBON_CRASH_HANDLER #include #endif +#include +#include + #include "lldir.h" #include #include // for systemwide mute @@ -56,7 +62,6 @@ namespace // They are not used immediately by the app. int gArgC; char** gArgV; - bool sCrashReporterIsRunning = false; LLAppViewerMacOSX* gViewerAppPtr; #ifdef LL_CARBON_CRASH_HANDLER OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) @@ -68,6 +73,20 @@ namespace return(result); } #endif + void (*gOldTerminateHandler)() = NULL; +} + +static void exceptionTerminateHandler() +{ + // reinstall default terminate() handler in case we re-terminate. + if (gOldTerminateHandler) std::set_terminate(gOldTerminateHandler); + // treat this like a regular viewer crash, with nice stacktrace etc. + long *null_ptr; + null_ptr = 0; + *null_ptr = 0xDEADBEEF; //Force an exception that will trigger breakpad. + //LLAppViewer::handleViewerCrash(); + // we've probably been killed-off before now, but... + gOldTerminateHandler(); // call old terminate() handler } bool initViewer() @@ -83,19 +102,21 @@ bool initViewer() << gDirUtilp->getAppRODataDir() << ": " << strerror(errno) << llendl; } - + gViewerAppPtr = new LLAppViewerMacOSX(); - + + // install unexpected exception handler + gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler); + gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash); - - + bool ok = gViewerAppPtr->init(); if(!ok) { llwarns << "Application init failed." << llendl; } - + return ok; } @@ -121,7 +142,8 @@ void cleanupViewer() { if(!LLApp::isError()) { - gViewerAppPtr->cleanup(); + if (gViewerAppPtr) + gViewerAppPtr->cleanup(); } delete gViewerAppPtr; @@ -146,7 +168,17 @@ LLAppViewerMacOSX::~LLAppViewerMacOSX() bool LLAppViewerMacOSX::init() { - return LLAppViewer::init(); + bool success = LLAppViewer::init(); + +#if LL_SEND_CRASH_REPORTS + if (success) + { + LLAppViewer* pApp = LLAppViewer::instance(); + pApp->initCrashReporting(); + } +#endif + + return success; } // MacOSX may add and addition command line arguement for the process serial number. @@ -263,132 +295,17 @@ bool LLAppViewerMacOSX::restoreErrorTrap() return reset_count == 0; } -#ifdef LL_CARBON_CRASH_HANDLER -static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef, - EventRef inEvent, - void* inUserData) +void LLAppViewerMacOSX::initCrashReporting(bool reportFreeze) { - ProcessSerialNumber psn; - - GetEventParameter(inEvent, - kEventParamProcessID, - typeProcessSerialNumber, - NULL, - sizeof(psn), - NULL, - &psn); - - if( GetEventKind(inEvent) == kEventAppTerminated ) - { - Boolean matching_psn = FALSE; - OSErr os_result = SameProcess(&psn, (ProcessSerialNumber*)inUserData, &matching_psn); - if(os_result >= 0 && matching_psn) - { - sCrashReporterIsRunning = false; - QuitApplicationEventLoop(); - } - } - return noErr; -} -#endif - -void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze) -{ -#ifdef LL_CARBON_CRASH_HANDLER - // This used to use fork&exec, but is switched to LSOpenApplication to - // Make sure the crash reporter launches in front of the SL window. - - std::string command_str; - //command_str = "open Second Life.app/Contents/Resources/mac-crash-logger.app"; - command_str = "mac-crash-logger.app/Contents/MacOS/mac-crash-logger"; - - CFURLRef urlRef = CFURLCreateFromFileSystemRepresentation(NULL, (UInt8*)command_str.c_str(), strlen(command_str.c_str()), FALSE); - - // FSRef apparently isn't deprecated. - // There's other funcitonality that depends on it existing as well that isn't deprecated. - // There doesn't seem to be much to directly verify what the status of FSRef is, outside of some documentation pointing at FSRef being valid, and other documentation pointing to everything in Files.h being deprecated. - // We'll assume it isn't for now, since all non-deprecated functions that use it seem to assume similar. - - FSRef appRef; - Boolean pathstatus = CFURLGetFSRef(urlRef, &appRef); - - OSStatus os_result = noErr; - - if(pathstatus == true) - { - LSApplicationParameters appParams; - memset(&appParams, 0, sizeof(appParams)); - appParams.version = 0; - appParams.flags = kLSLaunchNoParams | kLSLaunchStartClassic; - - appParams.application = &appRef; - - if(reportFreeze) - { - // Make sure freeze reporting launches the crash logger synchronously, lest - // Log files get changed by SL while the logger is running. - - // *NOTE:Mani A better way - make a copy of the data that the crash reporter will send - // and let SL go about its business. This way makes the mac work like windows and linux - // and is the smallest patch for the issue. - sCrashReporterIsRunning = false; - ProcessSerialNumber o_psn; - - static EventHandlerRef sCarbonEventsRef = NULL; - static const EventTypeSpec kEvents[] = - { - { kEventClassApplication, kEventAppTerminated } - }; - - // Install the handler to detect crash logger termination - InstallEventHandler(GetApplicationEventTarget(), - (EventHandlerUPP) CarbonEventHandler, - GetEventTypeCount(kEvents), - kEvents, - &o_psn, - &sCarbonEventsRef - ); - - // Remove, temporarily the quit handler - which has *crash* behavior before - // the mainloop gets running! - AERemoveEventHandler(kCoreEventClass, - kAEQuitApplication, - NewAEEventHandlerUPP(AEQuitHandler), - false); - - // Launch the crash reporter. - os_result = LSOpenApplication(&appParams, &o_psn); - - if(os_result >= 0) - { - sCrashReporterIsRunning = true; - } - - while(sCrashReporterIsRunning) - { - RunApplicationEventLoop(); - } - - // Re-install the apps quit handler. - AEInstallEventHandler(kCoreEventClass, - kAEQuitApplication, - NewAEEventHandlerUPP(AEQuitHandler), - 0, - false); - - // Remove the crash reporter quit handler. - RemoveEventHandler(sCarbonEventsRef); - } - else - { - appParams.flags |= kLSLaunchAsync; - clear_signals(); - - ProcessSerialNumber o_psn; - os_result = LSOpenApplication(&appParams, &o_psn); - } - } -#endif + std::string command_str = "mac-crash-logger.app"; + + std::stringstream pid_str; + pid_str << LLApp::getPid(); + std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); + std::string appname = gDirUtilp->getExecutableFilename(); + std::string str[] = { "-pid", pid_str.str(), "-dumpdir", logdir, "-procname", appname.c_str() }; + std::vector< std::string > args( str, str + ( sizeof ( str ) / sizeof ( std::string ) ) ); + launchApplication(&command_str, &args); } std::string LLAppViewerMacOSX::generateSerialNumber() diff --git a/indra/newview/llappviewermacosx.h b/indra/newview/llappviewermacosx.h index 25053da5e8..ebb41a495c 100755 --- a/indra/newview/llappviewermacosx.h +++ b/indra/newview/llappviewermacosx.h @@ -48,7 +48,7 @@ public: protected: virtual bool restoreErrorTrap(); - virtual void handleCrashReporting(bool reportFreeze); + virtual void initCrashReporting(bool reportFreeze); std::string generateSerialNumber(); virtual bool initParseCommandLine(LLCommandLineParser& clp); diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp old mode 100755 new mode 100644 index 80a80f4298..c6152574c1 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -65,6 +65,31 @@ #include "llwindebug.h" #endif +#include +namespace +{ + void (*gOldTerminateHandler)() = NULL; +} + +static void exceptionTerminateHandler() +{ + // reinstall default terminate() handler in case we re-terminate. + if (gOldTerminateHandler) std::set_terminate(gOldTerminateHandler); + // treat this like a regular viewer crash, with nice stacktrace etc. + long *null_ptr; + null_ptr = 0; + *null_ptr = 0xDEADBEEF; //Force an exception that will trigger breakpad. + //LLAppViewer::handleViewerCrash(); + // we've probably been killed-off before now, but... + gOldTerminateHandler(); // call old terminate() handler +} + +LONG WINAPI catchallCrashHandler(EXCEPTION_POINTERS * /*ExceptionInfo*/) +{ + llwarns << "Hit last ditch-effort attempt to catch crash." << llendl; + exceptionTerminateHandler(); + return 0; +} // *FIX:Mani - This hack is to fix a linker issue with libndofdev.lib // The lib was compiled under VS2005 - in VS2003 we need to remap assert @@ -244,8 +269,15 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, LLAppViewerWin32* viewer_app_ptr = new LLAppViewerWin32(lpCmdLine); + // install unexpected exception handler SPATTERS test point + gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler); + viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); +#if LL_SEND_CRASH_REPORTS + ::SetUnhandledExceptionFilter(catchallCrashHandler); //SPATTERS test point +#endif + // Set a debug info flag to indicate if multiple instances are running. bool found_other_instance = !create_app_mutex(); gDebugInfo["FoundOtherInstanceAtStartup"] = LLSD::Boolean(found_other_instance); @@ -354,6 +386,14 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, hSession = 0; } + /* SPATTERS? + // Wait until child process exits. + WaitForSingleObject( mCrashReporterProcessInfo.hProcess, 30000 ); //Wait up to 30 seconds for crash report to finish up. + + // Close process and thread handles. + CloseHandle( mCrashReporterProcessInfo.hProcess ); + CloseHandle( mCrashReporterProcessInfo.hThread ); + */ return 0; } @@ -496,7 +536,19 @@ bool LLAppViewerWin32::init() LLWinDebug::instance().init(); #endif - return LLAppViewer::init(); +#if LL_WINDOWS +#if LL_SEND_CRASH_REPORTS + + + LLAppViewer* pApp = LLAppViewer::instance(); + pApp->initCrashReporting(); + +#endif +#endif + + bool success = LLAppViewer::init(); + + return success; } bool LLAppViewerWin32::cleanup() @@ -635,26 +687,61 @@ bool LLAppViewerWin32::restoreErrorTrap() //return LLWinDebug::checkExceptionHandler(); } -void LLAppViewerWin32::handleCrashReporting(bool reportFreeze) +void LLAppViewerWin32::initCrashReporting(bool reportFreeze) { const char* logger_name = "win_crash_logger.exe"; std::string exe_path = gDirUtilp->getExecutableDir(); exe_path += gDirUtilp->getDirDelimiter(); exe_path += logger_name; - const char* arg_str = logger_name; + std::stringstream pid_str; + pid_str << LLApp::getPid(); + std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); + std::string appname = gDirUtilp->getExecutableFilename(); - // *NOTE:Mani - win_crash_logger.exe no longer parses command line options. - if(reportFreeze) + std::cout << "SPATTERS in init" << std::endl; + S32 slen = logdir.length() -1; + S32 end = slen; + while (logdir.at(end) == '/' || logdir.at(end) == '\\') end--; + + if (slen !=end) { - // Spawn crash logger. - // NEEDS to wait until completion, otherwise log files will get smashed. - _spawnl(_P_WAIT, exe_path.c_str(), arg_str, NULL); + logdir = logdir.substr(0,end+1); } - else + std::string arg_str = "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + pid_str.str(); + _spawnl(_P_NOWAIT, exe_path.c_str(), arg_str.c_str(), NULL); + +/* STARTUPINFO siStartupInfo; + + std::string arg_str = "-dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + pid_str.str(); + + memset(&siStartupInfo, 0, sizeof(siStartupInfo)); + memset(&mCrashReporterProcessInfo, 0, sizeof(mCrashReporterProcessInfo)); + + siStartupInfo.cb = sizeof(siStartupInfo); + + std::wstring exe_wstr; + exe_wstr.assign(exe_path.begin(), exe_path.end()); + + std::wstring arg_wstr; + arg_wstr.assign(arg_str.begin(), arg_str.end()); + + if(CreateProcess(&exe_wstr[0], + &arg_wstr[0], // Application arguments + 0, + 0, + FALSE, + CREATE_DEFAULT_ERROR_MODE, + 0, + 0, // Working directory + &siStartupInfo, + &mCrashReporterProcessInfo) == FALSE) + // Could not start application -> call 'GetLastError()' { - _spawnl(_P_NOWAIT, exe_path.c_str(), arg_str, NULL); - } + //llinfos << "CreateProcess failed " << GetLastError() << llendl; + return; + } + */ } //virtual diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h old mode 100755 new mode 100644 index 386bddd495..1fb255d7f1 --- a/indra/newview/llappviewerwin32.h +++ b/indra/newview/llappviewerwin32.h @@ -50,11 +50,13 @@ protected: virtual bool initParseCommandLine(LLCommandLineParser& clp); virtual bool restoreErrorTrap(); - virtual void handleCrashReporting(bool reportFreeze); + virtual void initCrashReporting(bool reportFreeze); virtual bool sendURLToOtherInstance(const std::string& url); std::string generateSerialNumber(); + PROCESS_INFORMATION mCrashReporterProcessInfo; + static const std::string sWindowClass; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 67a76460a7..5da0546380 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -3506,7 +3506,8 @@ bool process_login_success_response() { success = true; } - + LLAppViewer* pApp = LLAppViewer::instance(); + pApp->writeDebugInfo(); //Write our static data now that we have username, session_id, etc. return success; } -- 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/newview/llappviewer.cpp | 6 +----- indra/newview/llappviewerwin32.cpp | 44 +------------------------------------- indra/newview/llappviewerwin32.h | 2 -- 3 files changed, 2 insertions(+), 50 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index eaced99c13..307a02b527 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3365,7 +3365,7 @@ void LLAppViewer::writeSystemInfo() //also didn't see fit to provide a simple query request across the pipe to get this name either. //Since we are putting our output in a runtime generated directory and we know the header data in //the dump format, we can however use the following hack to identify our file. -//SPATTERS TODO make this a member function. +// TODO make this a member function. void getFileList() { std::stringstream filenames; @@ -3403,8 +3403,6 @@ void LLAppViewer::handleViewerCrash() llinfos << "Last render pool type: " << LLPipeline::sCurRenderPoolType << llendl ; - std::cout << "SPATTERS I am here." << std::endl; - LLMemory::logMemoryInfo(true) ; //print out recorded call stacks if there are any. @@ -3509,7 +3507,6 @@ void LLAppViewer::handleViewerCrash() char *minidump_file = pApp->getMiniDumpFilename(); - std::cout << "SPATTERS minidump name is " << minidump_file << std::endl; if(minidump_file && minidump_file[0] != 0) { gDebugInfo["Dynamic"]["MinidumpPath"] = minidump_file; @@ -3517,7 +3514,6 @@ void LLAppViewer::handleViewerCrash() #ifdef LL_WINDOWS getFileList(); #endif - gDebugInfo["Dynamic"]["SPATTERS1"] = "Where my output?"; gDebugInfo["Dynamic"]["CrashType"]="crash"; if (gMessageSystem && gDirUtilp) diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index c6152574c1..6946130631 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -269,13 +269,12 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, LLAppViewerWin32* viewer_app_ptr = new LLAppViewerWin32(lpCmdLine); - // install unexpected exception handler SPATTERS test point gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler); viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); #if LL_SEND_CRASH_REPORTS - ::SetUnhandledExceptionFilter(catchallCrashHandler); //SPATTERS test point + ::SetUnhandledExceptionFilter(catchallCrashHandler); #endif // Set a debug info flag to indicate if multiple instances are running. @@ -386,14 +385,6 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, hSession = 0; } - /* SPATTERS? - // Wait until child process exits. - WaitForSingleObject( mCrashReporterProcessInfo.hProcess, 30000 ); //Wait up to 30 seconds for crash report to finish up. - - // Close process and thread handles. - CloseHandle( mCrashReporterProcessInfo.hProcess ); - CloseHandle( mCrashReporterProcessInfo.hThread ); - */ return 0; } @@ -699,7 +690,6 @@ void LLAppViewerWin32::initCrashReporting(bool reportFreeze) std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); std::string appname = gDirUtilp->getExecutableFilename(); - std::cout << "SPATTERS in init" << std::endl; S32 slen = logdir.length() -1; S32 end = slen; while (logdir.at(end) == '/' || logdir.at(end) == '\\') end--; @@ -710,38 +700,6 @@ void LLAppViewerWin32::initCrashReporting(bool reportFreeze) } std::string arg_str = "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + pid_str.str(); _spawnl(_P_NOWAIT, exe_path.c_str(), arg_str.c_str(), NULL); - -/* STARTUPINFO siStartupInfo; - - std::string arg_str = "-dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + pid_str.str(); - - memset(&siStartupInfo, 0, sizeof(siStartupInfo)); - memset(&mCrashReporterProcessInfo, 0, sizeof(mCrashReporterProcessInfo)); - - siStartupInfo.cb = sizeof(siStartupInfo); - - std::wstring exe_wstr; - exe_wstr.assign(exe_path.begin(), exe_path.end()); - - std::wstring arg_wstr; - arg_wstr.assign(arg_str.begin(), arg_str.end()); - - if(CreateProcess(&exe_wstr[0], - &arg_wstr[0], // Application arguments - 0, - 0, - FALSE, - CREATE_DEFAULT_ERROR_MODE, - 0, - 0, // Working directory - &siStartupInfo, - &mCrashReporterProcessInfo) == FALSE) - // Could not start application -> call 'GetLastError()' - { - //llinfos << "CreateProcess failed " << GetLastError() << llendl; - return; - } - */ } //virtual diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h index 1fb255d7f1..fb37df1a2f 100644 --- a/indra/newview/llappviewerwin32.h +++ b/indra/newview/llappviewerwin32.h @@ -55,8 +55,6 @@ protected: virtual bool sendURLToOtherInstance(const std::string& url); std::string generateSerialNumber(); - PROCESS_INFORMATION mCrashReporterProcessInfo; - static const std::string sWindowClass; -- 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/newview/llappviewer.cpp | 5 ++++- indra/newview/llappviewerwin32.cpp | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 307a02b527..5c0368df19 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3512,7 +3512,10 @@ void LLAppViewer::handleViewerCrash() gDebugInfo["Dynamic"]["MinidumpPath"] = minidump_file; } #ifdef LL_WINDOWS - getFileList(); + else + { + getFileList(); + } #endif gDebugInfo["Dynamic"]["CrashType"]="crash"; diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 6946130631..c861d0a99f 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -65,6 +65,8 @@ #include "llwindebug.h" #endif +#include "stringize.h" + #include namespace { @@ -685,8 +687,6 @@ void LLAppViewerWin32::initCrashReporting(bool reportFreeze) exe_path += gDirUtilp->getDirDelimiter(); exe_path += logger_name; - std::stringstream pid_str; - pid_str << LLApp::getPid(); std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); std::string appname = gDirUtilp->getExecutableFilename(); @@ -698,7 +698,7 @@ void LLAppViewerWin32::initCrashReporting(bool reportFreeze) { logdir = logdir.substr(0,end+1); } - std::string arg_str = "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + pid_str.str(); + std::string arg_str = "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + stringize(LLApp::getPid()); _spawnl(_P_NOWAIT, exe_path.c_str(), arg_str.c_str(), NULL); } -- 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/newview/llappviewer.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 5c0368df19..537142ebde 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3376,7 +3376,7 @@ void getFileList() for(vec::const_iterator iter=file_vec.begin(); iter!=file_vec.end(); ++iter) { filenames << *iter << " "; - if ( ( iter->length() > 30 ) && (iter->rfind(".log") != (iter->length()-4) ) ) + if ( ( iter->length() > 30 ) && (iter->rfind(".dmp") == (iter->length()-4) ) ) { std::string fullname = pathname + *iter; std::ifstream fdat( fullname.c_str(), std::ifstream::binary); @@ -3388,6 +3388,7 @@ void getFileList() if (!strncmp(buf,"MDMP",4)) { gDebugInfo["Dynamic"]["MinidumpPath"] = fullname; + break; } } } @@ -3504,15 +3505,21 @@ void LLAppViewer::handleViewerCrash() LL_WARNS("MarkerFile") << "No gDirUtilp with which to create error marker file name" << LL_ENDL; } +#ifdef LL_WINDOWS //SPATTERS Wild guess that filename for Breakpad is not being returned due to sleep cycle in Crash Reporter. + Sleep(2000); +#endif char *minidump_file = pApp->getMiniDumpFilename(); if(minidump_file && minidump_file[0] != 0) { gDebugInfo["Dynamic"]["MinidumpPath"] = minidump_file; + //SPATTERS another possibility is that when using OOP it must be initiated by a wrapping program so that when the + //viewer crashes, we are from a sibling thread than as a child. Might be able to request minidump at this point + //as a work-around. } #ifdef LL_WINDOWS - else + else //SPATTERS there is no else here in the older code { getFileList(); } -- 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/newview/llappviewer.cpp | 20 +++++++++------ indra/newview/llappviewerwin32.cpp | 33 ++++++++++++++++++++++--- indra/newview/llfloaterspellchecksettings.cpp | 35 ++------------------------- indra/newview/llfloaterspellchecksettings.h | 1 - 4 files changed, 45 insertions(+), 44 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 537142ebde..c31c0990c7 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1940,7 +1940,6 @@ bool LLAppViewer::cleanup() gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*"); } - removeDumpDir(); writeDebugInfo(); LLLocationHistory::getInstance()->save(); @@ -2102,6 +2101,14 @@ bool LLAppViewer::cleanup() llinfos << "Goodbye!" << llendflush; + //To preserve logfile on clean shutdown move to regular log dir. + std::string curr_log = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log"); + std::string last_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log"); + LLError::logToFile(""); //Close Secondlife.log + LLFile::remove(last_log); + LLFile::copy(curr_log, last_log); + removeDumpDir(); + // return 0; return true; } @@ -2191,7 +2198,7 @@ void LLAppViewer::initLoggingAndGetLastDuration() // Get name of the log file std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log"); - /* + /* * Before touching any log files, compute the duration of the last run * by comparing the ctime of the previous start marker file with the ctime * of the last log file. @@ -2237,6 +2244,8 @@ void LLAppViewer::initLoggingAndGetLastDuration() // Rename current log file to ".old" LLFile::rename(log_file, old_log_file); + log_file = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, + "SecondLife.log"); // Set the log file to SecondLife.log LLError::logToFile(log_file); if (!duration_log_msg.empty()) @@ -3505,7 +3514,7 @@ void LLAppViewer::handleViewerCrash() LL_WARNS("MarkerFile") << "No gDirUtilp with which to create error marker file name" << LL_ENDL; } -#ifdef LL_WINDOWS //SPATTERS Wild guess that filename for Breakpad is not being returned due to sleep cycle in Crash Reporter. +#ifdef LL_WINDOWS Sleep(2000); #endif @@ -3514,12 +3523,9 @@ void LLAppViewer::handleViewerCrash() if(minidump_file && minidump_file[0] != 0) { gDebugInfo["Dynamic"]["MinidumpPath"] = minidump_file; - //SPATTERS another possibility is that when using OOP it must be initiated by a wrapping program so that when the - //viewer crashes, we are from a sibling thread than as a child. Might be able to request minidump at this point - //as a work-around. } #ifdef LL_WINDOWS - else //SPATTERS there is no else here in the older code + else { getFileList(); } diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index c861d0a99f..0e4efa34c7 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -276,7 +276,7 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); #if LL_SEND_CRASH_REPORTS - ::SetUnhandledExceptionFilter(catchallCrashHandler); + // ::SetUnhandledExceptionFilter(catchallCrashHandler); #endif // Set a debug info flag to indicate if multiple instances are running. @@ -698,8 +698,35 @@ void LLAppViewerWin32::initCrashReporting(bool reportFreeze) { logdir = logdir.substr(0,end+1); } - std::string arg_str = "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + stringize(LLApp::getPid()); - _spawnl(_P_NOWAIT, exe_path.c_str(), arg_str.c_str(), NULL); + //std::string arg_str = "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + stringize(LLApp::getPid()); + //_spawnl(_P_NOWAIT, exe_path.c_str(), arg_str.c_str(), NULL); + std::string arg_str = "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + stringize(LLApp::getPid()); + + STARTUPINFO startInfo={sizeof(startInfo)}; + PROCESS_INFORMATION processInfo; + + std::wstring exe_wstr; + exe_wstr=wstringize(exe_path); + + std::wstring arg_wstr; + arg_wstr=wstringize(arg_str); + + LL_INFOS("CrashReport") << "Creating crash reporter process " << exe_path << " with params: " << arg_str << LL_ENDL; + if(CreateProcess(exe_wstr.c_str(), + &arg_wstr[0], // Application arguments + 0, + 0, + FALSE, + CREATE_DEFAULT_ERROR_MODE, + 0, + 0, // Working directory + &startInfo, + &processInfo) == FALSE) + // Could not start application -> call 'GetLastError()' + { + LL_WARNS("CrashReport Launch") << "CreateProcess failed " << GetLastError() << LL_ENDL; + return; + } } //virtual diff --git a/indra/newview/llfloaterspellchecksettings.cpp b/indra/newview/llfloaterspellchecksettings.cpp index 5ecdd11918..54c7b4c37d 100755 --- a/indra/newview/llfloaterspellchecksettings.cpp +++ b/indra/newview/llfloaterspellchecksettings.cpp @@ -307,12 +307,12 @@ void LLFloaterSpellCheckerImport::onBtnOK() else { std::string settings_dic = LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".dic"; - if ( copyFile( dict_dic, settings_dic ) ) + if ( LLFile::copy( dict_dic, settings_dic ) ) { if (gDirUtilp->fileExists(dict_aff)) { std::string settings_aff = LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".aff"; - if (copyFile( dict_aff, settings_aff )) + if ( LLFile::copy( dict_aff, settings_aff )) { imported = true; } @@ -385,37 +385,6 @@ void LLFloaterSpellCheckerImport::onBtnOK() closeFloater(false); } -bool LLFloaterSpellCheckerImport::copyFile(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("SpellCheck") << "Short write" << LL_ENDL; - write_ok = false; - } - } - if ( write_ok ) - { - copied = true; - } - fclose(out); - } - } - fclose(in); - return copied; -} - std::string LLFloaterSpellCheckerImport::parseXcuFile(const std::string& file_path) const { LLXMLNodePtr xml_root; diff --git a/indra/newview/llfloaterspellchecksettings.h b/indra/newview/llfloaterspellchecksettings.h index eded3a9133..de59d83f24 100755 --- a/indra/newview/llfloaterspellchecksettings.h +++ b/indra/newview/llfloaterspellchecksettings.h @@ -58,7 +58,6 @@ protected: void onBtnBrowse(); void onBtnCancel(); void onBtnOK(); - bool copyFile(const std::string from, const std::string to); std::string parseXcuFile(const std::string& file_path) const; std::string mDictionaryDir; -- cgit v1.2.3 From 35ab71d8ea85ff43f1940bc582bb5bbb8f52d6df Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Thu, 20 Mar 2014 12:04:39 -0700 Subject: Returned Secondlife.log to main directory due to unforeseen LLErrorThread complexities. --- indra/newview/llappviewer.cpp | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 9bbc2031f6..d2e4136b9b 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2103,12 +2103,6 @@ bool LLAppViewer::cleanup() llinfos << "Goodbye!" << llendflush; - //To preserve logfile on clean shutdown move to regular log dir. - std::string curr_log = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log"); - std::string last_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log"); - LLError::logToFile(""); //Close Secondlife.log - LLFile::remove(last_log); - LLFile::copy(curr_log, last_log); removeDumpDir(); // return 0; @@ -2246,8 +2240,6 @@ void LLAppViewer::initLoggingAndGetLastDuration() // Rename current log file to ".old" LLFile::rename(log_file, old_log_file); - log_file = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, - "SecondLife.log"); // Set the log file to SecondLife.log LLError::logToFile(log_file); if (!duration_log_msg.empty()) @@ -3733,9 +3725,6 @@ void LLAppViewer::handleViewerCrash() // Close the debug file pApp->writeDebugInfo(false); //false answers the isStatic question with the least overhead. - - LLError::logToFile(""); - pApp->removeMarkerFiles(); } // static -- cgit v1.2.3 From 0893b49ebdd5c072f099ab7a9aa75d106c0c439b Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Mon, 24 Mar 2014 22:44:51 -0700 Subject: The simple approach has not worked. This hybrid solution should avoid the Windows issues and get us per-run logfiles. --- indra/newview/llappviewer.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'indra/newview') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index d2e4136b9b..817ae9e2d2 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -725,6 +725,13 @@ LLAppViewer::~LLAppViewer() destroyMainloopTimeout(); +#if !LL_WINDOWS + //Last thing, let's copy SL.log into the per-run directory. We don't care if this operation fails. + std::string per_run_log = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log"); + std::string current_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log"); + LLFile::copy(per_run_log, current_log); +#endif + // If we got to this destructor somehow, the app didn't hang. removeMarkerFiles(); } -- cgit v1.2.3 From 5b7929364b53ed1e4798ff4c7904014b6f423c0c Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Tue, 25 Mar 2014 18:30:39 -0700 Subject: Still wasn't doing the right thing with log files. --- indra/newview/llappviewer.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 817ae9e2d2..2015876120 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -727,9 +727,16 @@ LLAppViewer::~LLAppViewer() #if !LL_WINDOWS //Last thing, let's copy SL.log into the per-run directory. We don't care if this operation fails. - std::string per_run_log = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log"); - std::string current_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log"); - LLFile::copy(per_run_log, current_log); + std::string per_run_dir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,""); + std::string per_run_file = per_run_dir + "SecondLife.log"; + std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log"); + + if (gDirUtilp->fileExists(per_run_dir)) + { + LL_INFOS ("CrashReporting") << "Copying " << log_file << " to " << per_run_file << llendl; + LLFile::copy(log_file, per_run_file); + } + #endif // If we got to this destructor somehow, the app didn't hang. @@ -3471,7 +3478,7 @@ void LLAppViewer::writeSystemInfo() if (! gDebugInfo.has("Dynamic") ) gDebugInfo["Dynamic"] = LLSD::emptyMap(); - gDebugInfo["SLLog"] = LLError::logFileName(); + gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log"); //LLError::logFileName(); gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel(); gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor(); -- cgit v1.2.3 From 9ea2694c0e73b9c74a09511c74c6cc175a7f50f8 Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Wed, 26 Mar 2014 02:07:29 -0700 Subject: Not ideal but sufficient. --- indra/newview/llappviewer.cpp | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 2015876120..c09d9d4add 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -724,20 +724,6 @@ LLAppViewer::~LLAppViewer() LLLoginInstance::instance().setUpdaterService(0); destroyMainloopTimeout(); - -#if !LL_WINDOWS - //Last thing, let's copy SL.log into the per-run directory. We don't care if this operation fails. - std::string per_run_dir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,""); - std::string per_run_file = per_run_dir + "SecondLife.log"; - std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log"); - - if (gDirUtilp->fileExists(per_run_dir)) - { - LL_INFOS ("CrashReporting") << "Copying " << log_file << " to " << per_run_file << llendl; - LLFile::copy(log_file, per_run_file); - } - -#endif // If we got to this destructor somehow, the app didn't hang. removeMarkerFiles(); @@ -3478,7 +3464,12 @@ void LLAppViewer::writeSystemInfo() if (! gDebugInfo.has("Dynamic") ) gDebugInfo["Dynamic"] = LLSD::emptyMap(); - gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log"); //LLError::logFileName(); +#if LL_WINDOWS + gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log"); +#else + //Not ideal but sufficient for good reporting. + gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.old"); //LLError::logFileName(); +#endif gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel(); gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor(); -- cgit v1.2.3 From 1d15ac293b276aa35cde3c58ff22498ce9bf8522 Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Wed, 26 Mar 2014 05:26:10 -0700 Subject: Double init of logging probably due to merge fail. --- indra/newview/llappviewer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c09d9d4add..63d31824e4 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -766,7 +766,7 @@ bool LLAppViewer::init() // this allows simple skinned file lookups to work gDirUtilp->setSkinFolder("default", "en"); - initLoggingAndGetLastDuration(); +// initLoggingAndGetLastDuration(); // // OK to write stuff to logs now, we've now crash reported if necessary -- cgit v1.2.3 From 41d8db0d3e0c519fd59719894592f57b8594bf15 Mon Sep 17 00:00:00 2001 From: andreylproductengine Date: Thu, 3 Apr 2014 19:37:52 +0300 Subject: MAINT-3870 FIXED The freelook animation never ends so the avatar never gets to the idle status... --- indra/newview/llviewerwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/newview') diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index f2b5ef54fd..609d2b47f2 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -3241,6 +3241,8 @@ void LLViewerWindow::updateUI() updateLayout(); + saveLastMouse(mCurrentMousePoint); + // cleanup unused selections when no modal dialogs are open if (LLModalDialog::activeCount() == 0) { -- cgit v1.2.3 From 7e966f28da79d2d24f93a2615c8807421300700c Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Mon, 7 Apr 2014 15:12:21 -0400 Subject: increment viewer version to 3.7.6 --- indra/newview/VIEWER_VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview') diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index aaf18d2948..897e56be0b 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -3.7.5 +3.7.6 -- cgit v1.2.3 From c9c782b5963f2f63e5a01ecebeb01cbef08c09aa Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 7 Apr 2014 14:17:15 -0700 Subject: MAINT-3915 FIX Recent Inventory Tab not showing Recent activity old logic would interpret "don't care whether or not I am showing wearables" as "filter for just wearables, of any type" --- indra/newview/llinventoryfilter.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 15463e0d33..b666331a2c 100755 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -938,7 +938,10 @@ void LLInventoryFilter::toParams(Params& params) const { params.filter_ops.types = getFilterObjectTypes(); params.filter_ops.category_types = getFilterCategoryTypes(); - params.filter_ops.wearable_types = getFilterWearableTypes(); + if (getFilterObjectTypes() & FILTERTYPE_WEARABLE) + { + params.filter_ops.wearable_types = getFilterWearableTypes(); + } params.filter_ops.date_range.min_date = getMinDate(); params.filter_ops.date_range.max_date = getMaxDate(); params.filter_ops.hours_ago = getHoursAgo(); @@ -957,7 +960,10 @@ void LLInventoryFilter::fromParams(const Params& params) setFilterObjectTypes(params.filter_ops.types); setFilterCategoryTypes(params.filter_ops.category_types); - setFilterWearableTypes(params.filter_ops.wearable_types); + if (params.filter_ops.wearable_types.isProvided()) + { + setFilterWearableTypes(params.filter_ops.wearable_types); + } setDateRange(params.filter_ops.date_range.min_date, params.filter_ops.date_range.max_date); setHoursAgo(params.filter_ops.hours_ago); setShowFolderState(params.filter_ops.show_folder_state); -- cgit v1.2.3