diff options
| author | andreykproductengine <andreykproductengine@lindenlab.com> | 2017-11-06 16:46:16 +0200 | 
|---|---|---|
| committer | andreykproductengine <andreykproductengine@lindenlab.com> | 2017-11-06 16:46:16 +0200 | 
| commit | 7161619d6c0ee790c5741d0df028e428052e5fcc (patch) | |
| tree | c6bb2f0e47e3fe28256a89226c5b82bf92d043cc /indra | |
| parent | ece5e6b827ad278fec4a8c859fe97977cc4f1fda (diff) | |
MAINT-7978 - Fixed allocation crash in doRead(), workers should never crash
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/newview/lltexturecache.cpp | 112 | 
1 files changed, 68 insertions, 44 deletions
| diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 062ee37864..435d833345 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -387,22 +387,35 @@ bool LLTextureCacheRemoteWorker::doRead()  		}  		// Allocate read buffer  		mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize); -		S32 bytes_read = LLAPRFile::readEx(local_filename,  -											 mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool()); -		if (bytes_read != mDataSize) + +		if (mReadData)  		{ - 			LL_WARNS() << "Error reading file from local cache: " << local_filename - 					<< " Bytes: " << mDataSize << " Offset: " << mOffset +			S32 bytes_read = LLAPRFile::readEx( local_filename, +												mReadData, +												mOffset, +												mDataSize, +												mCache->getLocalAPRFilePool()); + +			if (bytes_read != mDataSize) +			{ + 				LL_WARNS() << "Error reading file from local cache: " << local_filename + 						<< " Bytes: " << mDataSize << " Offset: " << mOffset   					<< " / " << mDataSize << LL_ENDL; -			mDataSize = 0; -			FREE_MEM(LLImageBase::getPrivatePool(), mReadData); -			mReadData = NULL; +				mDataSize = 0; +				FREE_MEM(LLImageBase::getPrivatePool(), mReadData); +				mReadData = NULL; +			} +			else +			{ +				mImageSize = local_size; +				mImageLocal = TRUE; +			}  		}  		else  		{ -			//LL_INFOS() << "texture " << mID.asString() << " found in local_assets" << LL_ENDL; -			mImageSize = local_size; -			mImageLocal = TRUE; + 			LL_WARNS() << "Error allocating memory for cache: " << local_filename + 					<< " of size: " << mDataSize << LL_ENDL; +			mDataSize = 0;  		}  		// We're done...  		done = true; @@ -477,44 +490,55 @@ bool LLTextureCacheRemoteWorker::doRead()  			// Reserve the whole data buffer first  			U8* data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize); - -			// Set the data file pointers taking the read offset into account. 2 cases: -			if (mOffset < TEXTURE_CACHE_ENTRY_SIZE) +			if (data)  			{ -				// Offset within the header record. That means we read something from the header cache. -				// Note: most common case is (mOffset = 0), so this is the "normal" code path. -				data_offset = TEXTURE_CACHE_ENTRY_SIZE - mOffset;	// i.e. TEXTURE_CACHE_ENTRY_SIZE if mOffset nul (common case) -				file_offset = 0; -				file_size = mDataSize - data_offset; -				// Copy the raw data we've been holding from the header cache into the new sized buffer -				llassert_always(mReadData); -				memcpy(data, mReadData, data_offset); -				FREE_MEM(LLImageBase::getPrivatePool(), mReadData); -				mReadData = NULL; -			} -			else -			{ -				// Offset bigger than the header record. That means we haven't read anything yet. -				data_offset = 0; -				file_offset = mOffset - TEXTURE_CACHE_ENTRY_SIZE; -				file_size = mDataSize; -				// No data from header cache to copy in that case, we skipped it all -			} +				// Set the data file pointers taking the read offset into account. 2 cases: +				if (mOffset < TEXTURE_CACHE_ENTRY_SIZE) +				{ +					// Offset within the header record. That means we read something from the header cache. +					// Note: most common case is (mOffset = 0), so this is the "normal" code path. +					data_offset = TEXTURE_CACHE_ENTRY_SIZE - mOffset;	// i.e. TEXTURE_CACHE_ENTRY_SIZE if mOffset nul (common case) +					file_offset = 0; +					file_size = mDataSize - data_offset; +					// Copy the raw data we've been holding from the header cache into the new sized buffer +					llassert_always(mReadData); +					memcpy(data, mReadData, data_offset); +					FREE_MEM(LLImageBase::getPrivatePool(), mReadData); +					mReadData = NULL; +				} +				else +				{ +					// Offset bigger than the header record. That means we haven't read anything yet. +					data_offset = 0; +					file_offset = mOffset - TEXTURE_CACHE_ENTRY_SIZE; +					file_size = mDataSize; +					// No data from header cache to copy in that case, we skipped it all +				} -			// Now use that buffer as the object read buffer -			llassert_always(mReadData == NULL); -			mReadData = data; +				// Now use that buffer as the object read buffer +				llassert_always(mReadData == NULL); +				mReadData = data; -			// Read the data at last -			S32 bytes_read = LLAPRFile::readEx(filename,  -											 mReadData + data_offset, -											 file_offset, file_size, -											 mCache->getLocalAPRFilePool()); -			if (bytes_read != file_size) +				// Read the data at last +				S32 bytes_read = LLAPRFile::readEx(filename,  +												 mReadData + data_offset, +												 file_offset, file_size, +												 mCache->getLocalAPRFilePool()); +				if (bytes_read != file_size) +				{ +					LL_WARNS() << "LLTextureCacheWorker: "  << mID +							<< " incorrect number of bytes read from body: " << bytes_read +							<< " / " << file_size << LL_ENDL; +					FREE_MEM(LLImageBase::getPrivatePool(), mReadData); +					mReadData = NULL; +					mDataSize = -1; // failed +					done = true; +				} +			} +			else  			{  				LL_WARNS() << "LLTextureCacheWorker: "  << mID -						<< " incorrect number of bytes read from body: " << bytes_read -						<< " / " << file_size << LL_ENDL; +					<< " failed to allocate memory for reading: " << mDataSize << LL_ENDL;  				FREE_MEM(LLImageBase::getPrivatePool(), mReadData);  				mReadData = NULL;  				mDataSize = -1; // failed | 
