diff options
author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2024-07-19 20:17:37 +0300 |
---|---|---|
committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2024-07-29 21:20:38 +0300 |
commit | c4ff0b48898de86b9ee8e198395e16a8429c8aa4 (patch) | |
tree | 6b142eebb25f0f7fee253daa4d4b83b1d7f94a2c | |
parent | 5d25504f8335132d0d222b266f8772062c88b335 (diff) |
viewer#2071 Properly handle 'out of memory' for meshes
-rw-r--r-- | indra/llcharacter/llkeyframemotion.cpp | 14 | ||||
-rw-r--r-- | indra/newview/llfloaterbvhpreview.cpp | 14 | ||||
-rw-r--r-- | indra/newview/llmeshrepository.cpp | 60 | ||||
-rw-r--r-- | indra/newview/llviewerassetupload.cpp | 7 | ||||
-rw-r--r-- | indra/newview/llviewerobject.cpp | 7 |
5 files changed, 90 insertions, 12 deletions
diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index 6c060d7980..6790f1ad56 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -2227,7 +2227,12 @@ bool LLKeyframeMotion::dumpToFile(const std::string& name) } S32 file_size = getFileSize(); - U8* buffer = new U8[file_size]; + U8* buffer = new(std::nothrow) U8[file_size]; + if (!buffer) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Bad memory allocation for buffer, file: " << name << " " << file_size << LL_ENDL; + } LL_DEBUGS("BVH") << "Dumping " << outfilename << LL_ENDL; LLDataPackerBinaryBuffer dp(buffer, file_size); @@ -2435,7 +2440,12 @@ void LLKeyframeMotion::onLoadComplete(const LLUUID& asset_uuid, LLFileSystem file(asset_uuid, type, LLFileSystem::READ); S32 size = file.getSize(); - U8* buffer = new U8[size]; + U8* buffer = new(std::nothrow) U8[size]; + if (!buffer) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Bad memory allocation for buffer of size: " << size << LL_ENDL; + } file.read((U8*)buffer, size); /*Flawfinder: ignore*/ LL_DEBUGS("Animation") << "Loading keyframe data for: " << motionp->getName() << ":" << motionp->getID() << " (" << size << " bytes)" << LL_ENDL; diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index 2cb930922a..3d81d01e16 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -285,7 +285,12 @@ bool LLFloaterBvhPreview::postBuild() // create data buffer for keyframe initialization S32 buffer_size = loaderp->getOutputSize(); - U8* buffer = new U8[buffer_size]; + U8* buffer = new(std::nothrow) U8[buffer_size]; + if (!buffer) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Bad memory allocation for buffer, size: " << buffer_size << LL_ENDL; + } LLDataPackerBinaryBuffer dp(buffer, buffer_size); @@ -992,7 +997,12 @@ void LLFloaterBvhPreview::onBtnOK(void* userdata) LLKeyframeMotion* motionp = (LLKeyframeMotion*)floaterp->mAnimPreview->getDummyAvatar()->findMotion(floaterp->mMotionID); S32 file_size = motionp->getFileSize(); - U8* buffer = new U8[file_size]; + U8* buffer = new(std::nothrow) U8[file_size]; + if (!buffer) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Bad memory allocation for buffer, size: " << file_size << LL_ENDL; + } LLDataPackerBinaryBuffer dp(buffer, file_size); if (motionp->serialize(dp)) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 1c64ed6822..a1b2d502af 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1360,7 +1360,19 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry) U8* buffer = new(std::nothrow) U8[size]; if (!buffer) { - LL_WARNS(LOG_MESH) << "Failed to allocate memory for skin info, size: " << size << LL_ENDL; + // Not sure what size is reasonable for skin info, + // but if 20MB allocation failed, we definetely have issues + const S32 MAX_SIZE = 20 * 1024 * 1024; //20MB + if (size < MAX_SIZE) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Bad memory allocation for skin info, size: " << size << LL_ENDL; + } + else + { + // Ignore failures for anomalously large data + LL_WARNS(LOG_MESH) << "Failed to allocate memory for skin info, size: " << size << LL_ENDL; + } return false; } LLMeshRepository::sCacheBytesRead += size; @@ -1473,7 +1485,19 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) U8* buffer = new(std::nothrow) U8[size]; if (!buffer) { - LL_WARNS(LOG_MESH) << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL; + // Not sure what size is reasonable for decomposition + // but if 20MB allocation failed, we definetely have issues + const S32 MAX_SIZE = 20 * 1024 * 1024; //20MB + if (size < MAX_SIZE) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL; + } + else + { + // Ignore failures for anomalously large decompositiions + LL_WARNS(LOG_MESH) << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL; + } return false; } LLMeshRepository::sCacheBytesRead += size; @@ -1575,7 +1599,19 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) U8* buffer = new(std::nothrow) U8[size]; if (!buffer) { - LL_WARNS(LOG_MESH) << "Failed to allocate memory for physics shape, size: " << size << LL_ENDL; + // Not sure what size is reasonable for physcis + // but if 20MB allocation failed, we definetely have issues + const S32 MAX_SIZE = 20 * 1024 * 1024; //20MB + if (size < MAX_SIZE) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL; + } + else + { + // Ignore failures for anomalously large meshes + LL_WARNS(LOG_MESH) << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL; + } return false; } file.read(buffer, size); @@ -1766,9 +1802,21 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U8* buffer = new(std::nothrow) U8[size]; if (!buffer) { - LL_WARNS(LOG_MESH) << "Can't allocate memory for mesh " << mesh_id << " LOD " << lod << ", size: " << size << LL_ENDL; - // todo: for now it will result in indefinite constant retries, should result in timeout - // or in retry-count and disabling mesh. (but usually viewer is beyond saving at this point) + // Not sure what size is reasonable for a mesh, + // but if 20MB allocation failed, we definetely have issues + const S32 MAX_SIZE = 20 * 1024 * 1024; //20MB + if (size < MAX_SIZE) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Can't allocate memory for mesh " << mesh_id << " LOD " << lod << ", size: " << size << LL_ENDL; + } + else + { + // Ignore failures for anomalously large data + LL_WARNS(LOG_MESH) << "Can't allocate memory for mesh " << mesh_id << " LOD " << lod << ", size: " << size << LL_ENDL; + // todo: for now it will result in indefinite constant retries, should result in timeout + // or in retry-count and disabling mesh. (but usually viewer is beyond saving at this point) + } return false; } LLMeshRepository::sCacheBytesRead += size; diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 50128d826a..b74b48b9f6 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -479,7 +479,12 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile() else { S32 size = LLAPRFile::size(getFileName()); - U8* buffer = new U8[size]; + U8* buffer = new(std::nothrow) U8[size]; + if (!buffer) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Bad memory allocation for buffer, size: " << size << LL_ENDL; + } S32 size_read = infile.read(buffer,size); if (size_read != size) { diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 094d866bc1..fd85d75d98 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1521,7 +1521,12 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, S32 size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ExtraParams); if (size > 0) { - U8 *buffer = new U8[size]; + U8 *buffer = new(std::nothrow) U8[size]; + if (!buffer) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Bad memory allocation for buffer, size: " << size << LL_ENDL; + } mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ExtraParams, buffer, size, block_num); LLDataPackerBinaryBuffer dp(buffer, size); |