Improved error handling (introduced debugsession commandline argument). Startup/shutdown now more verbose. SSE checks if project was compiled with SSE(2)... not sure if windows would reach it if hardware lacked support, but linux/mac may (from V2). Fixed Mac crashes in deferred.

This commit is contained in:
Shyotl
2011-05-28 01:46:11 -05:00
parent 2f3a8fb6c0
commit 71eec1caed
40 changed files with 1404 additions and 190 deletions

View File

@@ -589,6 +589,7 @@ bool LLAppViewer::init()
LLCurl::initClass();
initThreads();
LL_INFOS("InitInfo") << "Threads initialized." << LL_ENDL ; ;
writeSystemInfo();
@@ -736,12 +737,14 @@ bool LLAppViewer::init()
OSMB_OK);
return 1;
}
LL_INFOS("InitInfo") << "Cache initialization is done." << LL_ENDL ;
//
// Initialize the window
//
gGLActive = TRUE;
initWindow();
LL_INFOS("InitInfo") << "Window is initialized." << LL_ENDL ;
// initWindow also initializes the Feature List, so now we can initialize this global.
LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap");
@@ -784,6 +787,32 @@ bool LLAppViewer::init()
return 0;
}
#if (_M_IX86_FP > 1 || defined(__SSE2__))
// Without SSE2 support we will crash almost immediately, warn here.
if (!gSysCPU.hasSSE2())
{
// can't use an alert here since we're exiting and
// all hell breaks lose.
OSMessageBox(
LLNotifications::instance().getGlobalString("UnsupportedCPUSSE2"),
LLStringUtil::null,
OSMB_OK);
return 0;
}
#else if (_M_IX86_FP == 1 || defined(__SSE__))
// Without SSE support we will crash almost immediately, warn here.
if (!gSysCPU.hasSSE())
{
// can't use an alert here since we're exiting and
// all hell breaks lose.
OSMessageBox(
LLNotifications::instance().getGlobalString("UnsupportedCPUSSE"),
LLStringUtil::null,
OSMB_OK);
return 0;
}
#endif
// alert the user if they are using unsupported hardware
if(!gSavedSettings.getBOOL("AlertedUnsupportedHardware"))
{
@@ -874,13 +903,33 @@ bool LLAppViewer::mainLoop()
LLMemType mt1(LLMemType::MTYPE_MAIN);
LLTimer frameTimer,idleTimer;
LLTimer debugTime;
LLFrameTimer memCheckTimer;
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
joystick->setNeedsReset(true);
const F32 memory_check_interval = 1.0f ; //second
// Handle messages
while (!LLApp::isExiting())
{
LLFastTimer::reset(); // Should be outside of any timer instances
//clear call stack records
llclearcallstacks;
//check memory availability information
{
if(memory_check_interval < memCheckTimer.getElapsedTimeF32())
{
memCheckTimer.reset() ;
//update the availability of memory
LLMemoryInfo::getAvailableMemoryKB(mAvailPhysicalMemInKB, mAvailVirtualMemInKB) ;
}
llcallstacks << "Available physical mem(KB): " << mAvailPhysicalMemInKB << llcallstacksendl ;
llcallstacks << "Available virtual mem(KB): " << mAvailVirtualMemInKB << llcallstacksendl ;
}
try
{
LLFastTimer t(LLFastTimer::FTM_FRAME);
@@ -914,9 +963,11 @@ bool LLAppViewer::mainLoop()
#endif
//memory leaking simulation
if(LLFloaterMemLeak::getInstance())
LLFloaterMemLeak* mem_leak_instance =
LLFloaterMemLeak::getInstance();
if(mem_leak_instance)
{
LLFloaterMemLeak::getInstance()->idle() ;
mem_leak_instance->idle() ;
}
if (!LLApp::isExiting())
@@ -1079,10 +1130,22 @@ bool LLAppViewer::mainLoop()
}
catch(std::bad_alloc)
{
//stop memory leaking simulation
if(LLFloaterMemLeak::getInstance())
{
LLFloaterMemLeak::getInstance()->stop() ;
llinfos << "Availabe physical memory(KB) at the beginning of the frame: " << mAvailPhysicalMemInKB << llendl ;
llinfos << "Availabe virtual memory(KB) at the beginning of the frame: " << mAvailVirtualMemInKB << llendl ;
LLMemoryInfo::getAvailableMemoryKB(mAvailPhysicalMemInKB, mAvailVirtualMemInKB) ;
llinfos << "Current availabe physical memory(KB): " << mAvailPhysicalMemInKB << llendl ;
llinfos << "Current availabe virtual memory(KB): " << mAvailVirtualMemInKB << llendl ;
}
//stop memory leaking simulation
LLFloaterMemLeak* mem_leak_instance =
LLFloaterMemLeak::getInstance();
if(mem_leak_instance)
{
mem_leak_instance->stop() ;
llwarns << "Bad memory allocation in LLAppViewer::mainLoop()!" << llendl ;
}
else
@@ -1107,9 +1170,11 @@ bool LLAppViewer::mainLoop()
llwarns << "Bad memory allocation when saveFinalSnapshot() is called!" << llendl ;
//stop memory leaking simulation
if(LLFloaterMemLeak::getInstance())
LLFloaterMemLeak* mem_leak_instance =
LLFloaterMemLeak::getInstance();
if(mem_leak_instance)
{
LLFloaterMemLeak::getInstance()->stop() ;
mem_leak_instance->stop() ;
}
}
}
@@ -1123,6 +1188,21 @@ bool LLAppViewer::mainLoop()
return true;
}
void LLAppViewer::flushVFSIO()
{
while (1)
{
S32 pending = LLVFSThread::updateClass(0);
pending += LLLFSThread::updateClass(0);
if (!pending)
{
break;
}
llinfos << "Waiting for pending IO to finish: " << pending << llendflush;
ms_sleep(100);
}
}
extern void cleanup_pose_stand(void);
bool LLAppViewer::cleanup()
@@ -1235,36 +1315,31 @@ bool LLAppViewer::cleanup()
removeCacheFiles("*.dsf");
removeCacheFiles("*.bodypart");
removeCacheFiles("*.clothing");
// <edit>
llinfos << "Cache files removed" << llendflush;
*/
// </edit>
llinfos << "Cache files removed" << llendflush;
cleanup_menus();
// Wait for any pending VFS IO
while (1)
{
S32 pending = LLVFSThread::updateClass(0);
pending += LLLFSThread::updateClass(0);
if (!pending)
{
break;
}
llinfos << "Waiting for pending IO to finish: " << pending << llendflush;
ms_sleep(100);
}
llinfos << "Shutting down." << llendflush;
flushVFSIO();
llinfos << "Shutting down Views" << llendflush;
// Destroy the UI
if( gViewerWindow)
gViewerWindow->shutdownViews();
llinfos << "Cleaning up Selections" << llendflush;
// Clean up selection managers after UI is destroyed, as UI may be observing them.
// Clean up before GL is shut down because we might be holding on to objects with texture references
LLSelectMgr::cleanupGlobals();
llinfos << "Shutting down OpenGL" << llendflush;
// Shut down OpenGL
if( gViewerWindow)
@@ -1279,10 +1354,15 @@ bool LLAppViewer::cleanup()
llinfos << "ViewerWindow deleted" << llendflush;
}
llinfos << "Cleaning up Keyboard & Joystick" << llendflush;
// viewer UI relies on keyboard so keep it aound until viewer UI isa gone
delete gKeyboard;
gKeyboard = NULL;
llinfos << "Cleaning up Objects" << llendflush;
LLViewerObject::cleanupVOClasses();
LLWaterParamManager::cleanupClass();
@@ -1311,6 +1391,8 @@ bool LLAppViewer::cleanup()
}
LLPrimitive::cleanupVolumeManager();
llinfos << "Additional Cleanup..." << llendflush;
LLViewerParcelMgr::cleanupGlobals();
// *Note: this is where gViewerStats used to be deleted.
@@ -1330,8 +1412,10 @@ bool LLAppViewer::cleanup()
// Also after shutting down the messaging system since it has VFS dependencies
//
llinfos << "Cleaning up VFS" << llendflush;
LLVFile::cleanupClass();
llinfos << "VFS cleaned up" << llendflush;
llinfos << "Saving Data" << llendflush;
// Quitting with "Remember Password" turned off should always stomp your
// saved password, whether or not you successfully logged in. JC
@@ -1347,10 +1431,17 @@ bool LLAppViewer::cleanup()
// save their rects on delete.
gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
// PerAccountSettingsFile should be empty if no use has been logged on.
// PerAccountSettingsFile should be empty if no user has been logged on.
// *FIX:Mani This should get really saved in a "logoff" mode.
gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
llinfos << "Saved settings" << llendflush;
if (gSavedSettings.getString("PerAccountSettingsFile").empty())
{
llinfos << "Not saving per-account settings; don't know the account name yet." << llendl;
}
else
{
gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
llinfos << "Saved settings" << llendflush;
}
std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
// save all settings, even if equals defaults
@@ -1383,6 +1474,11 @@ bool LLAppViewer::cleanup()
removeCacheFiles("*.dsf");
removeCacheFiles("*.bodypart");
removeCacheFiles("*.clothing");
llinfos << "Cache files removed" << llendflush;
}
else
{
llinfos << "Not removing cache files. Other viewer instance detected." << llendflush;
}
// </edit>
@@ -1391,6 +1487,8 @@ bool LLAppViewer::cleanup()
// Stop the plugin read thread if it's running.
LLPluginProcessParent::setUseReadThread(false);
llinfos << "Shutting down Threads" << llendflush;
// Let threads finish
LLTimer idleTimer;
idleTimer.reset();
@@ -1428,6 +1526,9 @@ bool LLAppViewer::cleanup()
delete sImageDecodeThread;
sImageDecodeThread = NULL;
llinfos << "Cleaning up Media and Textures" << llendflush;
//Note:
//LLViewerMedia::cleanupClass() has to be put before gTextureList.shutdown()
//because some new image might be generated during cleaning up media. --bao
@@ -1490,7 +1591,10 @@ bool LLAppViewer::cleanup()
llinfos << "File launched." << llendflush;
}
llinfos << "Goodbye" << llendflush;
ll_close_fail_log();
llinfos << "Goodbye!" << llendflush;
// return 0;
return true;
@@ -1958,6 +2062,14 @@ bool LLAppViewer::initConfiguration()
{
gCrashOnStartup = TRUE;
}
if (clp.hasOption("debugsession"))
{
gDebugSession = TRUE;
gDebugGL = TRUE;
ll_init_fail_log(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "test_failures.log"));
}
// Handle slurl use. NOTE: Don't let SL-55321 reappear.
@@ -2363,7 +2475,12 @@ void LLAppViewer::writeSystemInfo()
{
gDebugInfo["SLLog"] = LLError::logFileName();
gDebugInfo["ClientInfo"]["Name"] = LL_CHANNEL;
gDebugInfo["ClientInfo"]["MajorVersion"] = LL_VERSION_MAJOR;
gDebugInfo["ClientInfo"]["MinorVersion"] = LL_VERSION_MINOR;
gDebugInfo["ClientInfo"]["PatchVersion"] = LL_VERSION_PATCH;
gDebugInfo["ClientInfo"]["BuildVersion"] = LL_VERSION_BUILD;
gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
@@ -2428,6 +2545,8 @@ void LLAppViewer::handleViewerCrash()
{
llinfos << "Handle viewer crash entry." << llendl;
llinfos << "Last render pool type: " << LLPipeline::sCurRenderPoolType << llendl ;
//print out recorded call stacks if there are any.
LLError::LLCallStacks::print();
@@ -2873,45 +2992,54 @@ void LLAppViewer::migrateCacheDirectory()
#endif // LL_WINDOWS || LL_DARWIN
}
//static
U32 LLAppViewer::getTextureCacheVersion()
{
//viewer texture cache version, change if the texture cache format changes.
static const U32 TEXTURE_CACHE_VERSION = 7;
return TEXTURE_CACHE_VERSION ;
}
bool LLAppViewer::initCache()
{
mPurgeCache = false;
BOOL read_only = mSecondInstance ? TRUE : FALSE;
LLAppViewer::getTextureCache()->setReadOnly(read_only);
BOOL texture_cache_mismatch = FALSE ;
static const S32 cache_version = 7;
if (gSavedSettings.getS32("LocalCacheVersion") != cache_version)
bool texture_cache_mismatch = false;
if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion())
{
texture_cache_mismatch = TRUE ;
if (!read_only)
texture_cache_mismatch = true;
if(!read_only)
{
gSavedSettings.setS32("LocalCacheVersion", cache_version);
gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion());
}
}
if (!read_only)
{
// Purge cache if user requested it
if (gSavedSettings.getBOOL("PurgeCacheOnStartup") ||
gSavedSettings.getBOOL("PurgeCacheOnNextStartup"))
{
gSavedSettings.setBOOL("PurgeCacheOnNextStartup", false);
mPurgeCache = true;
}
// Purge cache if user requested it
if (gSavedSettings.getBOOL("PurgeCacheOnStartup") ||
gSavedSettings.getBOOL("PurgeCacheOnNextStartup"))
{
gSavedSettings.setBOOL("PurgeCacheOnNextStartup", false);
mPurgeCache = true;
// STORM-1141 force purgeAllTextures to get called to prevent a crash here. -brad
texture_cache_mismatch = true;
}
// We have moved the location of the cache directory over time.
migrateCacheDirectory();
// We have moved the location of the cache directory over time.
migrateCacheDirectory();
// Setup and verify the cache location
std::string cache_location = gSavedSettings.getString("CacheLocation");
std::string new_cache_location = gSavedSettings.getString("NewCacheLocation");
if (new_cache_location != cache_location)
{
gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation"));
purgeCache(); // purge old cache
gSavedSettings.setString("CacheLocation", new_cache_location);
}
// Setup and verify the cache location
std::string cache_location = gSavedSettings.getString("CacheLocation");
std::string new_cache_location = gSavedSettings.getString("NewCacheLocation");
if (new_cache_location != cache_location)
{
gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation"));
purgeCache(); // purge old cache
gSavedSettings.setString("CacheLocation", new_cache_location);
}
}
if (!gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation")))
@@ -3238,6 +3366,7 @@ void LLAppViewer::loadNameCache()
// Phoenix: Wolfspirit: Loads the Display Name Cache. And set if we are using Display Names.
std::string filename =
gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml");
LL_INFOS("AvNameCache") << filename << LL_ENDL;
llifstream name_cache_stream(filename);
if(name_cache_stream.is_open())
{
@@ -3922,7 +4051,6 @@ void LLAppViewer::idleNetwork()
llpushcallstacks ;
LLTimer check_message_timer;
// Read all available packets from network
stop_glerror();
const S64 frame_count = gFrameCount; // U32->S64
F32 total_time = 0.0f;
while (gMessageSystem->checkAllMessages(frame_count, gServicePump))
@@ -3934,7 +4062,6 @@ void LLAppViewer::idleNetwork()
// server going down, so this is OK.
break;
}
stop_glerror();
total_decoded++;
gPacketsIn++;
@@ -3954,6 +4081,7 @@ void LLAppViewer::idleNetwork()
break;
#endif
}
// Handle per-frame message system processing.
gMessageSystem->processAcks();
@@ -3974,8 +4102,6 @@ void LLAppViewer::idleNetwork()
// we want to clear the control after sending out all necessary agent updates
gAgent.resetControlFlags();
stop_glerror();
// Decode enqueued messages...
S32 remaining_possible_decodes = MESSAGE_MAX_PER_FRAME - total_decoded;
@@ -4130,7 +4256,7 @@ void LLAppViewer::forceErrorBadMemoryAccess()
return;
}
void LLAppViewer::forceErrorInifiniteLoop()
void LLAppViewer::forceErrorInfiniteLoop()
{
while(true)
{