summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2026-03-27 19:46:38 +0200
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2026-03-28 13:35:25 +0200
commit5a7a5272a07935aae544767abc700e8fabf3cbbd (patch)
tree7d7f8bad69c9a91d71abb5654d8fd56908682092 /indra
parentb7fc5b2a9ec79f10a97fdb7b80f6eeb9cd65e0e2 (diff)
#4298 Handle various out of memory cases
Diffstat (limited to 'indra')
-rw-r--r--indra/llrender/llfontfreetype.cpp43
-rw-r--r--indra/llrender/llshadermgr.cpp19
-rw-r--r--indra/newview/lldebugview.cpp4
-rw-r--r--indra/newview/lldebugview.h1
-rw-r--r--indra/newview/llinventorymodel.cpp6
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("");