Beispiel #1
0
void FMacMallocCrashHandler::Free( void* Ptr )
{
	if ( IsOnCrashedThread() && Ptr && MemoryZone->size( MemoryZone, Ptr ) > 0 )
	{
		FMacMallocZone::Free( Ptr );
	}
}
void FGenericPlatformMallocCrash::Free( void* Ptr )
{
	if( IsOnCrashedThread() )
	{
		if( IsPtrInSmallPool(Ptr) )
		{
			FMallocCrashPool* Pool = FindPoolFromSize( GetAllocationSize(Ptr) );
			if( Pool )
			{
				Pool->TryFreeFromPool( (uint8*)Ptr );
			}
			else
			{
				FPlatformMisc::DebugBreak();
			}
		}
		else if( IsPtrInLargePool(Ptr) )
		{
			// Not implemented yet.
		}
		else
		{
			// From the previous allocator.
		}
	}
}
void* FGenericPlatformMallocCrash::Realloc( void* Ptr, SIZE_T NewSize, uint32 Alignment )
{
	if( IsOnCrashedThread() )
	{
		void* Result = nullptr;
		if( Ptr && NewSize )
		{
			SIZE_T PtrSize = 0;
			const bool bPreviousMalloc = NewSize > 0 && Ptr && !(IsPtrInLargePool(Ptr)||IsPtrInSmallPool(Ptr));

			if( bPreviousMalloc )
			{
				// At this moment, we can safely get allocation size only from the binned malloc, this may change in future.
				if( FCStringWide::Strcmp( PreviousMalloc->GetDescriptiveName(), TEXT("binned") ) == 0 )
				{
					// Realloc from the previous allocator.
					PreviousMalloc->GetAllocationSize(Ptr,PtrSize);
					if( PtrSize == 0 )
					{
						PtrSize = 0;
					}
				}
				// There is nothing we can do about it.
				else
				{
					FPlatformMisc::LowLevelOutputDebugString( TEXT( "Realloc from previous malloc, exiting...\n" ) );
					FPlatformMisc::RequestExit( true );	
				}
			}
			else
			{
				PtrSize = GetAllocationSize(Ptr);
			}
			
			Result = Malloc( NewSize, REQUIRED_ALIGNMENT );
			FMemory::Memcpy( Result, Ptr, FMath::Min(NewSize,PtrSize) );
			
			if( PtrSize > 32768 )
			{
				FPlatformMisc::LowLevelOutputDebugStringf( TEXT( "Realloc PtrSize=%u NewSize=%u PooledPtr=0x%016llx\n" ), (uint32)PtrSize, (uint32)NewSize, (uint64)Ptr );
			}

			Free( Ptr );
		}
		else if( Ptr == nullptr )
		{
			Result = Malloc( NewSize, REQUIRED_ALIGNMENT );
		}
		else
		{
			Free( Ptr );
			Result = nullptr;
		}
		return Result;
	}
	return nullptr;
}
Beispiel #4
0
bool FMacMallocCrashHandler::GetAllocationSize( void *Original, SIZE_T &SizeOut )
{
	SizeOut = 0;
	if ( IsOnCrashedThread() && Original )
	{
		SizeOut = MemoryZone->size( MemoryZone, Original );
	}
	return SizeOut > 0;
}
Beispiel #5
0
void* FMacMallocCrashHandler::Malloc( SIZE_T Size, uint32 Alignment )
{
	void* Result = nullptr;
	if ( IsOnCrashedThread() )
	{
		Result = FMacMallocZone::Malloc( Size, Alignment );
		if( !Result )
		{
			check(CrashContext);
			CrashContext->GenerateCrashInfoAndLaunchReporter();
		}
	}
	return Result;
}
void* FGenericPlatformMallocCrash::Malloc( SIZE_T Size, uint32 Alignment )
{
	const uint32 Size32 = (uint32)Size;
	if( Alignment > 16 )
	{
		FPlatformMisc::DebugBreak();
		FPlatformMisc::LowLevelOutputDebugString( TEXT( "Alignment > 16 is not supported\n" ) );
	}

	if( IsOnCrashedThread() )
	{
		FMallocCrashPool* Pool = FindPoolFromSize( Size32 );
		if( Pool )
		{
			const uint8* PooledPtr = Pool->AllocateFromPool( Size32 );	
			return (void*)PooledPtr;
		}
		else
		{
			const uint32 SizeWithOverhead = Size32 + PER_ALLOC_OVERHEAD;
			LargeMemoryPoolOffset = Align( LargeMemoryPoolOffset, REQUIRED_ALIGNMENT );

			if( LargeMemoryPoolOffset + SizeWithOverhead <= LARGE_MEMORYPOOL_SIZE )
			{
				const uint32 ReturnMemoryPoolOffset = LargeMemoryPoolOffset;
				LargeMemoryPoolOffset += SizeWithOverhead;

				FPtrInfo* PtrInfo = (FPtrInfo*)(LargeMemoryPool+ReturnMemoryPoolOffset);
				PtrInfo->Size = Size32;
				PtrInfo->Ptr = LargeMemoryPool+ReturnMemoryPoolOffset+PER_ALLOC_OVERHEAD;

				FPlatformMisc::LowLevelOutputDebugStringf( TEXT( "Malloc Size=%u LargeMemoryPoolOffset=%u \n" ), Size32, LargeMemoryPoolOffset );
				return (void*)PtrInfo->Ptr;
			}
			else
			{
				FPlatformMisc::DebugBreak();
				FPlatformMisc::LowLevelOutputDebugStringf( TEXT( "MallocCrash run out of memory allocating %u bytes, free %u bytes\n" ), Size32, LARGE_MEMORYPOOL_SIZE-LargeMemoryPoolOffset );
				FPlatformMisc::LowLevelOutputDebugString( TEXT( "Please increase LARGE_MEMORYPOOL_SIZE, exiting...\n" ) );
				FPlatformMisc::RequestExit( true );			
			}
		}
	}
	return nullptr;
}
Beispiel #7
0
void* FMacMallocCrashHandler::Realloc( void* Ptr, SIZE_T NewSize, uint32 Alignment )
{
	void* Result = nullptr;
	if ( IsOnCrashedThread() )
	{
		if ( Ptr == nullptr || MemoryZone->size( MemoryZone, Ptr ) > 0 )
		{
			Result = FMacMallocZone::Realloc( Ptr, NewSize, Alignment );
			if( NewSize && !Result )
			{
				check(CrashContext);
				CrashContext->GenerateCrashInfoAndLaunchReporter();
			}
		}
		else if ( NewSize )
		{
			if ( FCStringWide::Strcmp( OriginalHeap->GetDescriptiveName(), TEXT("ANSI") ) != 0 )
			{
				SIZE_T OldSize = 0;
				if ( OriginalHeap->GetAllocationSize( Ptr, OldSize ) )
				{
					Result = Malloc( NewSize, Alignment );
					if ( Result )
					{
						FMemory::Memcpy( Result, Ptr, FMath::Min( NewSize, OldSize ) );
					}
					else
					{
						check(CrashContext);
						CrashContext->GenerateCrashInfoAndLaunchReporter();
					}
				}
			}
			else // Can't safely handle this, so just report & exit
			{
				check(CrashContext);
				CrashContext->GenerateCrashInfoAndLaunchReporter();
			}
		}
	}
	return Result;
}