diff options
| author | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-03-27 19:46:38 +0200 |
|---|---|---|
| committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-03-28 13:35:25 +0200 |
| commit | 5a7a5272a07935aae544767abc700e8fabf3cbbd (patch) | |
| tree | 7d7f8bad69c9a91d71abb5654d8fd56908682092 /indra | |
| parent | b7fc5b2a9ec79f10a97fdb7b80f6eeb9cd65e0e2 (diff) | |
#4298 Handle various out of memory cases
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llrender/llfontfreetype.cpp | 43 | ||||
| -rw-r--r-- | indra/llrender/llshadermgr.cpp | 19 | ||||
| -rw-r--r-- | indra/newview/lldebugview.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/lldebugview.h | 1 | ||||
| -rw-r--r-- | indra/newview/llinventorymodel.cpp | 6 |
5 files changed, 49 insertions, 24 deletions
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index d37b16ce0c..d9857a7ad5 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -871,30 +871,39 @@ namespace ll U8 const* LLFontManager::loadFont( std::string const &aFilename, long &a_Size) { - a_Size = 0; - std::map< std::string, std::shared_ptr<ll::fonts::LoadedFont> >::iterator itr = m_LoadedFonts.find( aFilename ); - if( itr != m_LoadedFonts.end() ) + try { - ++itr->second->mRefs; - // A possible overflow cannot happen here, as it is asserted that the size is less than std::numeric_limits<long>::max() a few lines below. - a_Size = static_cast<long>(itr->second->mSize); - return reinterpret_cast<U8 const*>(itr->second->mAddress.c_str()); - } + a_Size = 0; + std::map< std::string, std::shared_ptr<ll::fonts::LoadedFont> >::iterator itr = m_LoadedFonts.find(aFilename); + if (itr != m_LoadedFonts.end()) + { + ++itr->second->mRefs; + // A possible overflow cannot happen here, as it is asserted that the size is less than std::numeric_limits<long>::max() a few lines below. + a_Size = static_cast<long>(itr->second->mSize); + return reinterpret_cast<U8 const*>(itr->second->mAddress.c_str()); + } - auto strContent = LLFile::getContents(aFilename); + auto strContent = LLFile::getContents(aFilename); - if( strContent.empty() ) - return nullptr; + if (strContent.empty()) + return nullptr; - // For fontconfig a type of long is required, std::string::size() returns size_t. I think it is safe to limit this to 2GiB and not support fonts that huge (can that even be a thing?) - llassert_always( strContent.size() < std::numeric_limits<long>::max() ); + // For fontconfig a type of long is required, std::string::size() returns size_t. I think it is safe to limit this to 2GiB and not support fonts that huge (can that even be a thing?) + llassert_always(strContent.size() < std::numeric_limits<long>::max()); - a_Size = static_cast<long>(strContent.size()); + a_Size = static_cast<long>(strContent.size()); - auto pCache = std::make_shared<ll::fonts::LoadedFont>( aFilename, strContent, a_Size ); - itr = m_LoadedFonts.insert( std::make_pair( aFilename, pCache ) ).first; + auto pCache = std::make_shared<ll::fonts::LoadedFont>(aFilename, strContent, a_Size); + itr = m_LoadedFonts.insert(std::make_pair(aFilename, pCache)).first; - return reinterpret_cast<U8 const*>(itr->second->mAddress.c_str()); + return reinterpret_cast<U8 const*>(itr->second->mAddress.c_str()); + } + catch (const std::bad_alloc&) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Failed to load font. Out of memory." << LL_ENDL; + } + return nullptr; } void LLFontManager::unloadAllFonts() diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 2c35a6acae..b8545b3ed9 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1024,8 +1024,23 @@ void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version, llifstream instream(meta_out_path, std::ifstream::in | std::ifstream::binary); LLSD in_data; - // todo: this is likely very expensive to parse, should use binary - LLSDSerialize::fromBinary(in_data, instream, LLSDSerialize::SIZE_UNLIMITED); + try + { + LLSDSerialize::fromBinary(in_data, instream, LLSDSerialize::SIZE_UNLIMITED); + } + catch( std::bad_alloc& ) + { + // Try to get a bit more memory back before we try to clear the cache. + in_data.clear(); + // Just in case it was somehow the cause, clear cache. + clearShaderCache(); + // If user run out of memory this early in init, + // we don't want to keep going just to crash again. + // Notify user and close. + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS("ShaderMgr") << "Failed to parse shader cache metadata, potentially due to size. Purged cache." << LL_ENDL; + return; + } instream.close(); if (old_cache_version == current_cache_version diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp index 53da9826ed..3941b82e75 100644 --- a/indra/newview/lldebugview.cpp +++ b/indra/newview/lldebugview.cpp @@ -38,7 +38,6 @@ #include "llappviewer.h" #include "llsceneview.h" #include "llviewertexture.h" -#include "llfloaterreg.h" #include "llscenemonitor.h" // // Globals @@ -53,7 +52,6 @@ static LLDefaultChildRegistry::Register<LLDebugView> r("debug_view"); LLDebugView::LLDebugView(const LLDebugView::Params& p) : LLView(p), - mFastTimerView(NULL), mDebugConsolep(NULL), mFloaterSnapRegion(NULL) {} @@ -89,8 +87,6 @@ void LLDebugView::init() r.setLeftTopAndSize(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f), (S32) (gViewerWindow->getWindowRectScaled().getHeight() * 0.75f)); - mFastTimerView = dynamic_cast<LLFastTimerView*>(LLFloaterReg::getInstance("block_timers")); - gSceneView = new LLSceneView(r); gSceneView->setFollowsTop(); gSceneView->setFollowsLeft(); diff --git a/indra/newview/lldebugview.h b/indra/newview/lldebugview.h index 8fa2acc3c9..ca274d6f91 100644 --- a/indra/newview/lldebugview.h +++ b/indra/newview/lldebugview.h @@ -59,7 +59,6 @@ public: void setStatsVisible(bool visible); - LLFastTimerView* mFastTimerView; LLConsole* mDebugConsolep; LLView* mFloaterSnapRegion; }; diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 187b2248de..8b9aad4641 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -3589,6 +3589,12 @@ bool LLInventoryModel::saveToFile(const std::string& filename, LL_INFOS(LOG_INV) << "Inventory saved: " << (S32)cat_count << " categories, " << (S32)it_count << " items." << LL_ENDL; } + catch(std::bad_alloc&) + { + // We are quiting, so just log an error and move on. + LL_WARNS(LOG_INV) << "Failed to save inventory to cache due to memory allocation failure." << LL_ENDL; + return false; + } catch (...) { LOG_UNHANDLED_EXCEPTION(""); |
