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:
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user