From 1416c4d5c20f90f40093bd6b5a2b41414eaee54d Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Fri, 13 Nov 2020 17:51:41 +0000 Subject: [PATCH 1/9] Merged in marchcat/SL-13161 (pull request #375) SL-13161 Leftover change * SL-13161 Leftover change Approved-by: Andrey Kleshchev --- indra/newview/llfloatereditenvironmentbase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llfloatereditenvironmentbase.cpp b/indra/newview/llfloatereditenvironmentbase.cpp index 2a38f18b73..e888144b6a 100644 --- a/indra/newview/llfloatereditenvironmentbase.cpp +++ b/indra/newview/llfloatereditenvironmentbase.cpp @@ -197,7 +197,7 @@ void LLFloaterEditEnvironmentBase::onAssetLoaded(LLUUID asset_id, LLSettingsBase if (!settings || status) { LLSD args; - args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : "Unknown"; + args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString(); LLNotificationsUtil::add("FailedToFindSettings", args); closeFloater(); return; From 12d2bf47865559a8da087f6e3bbb4b65d421169c Mon Sep 17 00:00:00 2001 From: Mnikolenko ProductEngine Date: Wed, 18 Nov 2020 21:09:57 +0200 Subject: [PATCH 2/9] SL-14286 fixed crash when closing viewer while file picker is open --- indra/newview/llappdelegate-objc.mm | 1 + indra/newview/llfloatermodelpreview.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index a2b7362608..3f1b5139c5 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -134,6 +134,7 @@ // called again. Since it returned false, do not yet cancel // frameTimer. handleQuit(); + [[NSApplication sharedApplication] stopModal]; return NSTerminateCancel; } else { // pumpMainLoop() returned true: it's done. Okay, done with frameTimer. diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index b9c03f66a3..999e4a9582 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -103,6 +103,11 @@ LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod) void LLMeshFilePicker::notify(const std::vector& filenames) { + if(LLAppViewer::instance()->quitRequested()) + { + return; + } + if (filenames.size() > 0) { mMP->loadModel(filenames[0], mLOD); From a55ec705855d169e953cec10b42b156a3423fd94 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 19 Nov 2020 16:56:10 +0000 Subject: [PATCH 3/9] SL-14347 Crash at ChoosePixelFormat --- indra/llwindow/llwindowwin32.cpp | 34 ++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index a541e06c93..28e835a5fa 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -461,7 +461,8 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, memset(mCurrentGammaRamp, 0, sizeof(mCurrentGammaRamp)); memset(mPrevGammaRamp, 0, sizeof(mPrevGammaRamp)); mCustomGammaSet = FALSE; - + mWindowHandle = NULL; + if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &mMouseVanish, 0)) { mMouseVanish = TRUE; @@ -1171,7 +1172,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO << " Height: " << (window_rect.bottom - window_rect.top) << " Fullscreen: " << mFullscreen << LL_ENDL; - if (!destroy_window_handler(mWindowHandle)) + if (mWindowHandle && !destroy_window_handler(mWindowHandle)) { LL_WARNS("Window") << "Failed to properly close window before recreating it!" << LL_ENDL; } @@ -1230,13 +1231,26 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO LL_INFOS("Window") << "Device context retrieved." << LL_ENDL ; - if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd))) - { - close(); - OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), - mCallbacks->translateString("MBError"), OSMB_OK); - return FALSE; - } + try + { + // Looks like ChoosePixelFormat can crash in case of faulty driver + if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd))) + { + LL_WARNS("Window") << "ChoosePixelFormat failed, code: " << GetLastError() << LL_ENDL; + OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), + mCallbacks->translateString("MBError"), OSMB_OK); + close(); + return FALSE; + } + } + catch (...) + { + LL_WARNS("Window") << "ChoosePixelFormat failed." << LL_ENDL; + OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), + mCallbacks->translateString("MBError"), OSMB_OK); + close(); + return FALSE; + } LL_INFOS("Window") << "Pixel format chosen." << LL_ENDL ; @@ -1496,7 +1510,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO } // Destroy The Window - if (!destroy_window_handler(mWindowHandle)) + if (mWindowHandle && !destroy_window_handler(mWindowHandle)) { LL_WARNS("Window") << "Failed to properly close window!" << LL_ENDL; } From 10fa792e115fd4be00931b25662545b6bb4c47f2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 25 Nov 2020 01:37:10 +0200 Subject: [PATCH 4/9] SL-14393 Updater update Switch Intel HD4000 and HD2500 off of forced 32-bit --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 9f5e10cdfe..28fac4befe 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3206,9 +3206,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - dfef4288f26457f7d41bb17768cc88d4 + 2cad9f4819a814f307031df38542336b url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/71888/695068/viewer_manager-2.0.551854-darwin64-551854.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/73146/705975/viewer_manager-2.0.552903-darwin64-552903.tar.bz2 name darwin64 @@ -3230,9 +3230,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - d6d3081c7da304b24e9ff39452bae563 + b19cf411bad0a34b7862e9ea624a86af url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/71889/695075/viewer_manager-2.0.551854-windows-551854.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/73145/705981/viewer_manager-2.0.552903-windows-552903.tar.bz2 name windows @@ -3243,7 +3243,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors source_type hg version - 2.0.551854 + 2.0.552903 vlc-bin From 47bd603ceb2862f0aa389f8beb5376f0d6fdfcf9 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 25 Nov 2020 18:09:18 +0200 Subject: [PATCH 5/9] SL-13733 One more vivox shutdown crash Vivox was using dead pump --- indra/newview/llappviewer.cpp | 1 + indra/newview/llviewerwindow.cpp | 1 - indra/newview/llvoiceclient.cpp | 1 + indra/newview/llvoicevivox.cpp | 14 +++++++++++--- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 8045da66d0..0596df4ddb 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1620,6 +1620,7 @@ bool LLAppViewer::doFrame() } delete gServicePump; + gServicePump = NULL; destroyMainloopTimeout(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 0c81c44a57..cb37f268f2 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2323,7 +2323,6 @@ void LLViewerWindow::shutdownGL() LLViewerWindow::~LLViewerWindow() { LL_INFOS() << "Destroying Window" << LL_ENDL; - gDebugWindowProc = TRUE; // event catching, disable once we figure out cause for exit crashes destroyWindow(); delete mDebugText; diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 377f3174f3..6991ca6698 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -180,6 +180,7 @@ void LLVoiceClient::terminate() { if (mVoiceModule) mVoiceModule->terminate(); mVoiceModule = NULL; + m_servicePump = NULL; } const LLVoiceVersionInfo LLVoiceClient::getVersion() diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index a8d668420e..0c4450bea8 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -391,7 +391,7 @@ LLVivoxVoiceClient::~LLVivoxVoiceClient() void LLVivoxVoiceClient::init(LLPumpIO *pump) { // constructor will set up LLVoiceClient::getInstance() - LLVivoxVoiceClient::getInstance()->mPump = pump; + mPump = pump; // LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro", // boost::bind(&LLVivoxVoiceClient::voiceControlCoro, LLVivoxVoiceClient::getInstance())); @@ -419,6 +419,7 @@ void LLVivoxVoiceClient::terminate() } sShuttingDown = true; + mPump = NULL; } //--------------------------------------------------- @@ -953,10 +954,15 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS); - while (!mPump) - { // Can't do this until we have the pump available. + while (!mPump && !sShuttingDown) + { // Can't use the pump until we have it available. llcoro::suspend(); } + + if (sShuttingDown) + { + return false; + } // MBW -- Note to self: pumps and pipes examples in // indra/test/io.cpp @@ -969,8 +975,10 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() readChain.push_back(LLIOPipe::ptr_t(new LLIOSocketReader(mSocket))); readChain.push_back(LLIOPipe::ptr_t(new LLVivoxProtocolParser())); + mPump->addChain(readChain, NEVER_CHAIN_EXPIRY_SECS); + //--------------------------------------------------------------------- llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS); From 71bca1d8609901d98e4dca5f2e264d5d4b497e6d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 26 Nov 2020 22:26:18 +0200 Subject: [PATCH 6/9] SL-14399 Enqueue into 'LLViewerAssetStorage::assetRequestCoro' failed --- indra/llmessage/llassetstorage.h | 2 +- indra/llmessage/llcoproceduremanager.cpp | 8 ++-- indra/llmessage/llcoproceduremanager.h | 3 ++ indra/newview/app_settings/settings.xml | 2 +- indra/newview/llviewerassetstorage.cpp | 51 ++++++++++++++++++++---- indra/newview/llviewerassetstorage.h | 44 ++++++++++++++++---- 6 files changed, 89 insertions(+), 21 deletions(-) diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h index c799d8eefc..7e4572f50f 100644 --- a/indra/llmessage/llassetstorage.h +++ b/indra/llmessage/llassetstorage.h @@ -262,7 +262,7 @@ public: virtual void logAssetStorageInfo() = 0; - void checkForTimeouts(); + virtual void checkForTimeouts(); void getEstateAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id, const LLUUID &asset_id, LLAssetType::EType atype, EstateAssetType etype, diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp index a4fe3a2a8e..4d76dacdf7 100644 --- a/indra/llmessage/llcoproceduremanager.cpp +++ b/indra/llmessage/llcoproceduremanager.cpp @@ -47,7 +47,7 @@ static const std::map DefaultPoolSizes{ }; static const U32 DEFAULT_POOL_SIZE = 5; -static const U32 DEFAULT_QUEUE_SIZE = 4096; +const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 4096; //========================================================================= class LLCoprocedurePool: private boost::noncopyable @@ -194,7 +194,7 @@ void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpd mPropertyDefineFn = updatefn; // workaround until we get mutex into initializePool - initializePool("VAssetStorage"); + initializePool("AssetStorage"); initializePool("Upload"); } @@ -281,7 +281,7 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size): mPoolSize(size), mActiveCoprocsCount(0), mPending(0), - mPendingCoprocs(boost::make_shared(DEFAULT_QUEUE_SIZE)), + mPendingCoprocs(boost::make_shared(LLCoprocedureManager::DEFAULT_QUEUE_SIZE)), mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID), mCoroMapping() { @@ -332,7 +332,7 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size): mCoroMapping.insert(CoroAdapterMap_t::value_type(pooledCoro, httpAdapter)); } - LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << DEFAULT_QUEUE_SIZE << LL_ENDL; + LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << LLCoprocedureManager::DEFAULT_QUEUE_SIZE << LL_ENDL; } LLCoprocedurePool::~LLCoprocedurePool() diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h index 70204ba02b..d5557c129f 100644 --- a/indra/llmessage/llcoproceduremanager.h +++ b/indra/llmessage/llcoproceduremanager.h @@ -91,6 +91,9 @@ private: SettingQuery_t mPropertyQueryFn; SettingUpdate_t mPropertyDefineFn; + +public: + static const U32 DEFAULT_QUEUE_SIZE; }; #endif diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 48a89b40a5..bd1b25c863 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -15147,7 +15147,7 @@ Value 1 - PoolSizeVAssetStorage + PoolSizeAssetStorage Comment Coroutine Pool size for AssetStorage requests diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index 54f80a2995..7842d24279 100644 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -49,8 +49,8 @@ /// LLViewerAssetRequest ///---------------------------------------------------------------------------- - // There is also PoolSizeVAssetStorage value in setting that should mirror this name -static const std::string VIEWER_ASSET_STORAGE_CORO_POOL = "VAssetStorage"; + // There is also PoolSizeAssetStorage value in setting that should mirror this name +static const std::string VIEWER_ASSET_STORAGE_CORO_POOL = "AssetStorage"; /** * @brief Local class to encapsulate asset fetch requests with a timestamp. @@ -137,6 +137,14 @@ LLViewerAssetStorage::~LLViewerAssetStorage() // This class has dedicated coroutine pool, clean it up, otherwise coroutines will crash later. LLCoprocedureManager::instance().close(VIEWER_ASSET_STORAGE_CORO_POOL); } + + while (mCoroWaitList.size() > 0) + { + CoroWaitList &request = mCoroWaitList.front(); + // Clean up pending downloads, delete request and trigger callbacks + removeAndCallbackPendingDownloads(request.mId, request.mType, request.mId, request.mType, LL_ERR_NOERR, LLExtStat::NONE); + mCoroWaitList.pop_front(); + } } // virtual @@ -350,6 +358,27 @@ void LLViewerAssetStorage::storeAssetData( } } +void LLViewerAssetStorage::checkForTimeouts() +{ + LLAssetStorage::checkForTimeouts(); + + // Restore requests + LLCoprocedureManager* manager = LLCoprocedureManager::getInstance(); + while (mCoroWaitList.size() > 0 + && manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE) + { + CoroWaitList &request = mCoroWaitList.front(); + + bool with_http = true; + bool is_temp = false; + LLViewerAssetStatsFF::record_enqueue(request.mType, with_http, is_temp); + + manager->enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro", + boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, request.mRequest, request.mId, request.mType, request.mCallback, request.mUserData)); + + mCoroWaitList.pop_front(); + } +} /** * @brief Allocate and queue an asset fetch request for the viewer @@ -407,12 +436,20 @@ void LLViewerAssetStorage::queueRequestHttp( // This is the same as the current UDP logic - don't re-request a duplicate. if (!duplicate) { - bool with_http = true; - bool is_temp = false; - LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp); + // Coroutine buffer has fixed size (synchronization buffer, so we have no alternatives), so buffer any request above limit + if (LLCoprocedureManager::instance().count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE) + { + bool with_http = true; + bool is_temp = false; + LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp); - LLCoprocedureManager::instance().enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL,"LLViewerAssetStorage::assetRequestCoro", - boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data)); + LLCoprocedureManager::instance().enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro", + boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data)); + } + else + { + mCoroWaitList.emplace_back(req, uuid, atype, callback, user_data); + } } } diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h index ef01d179b7..5af16bd73e 100644 --- a/indra/newview/llviewerassetstorage.h +++ b/indra/newview/llviewerassetstorage.h @@ -45,7 +45,7 @@ public: ~LLViewerAssetStorage(); - virtual void storeAssetData( + void storeAssetData( const LLTransactionID& tid, LLAssetType::EType atype, LLStoreAssetCallback callback, @@ -54,9 +54,9 @@ public: bool is_priority = false, bool store_local = false, bool user_waiting=FALSE, - F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT); - - virtual void storeAssetData( + F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) override; + + void storeAssetData( const std::string& filename, const LLTransactionID& tid, LLAssetType::EType type, @@ -65,16 +65,17 @@ public: bool temp_file = false, bool is_priority = false, bool user_waiting=FALSE, - F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT); + F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) override; + + void checkForTimeouts() override; protected: - // virtual void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type, LLGetAssetCallback callback, void *user_data, BOOL duplicate, - BOOL is_priority); + BOOL is_priority) override; void queueRequestHttp(const LLUUID& uuid, LLAssetType::EType type, @@ -94,7 +95,34 @@ protected: std::string getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype); void logAssetStorageInfo(); - + + // Asset storage works through coroutines and coroutines have limited queue capacity + // This class is meant to temporary store requests when fiber's queue is full + class CoroWaitList + { + public: + CoroWaitList(LLViewerAssetRequest *req, + const LLUUID& uuid, + LLAssetType::EType atype, + LLGetAssetCallback &callback, + void *user_data) + : mRequest(req), + mId(uuid), + mType(atype), + mCallback(callback), + mUserData(user_data) + { + } + + LLViewerAssetRequest* mRequest; + LLUUID mId; + LLAssetType::EType mType; + LLGetAssetCallback mCallback; + void *mUserData; + }; + typedef std::list wait_list_t; + wait_list_t mCoroWaitList; + std::string mViewerAssetUrl; S32 mAssetCoroCount; S32 mCountRequests; From 54a5e4de5790e0cbe1198d8242dc6517ee9b58c7 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 27 Nov 2020 20:56:25 +0200 Subject: [PATCH 7/9] SL-14399 Mac build fix --- indra/newview/llviewerassetstorage.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h index 5af16bd73e..c1a5534b81 100644 --- a/indra/newview/llviewerassetstorage.h +++ b/indra/newview/llviewerassetstorage.h @@ -94,7 +94,7 @@ protected: std::string getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype); - void logAssetStorageInfo(); + void logAssetStorageInfo() override; // Asset storage works through coroutines and coroutines have limited queue capacity // This class is meant to temporary store requests when fiber's queue is full From 6d06c8b9de4708c4b8d8c68ae5fe4d753b9d70ca Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 1 Dec 2020 17:08:35 +0200 Subject: [PATCH 8/9] SL-13733 One more vivox shutdown crash #2 --- indra/newview/llvoicevivox.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 0c4450bea8..f9ffefd4a2 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -1001,6 +1001,11 @@ bool LLVivoxVoiceClient::provisionVoiceAccount() // *TODO* Pump a message for wake up. llcoro::suspend(); } + + if (sShuttingDown) + { + return false; + } std::string url = gAgent.getRegionCapability("ProvisionVoiceAccountRequest"); From bb4d02446fa215520a11f219ebca453d2dea0388 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 1 Dec 2020 18:21:43 +0200 Subject: [PATCH 9/9] SL-14347 Crash at ChoosePixelFormat SEH --- indra/llcommon/llcoros.cpp | 22 +--------------------- indra/llcommon/llexception.cpp | 25 +++++++++++++++++++++++++ indra/llcommon/llexception.h | 10 ++++++++++ indra/llwindow/llwindowwin32.cpp | 23 ++++++++++++++++++++--- indra/newview/llfeaturemanager.cpp | 18 +----------------- 5 files changed, 57 insertions(+), 41 deletions(-) diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 262929006d..23419a52a7 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -56,10 +56,6 @@ #include "stringize.h" #include "llexception.h" -#if LL_WINDOWS -#include -#endif - // static LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller) { @@ -253,29 +249,13 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl #if LL_WINDOWS -static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific - -U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) -{ - if (code == STATUS_MSC_EXCEPTION) - { - // C++ exception, go on - return EXCEPTION_CONTINUE_SEARCH; - } - else - { - // handle it - return EXCEPTION_EXECUTE_HANDLER; - } -} - void LLCoros::winlevel(const callable_t& callable) { __try { callable(); } - __except (exception_filter(GetExceptionCode(), GetExceptionInformation())) + __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation())) { // convert to C++ styled exception // Note: it might be better to use _se_set_translator diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp index 5ce8958687..b584b0ff8b 100644 --- a/indra/llcommon/llexception.cpp +++ b/indra/llcommon/llexception.cpp @@ -24,11 +24,14 @@ // `_GNU_SOURCE` macro or `BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED` if // _Unwind_Backtrace is available without `_GNU_SOURCE`." #define BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED + #if LL_WINDOWS // On Windows, header-only implementation causes macro collisions -- use // prebuilt library #define BOOST_STACKTRACE_LINK +#include #endif // LL_WINDOWS + #include // other Linden headers #include "llerror.h" @@ -85,3 +88,25 @@ void annotate_exception_(boost::exception& exc) // Anyway, which of us is really going to examine more than 100 frames? exc << errinfo_stacktrace(boost::stacktrace::stacktrace(1, 100)); } + +#if LL_WINDOWS + +// For windows SEH exception handling we sometimes need a filter that will +// separate C++ exceptions from C SEH exceptions +static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific + +U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) +{ + if (code == STATUS_MSC_EXCEPTION) + { + // C++ exception, go on + return EXCEPTION_CONTINUE_SEARCH; + } + else + { + // handle it + return EXCEPTION_EXECUTE_HANDLER; + } +} + +#endif //LL_WINDOWS diff --git a/indra/llcommon/llexception.h b/indra/llcommon/llexception.h index 422dd8810a..375bea4a57 100644 --- a/indra/llcommon/llexception.h +++ b/indra/llcommon/llexception.h @@ -102,4 +102,14 @@ void crash_on_unhandled_exception_(const char*, int, const char*, const std::str log_unhandled_exception_(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, CONTEXT) void log_unhandled_exception_(const char*, int, const char*, const std::string&); + +#if LL_WINDOWS + +// SEH exception filtering for use in __try __except +// Separates C++ exceptions from C SEH exceptions +// Todo: might be good idea to do some kind of seh_to_msc_wrapper(function, ARGS&&); +U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop); + +#endif //LL_WINDOWS + #endif /* ! defined(LL_LLEXCEPTION_H) */ diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 28e835a5fa..36148190fa 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -38,6 +38,7 @@ // Linden library includes #include "llerror.h" +#include "llexception.h" #include "llfasttimer.h" #include "llgl.h" #include "llstring.h" @@ -117,7 +118,7 @@ void show_window_creation_error(const std::string& title) LL_WARNS("Window") << title << LL_ENDL; } -HGLRC SafeCreateContext(HDC hdc) +HGLRC SafeCreateContext(HDC &hdc) { __try { @@ -129,6 +130,22 @@ HGLRC SafeCreateContext(HDC hdc) } } +GLuint SafeChoosePixelFormat(HDC &hdc, const PIXELFORMATDESCRIPTOR *ppfd) +{ + __try + { + return ChoosePixelFormat(hdc, ppfd); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + // convert to C++ styled exception + // C exception don't allow classes, so it's a regular char array + char integer_string[32]; + sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode()); + throw std::exception(integer_string); + } +} + //static BOOL LLWindowWin32::sIsClassRegistered = FALSE; @@ -1234,7 +1251,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO try { // Looks like ChoosePixelFormat can crash in case of faulty driver - if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd))) + if (!(pixel_format = SafeChoosePixelFormat(mhDC, &pfd))) { LL_WARNS("Window") << "ChoosePixelFormat failed, code: " << GetLastError() << LL_ENDL; OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), @@ -1245,7 +1262,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO } catch (...) { - LL_WARNS("Window") << "ChoosePixelFormat failed." << LL_ENDL; + LOG_UNHANDLED_EXCEPTION("ChoosePixelFormat"); OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), mCallbacks->translateString("MBError"), OSMB_OK); close(); diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index d915a9fd26..dc9816c9f7 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -379,22 +379,6 @@ F32 gpu_benchmark(); #if LL_WINDOWS -static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific - -U32 exception_benchmark_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) -{ - if (code == STATUS_MSC_EXCEPTION) - { - // C++ exception, go on - return EXCEPTION_CONTINUE_SEARCH; - } - else - { - // handle it - return EXCEPTION_EXECUTE_HANDLER; - } -} - F32 logExceptionBenchmark() { // Todo: make a wrapper/class for SEH exceptions @@ -403,7 +387,7 @@ F32 logExceptionBenchmark() { gbps = gpu_benchmark(); } - __except (exception_benchmark_filter(GetExceptionCode(), GetExceptionInformation())) + __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation())) { // convert to C++ styled exception char integer_string[32];