kerneltest/e32test/heap/t_heapcheck.cpp
branchRCL_3
changeset 257 3e88ff8f41d5
parent 256 c1f20ce4abcf
child 258 880ff05ad710
child 263 9e2d4f7f5028
--- a/kerneltest/e32test/heap/t_heapcheck.cpp	Tue Aug 31 16:34:26 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,652 +0,0 @@
-// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
-// All rights reserved.
-// This component and the accompanying materials are made available
-// under the terms of the License "Eclipse Public License v1.0"
-// which accompanies this distribution, and is available
-// at the URL "http://www.eclipse.org/legal/epl-v10.html".
-//
-// Initial Contributors:
-// Nokia Corporation - initial contribution.
-//
-// Contributors:
-//
-// Description:
-// e32test\debug\t_heapcorruption.cpp
-// This is a test application that will cause heap corruption 
-// to generate BTrace events (EHeapCorruption).
-// 
-//
-
-//  Include Files
-#include <e32test.h>
-#include <e32base.h>
-#include <e32panic.h>
-#include <e32cmn.h>
-#include "dla.h"
-#include "slab.h"
-#include "page_alloc.h"
-#include "heap_hybrid.h"
-
-LOCAL_D RTest test(_L("T_HEAPCHECK"));
-
-TUint32 gSeed = 0xb504f334;
-
-_LIT(KLitHeapCheck,"Heap Check");
-
-
-TUint32 Random()
-{
-	gSeed *= 69069;
-	gSeed += 41;
-	return gSeed;
-}
-
-TInt RandomNumber(TInt aMin, TInt aMax)
-{
-	TInt y = aMax - aMin;
-	if ( y <= 0 )
-		return aMax;
-	TUint32 x = Random() & 0xff;
-	TInt s = 0;
-	while ( y > (0x100 << s) )
-		{
-		s++;
-		}
-	return (aMin + (x << s) % y);
-}
-
-
-/**
-Friend class of RHeapHybrid to access to hybrid heap metadata
-*/
-class TestHybridHeap
-{
-	public:
-		TBool Init();
-		TBool Check();
-		TUint8* Alloc(TInt aLth);
-		TUint8* ReAlloc(TAny* aBfr, TInt aLth, TInt aMode);
-		void   Free(TAny* aBfr);
-		TInt  AllocLen(TAny* aBfr);
-		TInt  AllocSize(TInt& aTotalAllocSize);						
-		TBool SlabAllocatorExists();
-		TBool PageAllocatorExists();			   
-		TBool SlabsCreated();
-		TBool CorruptSmallBin();
-		TBool CorruptTreeBin();
-		TBool ConfigurePageAllocator();
-		TInt  CopyPageBitmap(TUint8* aBitmap, TInt aLth);
-		TBool RestorePageBitmap(TUint8* aBitmap, TInt aLth);
-		void AllocateSomeBuffers(TUint8** aBfrs, TInt aMinLth, TInt MaxLth, TInt aCount);
-		TBool PrintHeapInitData();		
-
-	private:
-		RHybridHeap* iHybridHeap;
-};
-
-
-
-TBool TestHybridHeap::Init()
-{
-	RHybridHeap::STestCommand cmd;
-	cmd.iCommand = RHybridHeap::EHeapMetaData;
-	RAllocator& heap = User::Allocator();
-	TInt ret = heap.DebugFunction(RHeap::EHybridHeap, &cmd, 0);
-	if (ret != KErrNone)
-		return EFalse;
-	iHybridHeap = (RHybridHeap*) cmd.iData;
-	
-	return ETrue;
-}
-
-TBool TestHybridHeap::Check()
-{
-	if ( iHybridHeap )
-		{
-		iHybridHeap->Check();  
-		}
-
-	return EFalse;
-}
-
-TUint8* TestHybridHeap::Alloc(TInt aLth)
-{
-	if ( iHybridHeap )
-		{
-		return (TUint8*)iHybridHeap->Alloc(aLth);  
-		}
-
-	return NULL;
-}
-
-TUint8* TestHybridHeap::ReAlloc(TAny* aBfr, TInt aLth, TInt aMode)
-{
-	if ( iHybridHeap )
-		{
-		return (TUint8*)iHybridHeap->ReAlloc(aBfr, aLth, aMode);  
-		}
-
-	return NULL;
-}
-
-void TestHybridHeap::Free(TAny* aBfr)
-{
-	if ( iHybridHeap )
-		{
-		iHybridHeap->Free(aBfr);  
-		}
-}
-
-TInt TestHybridHeap::AllocLen(TAny* aBfr)
-{
-	if ( iHybridHeap )
-		{
-		return iHybridHeap->AllocLen(aBfr);  
-		}
-	return 0;
-}
-
-TInt TestHybridHeap::AllocSize(TInt& aTotalAllocSize)
-{
-	aTotalAllocSize = 0;
-	if ( iHybridHeap )
-		{
-		return iHybridHeap->AllocSize(aTotalAllocSize);  
-		}
-	return 0;
-}
-
-TBool TestHybridHeap::SlabAllocatorExists()
-{
-	TBool status = EFalse;
-	if ( iHybridHeap )
-		{
-		status = !iHybridHeap->iDLOnly;
-		}
-	
-	return status;
-}
-
-TBool TestHybridHeap::PageAllocatorExists()
-{
-	TBool status = EFalse;
-	if ( iHybridHeap )
-		{
-		status = (!iHybridHeap->iDLOnly && (iHybridHeap->iPageThreshold < 31));
-		}
-
-	return status;
-}
-
-TBool TestHybridHeap::SlabsCreated()
-{
-	TBool status = EFalse;
-	if ( iHybridHeap )
-		{
-		status = (iHybridHeap->iSlabThreshold != 0);
-		}
-
-	return status;
-}
-
-TBool TestHybridHeap::ConfigurePageAllocator()
-{
-	TBool status = EFalse;
-	if ( iHybridHeap )
-		{
-		RHybridHeap::STestCommand conf;
-		conf.iCommand = RHybridHeap::ESetConfig;
-		conf.iConfig.iPagePower = 14;  // 16 Kb		
-		if ( iHybridHeap->DebugFunction(RHeap::EHybridHeap, (TAny*)&conf ) == KErrNone )
-			status = ETrue;
-		}
-
-	return status;
-}
-
-
-TBool TestHybridHeap::CorruptTreeBin()
-{
-	TBool status = EFalse;
-	if ( iHybridHeap )
-		{
-		TUint i;
-		for (i = 0; i < NTREEBINS; ++i)
-			{
-			tbinptr* tb = TREEBIN_AT(&iHybridHeap->iGlobalMallocState, i);
-			tchunkptr t = *tb;
-			if ( t )
-				{
-				// Corrupt tree bin by writing erroneous index value
-				t->iIndex ++;
-				return ETrue;
-				}
-			}
-		}
-
-	return status;
-}
-
-TBool TestHybridHeap::CorruptSmallBin()
-{
-	TBool status = EFalse;
-	if ( iHybridHeap )
-		{
-		TUint i;
-		for (i = 0; i < NSMALLBINS; ++i)
-			{
-			sbinptr b = SMALLBIN_AT(&iHybridHeap->iGlobalMallocState, i);
-			mchunkptr p = b->iBk;
-			if ( p != b )
-				{ 
-				b->iBk = b;
-				status = ETrue;
-				}
-			}
-		}
-
-	return status;
-}
-
-TInt TestHybridHeap::CopyPageBitmap(TUint8* aBitmap, TInt aLth)
-{
-	TInt lth = 0;
-	if ( iHybridHeap && (aLth > (TInt) sizeof(iHybridHeap->iBitMapBuffer)) )
-		{// Dirty version
-		memcpy(aBitmap, &iHybridHeap->iBitMapBuffer[0], sizeof(iHybridHeap->iBitMapBuffer));
-        lth = sizeof(iHybridHeap->iBitMapBuffer) << 3;
-		}
-
-	return lth;
-}
-
-TBool TestHybridHeap::RestorePageBitmap(TUint8* aBitmap, TInt aLth)
-{
-	TBool status = EFalse;
-	if ( iHybridHeap && ((aLth >> 3) <= (TInt) sizeof(iHybridHeap->iBitMapBuffer)) )
-		{// Dirty version
-		memcpy(&iHybridHeap->iBitMapBuffer[0], aBitmap, (aLth >> 3));
-		status = ETrue;
-		}
-
-	return status;
-}
-
-void TestHybridHeap::AllocateSomeBuffers(TUint8** aBfrs, TInt aMinLth, TInt MaxLth, TInt aCount )
-{
-	
-	TInt loop = RandomNumber(2, 8);
-
-	while ( loop )
-		{
-		// allocate all buffers
-		TInt i;
-		for (i=0; i<aCount; ++i)
-			{
-			if (!aBfrs[i])
-				{
-				aBfrs[i] = (TUint8*)Alloc(RandomNumber(aMinLth, MaxLth));
-				}
-			}
-
-		// free some cells
-		TInt n = RandomNumber(2, aCount);
-		while (--n)
-			{
-			i = RandomNumber(2, aCount);
-			if (aBfrs[i])
-				{
-				Free(aBfrs[i]);
-				aBfrs[i] = NULL;
-				}
-			}
-
-		// realloc some cells
-		n = RandomNumber(2, aCount);
-		while (--n)
-			{
-			TInt new_len = RandomNumber(aMinLth, MaxLth);
-			if (aBfrs[i])
-				{
-				TUint8* p = (TUint8*)ReAlloc(aBfrs[i], new_len, Random());
-				if (p)
-					{
-					aBfrs[i] = p;
-					}
-				}
-			}
-
-		loop --;
-		}
-
-}	
-
-TBool TestHybridHeap::PrintHeapInitData()
-{
-	TInt total;
-	TInt count = AllocSize(total);
-	RDebug::Printf("Heap initialised for test, alloc count: %d , alloc size: %d\n", count, total);
-	if ( iHybridHeap )
-		RDebug::Printf("Heap initialised for test, iCellCount: %d , iTotalAllocSize: %d\n", iHybridHeap->iCellCount, iHybridHeap->iTotalAllocSize);	    	
-	return (count != 0);
-}
-
-
-//  Local Functions
-LOCAL_D TInt HeapCheckTestThread(TAny* param)
-{
-	TInt t = *((TInt*)param);
-	TUint8* bfrs[256];
-	Mem::FillZ(bfrs, sizeof(bfrs));
-	TestHybridHeap heap;
-	test(heap.Init());
-
-	switch( t )
-		{
-		case 1:
-			{
-			// Overwrite Doug Lea buffer and check()
-			heap.AllocateSomeBuffers(bfrs, 0x40, 0xfff0, 256);
-			test(heap.PrintHeapInitData());
-			TUint8 *p = heap.Alloc(64);
-			test( p != NULL );
-			Mem::FillZ(p, 80);  // Heap corrupted
-			heap.Check();    // This should cause panic
-			break;
-			}
-
-		case 2:
-			// Corrupt a smallbin and check
-			{
-			TInt i = 0;
-			TBool smallbin_corrupted = EFalse;
-			while ( !smallbin_corrupted )
-				{
-				heap.AllocateSomeBuffers(bfrs, 0x4, 0xff, 256);
-				smallbin_corrupted = heap.CorruptSmallBin();
-				i ++;
-				if ( i > 9 )
-					break;
-				}
-			test(smallbin_corrupted);
-    		test(heap.PrintHeapInitData());
-			heap.Check();    // This should cause panic
-			}
-			break;
-
-		case 3:
-			// Corrupt a treebin and check
-			{
-			TInt i = 0;
-			TBool treebin_corrupted = EFalse;
-			while ( !treebin_corrupted )
-				{
-				heap.AllocateSomeBuffers(bfrs, 0x100, 0x4000, 256);
-				treebin_corrupted = heap.CorruptTreeBin();
-				i ++;
-				if ( i > 9 )
-					break;
-				}
-			test(treebin_corrupted);
-			test(heap.PrintHeapInitData());						
-			heap.Check();    // This should cause panic
-			break;
-			}
-
-		case 10:
-			// Overwrite slab buffer and check
-			{
-			TInt i = 0;
-			TBool slabs_created = EFalse;
-			if ( !heap.SlabAllocatorExists() )
-				{
-				User::Panic(KLitHeapCheck, ETHeapDebugUnmatchedCallToCheckHeap);
-				}
-
-			while ( !slabs_created )
-				{
-				// Allocate enough buffers to cause slab allocator to be
-				// initialised  		
-				heap.AllocateSomeBuffers(bfrs, 0x4, 0x2000, 256);
-				slabs_created = heap.SlabsCreated();
-				i ++;
-				if ( i > 9 )
-					break;
-				}
-			test(slabs_created);
-			test(heap.PrintHeapInitData());						
-			i = 0;
-			TUint8* p[10];
-			while ( i < 10 )
-				{
-				p[i] = heap.Alloc(24);
-				test( p[i] != NULL );
-				i ++;
-				}
-			i = 0;
-			while ( i < 10 )
-				{
-				heap.Free(p[i]);	
-				i +=2;
-				}
-			p[0] = heap.Alloc(24);
-			test( p[0] != NULL );
-			memset((TUint8*)(Floor(p[0], SLABSIZE) + sizeof(slabhdr)), 0xee, KMaxSlabPayload);  // Heap corrupted
-			heap.Check();         // This should cause panic
-			break;
-			}
-
-		case 11:
-			// Corrupt slab header
-			{
-			TInt i = 0;
-			TBool slabs_created = EFalse;
-			if ( !heap.SlabAllocatorExists() )
-				{
-				User::Panic(KLitHeapCheck, ETHeapDebugUnmatchedCallToCheckHeap);
-				}
-
-			while ( !slabs_created )
-				{
-				// Allocate enough buffers to cause slab allocator to be
-				// initialised  		
-				heap.AllocateSomeBuffers(bfrs, 0x4, 0x2000, 256);
-				slabs_created = heap.SlabsCreated();
-				i ++;
-				if ( i > 9 )
-					break;
-				}
-			test(slabs_created);
-			test(heap.PrintHeapInitData());						
-			TUint8* p = heap.Alloc(28);
-			test(p != NULL);
-			p = Floor(p, SLABSIZE);
-			*(TUint32*)p = 0xffeeddcc;
-			heap.Check();      // This should cause panic
-			break;
-			}
-
-		case 20:
-			// Corrupt page bitmap data and check
-			{
-			if ( !heap.PageAllocatorExists() )
-				{
-				User::Panic(KLitHeapCheck, ETHeapDebugUnmatchedCallToCheckHeap);
-				}
-			test(heap.ConfigurePageAllocator());
-			// Allocate some buffers to cause slab allocator to be
-			// initialised  		
-			heap.AllocateSomeBuffers(bfrs, 0x4000, 0x10000, 16);
-			test(heap.PrintHeapInitData());						
-			TUint8* bitmap = heap.Alloc(128);  // For saved bitmap
-			test(bitmap != NULL);
-			TInt bit_lth = heap.CopyPageBitmap(bitmap, 128);
-			test(bit_lth != 0);
-			memset(bitmap, 0xee, (bit_lth>>3));  //  corrupt bitmap data
-			heap.RestorePageBitmap(bitmap, bit_lth);
-			heap.Check();      // This should cause panic
-			break;
-			}
-
-		case 21:
-			// Corrupt page bitmap with a earlier freed "ghost" buffer info
-			{
-			if ( !heap.PageAllocatorExists() )
-				{
-				User::Panic(KLitHeapCheck, ETHeapDebugUnmatchedCallToCheckHeap);
-				}
-			test(heap.ConfigurePageAllocator());
-			// Allocate some buffers to cause slab allocator to be
-			// initialised  		
-			heap.AllocateSomeBuffers(bfrs, 0x4000, 0x10000, 16);
-			test(heap.PrintHeapInitData());						
-			TUint8* bitmap = heap.Alloc(128);  // For saved bitmap
-			test(bitmap != NULL);
-			TUint8* p = heap.Alloc(0x8000);     // One more page buffer
-			TInt bit_lth = heap.CopyPageBitmap(bitmap, 128);
-			test(bit_lth != 0);
-			heap.Free(p);
-			heap.RestorePageBitmap(bitmap, bit_lth);
-			heap.Check();      // This should cause panic
-			break;
-			}
-
-		default:
-			break;
-		}
-
-	User::Invariant();	// Should not reach here 
-	return 0;
-}
-
-
-class TestHeapCheck
-{
-	public:
-		void TestCheck(void);
-		TInt TestThreadExit(RThread& aThread, TExitType aExitType, TInt aExitReason);
-};
-
-
-TInt TestHeapCheck::TestThreadExit(RThread& aThread, TExitType aExitType, TInt aExitReason)
-{
-	// Disable JIT debugging.
-	TBool justInTime=User::JustInTime();
-	User::SetJustInTime(EFalse);
-
-	TRequestStatus status;
-	aThread.Logon(status); 
-	aThread.Resume();
-	User::WaitForRequest(status);
-	if (aExitType != aThread.ExitType())
-		return KErrGeneral;
-
-	if ( (status.Int() == ETHeapDebugUnmatchedCallToCheckHeap) && (aThread.ExitReason() == ETHeapDebugUnmatchedCallToCheckHeap))
-		{
-		CLOSE_AND_WAIT(aThread);
-		// Put JIT debugging back to previous status.
-		User::SetJustInTime(justInTime);
-		return KErrNotSupported;
-		}
-
-	if ( status.Int() == ERTestFailed )
-		return KErrGeneral;
-
-	if ( aExitReason > 0 )
-		{
-		if (aExitReason != status.Int())
-			return KErrGeneral;
-
-		if (aExitReason != aThread.ExitReason())
-			return KErrGeneral;		
-		}
-	
-	CLOSE_AND_WAIT(aThread);
-
-	// Put JIT debugging back to previous status.
-	User::SetJustInTime(justInTime);
-	return KErrNone;
-
-}
-
-void TestHeapCheck::TestCheck()
-{
-    TInt type;
-	TInt r;
-	
-	test.Next(_L("Testing Doug Lea allocator check"));
-	{
-	type = 1;
-	RThread thread;
-	test(thread.Create(_L("Check UserHeap"),HeapCheckTestThread, KDefaultStackSize, 0x1000, 0x400000,  (TAny*) &type)== KErrNone);
-	test(TestThreadExit(thread, EExitPanic, ETHeapBadCellAddress)==KErrNone);
-	
-    type = 2;
-    test(thread.Create(_L("Check UserHeap"),HeapCheckTestThread, KDefaultStackSize, 0x1000, 0x400000,  (TAny*) &type)==KErrNone);
-    test(TestThreadExit(thread, EExitPanic, ETHeapBadCellAddress)==KErrNone);
-
-	type = 3;
-	test(thread.Create(_L("Check UserHeap"),HeapCheckTestThread, KDefaultStackSize, 0x1000, 0x400000,  (TAny*) &type)==KErrNone);
-	test(TestThreadExit(thread, EExitPanic, ETHeapBadCellAddress)==KErrNone);
-	
-	}
-
-	test.Next(_L("Testing Slab allocator check"));	
-	{
-	type = 10;
-	RThread thread;
-	test(thread.Create(_L("Check UserHeap"),HeapCheckTestThread, KDefaultStackSize, 0x1000, 0x400000,  (TAny*) &type)==KErrNone);
-	r = TestThreadExit(thread, EExitPanic, ETHeapBadCellAddress);
-	if ( r != KErrNotSupported )
-		{
-		test(r==KErrNone);
-		
-		type = 11;
-		RThread thread;
-		test(thread.Create(_L("Check UserHeap"),HeapCheckTestThread, KDefaultStackSize, 0x1000, 0x400000,  (TAny*) &type)==KErrNone);
-		test(TestThreadExit(thread, EExitPanic, ETHeapBadCellAddress)==KErrNone);
-		}
-	else test.Printf(_L("Slab allocator does not exist, testes bypassed\n"));	
-	}
-
-	test.Next(_L("Testing Page allocator check"));	
-	{
-	type = 20;
-	RThread thread;
-	test(thread.Create(_L("Check UserHeap"),HeapCheckTestThread, KDefaultStackSize, 0x1000, 0x800000,  (TAny*) &type)==KErrNone);	
-	r = TestThreadExit(thread, EExitPanic, KErrNone);   // Accept any panic reason here
-	if ( r != KErrNotSupported )
-		{
-		test(r==KErrNone);
-
-		type = 21;
-		RThread thread;
-		test(thread.Create(_L("Check UserHeap"),HeapCheckTestThread, KDefaultStackSize, 0x1000, 0x800000,  (TAny*) &type)==KErrNone);
-		test(TestThreadExit(thread, EExitPanic,	KErrNone)==KErrNone);  // Accept any panic reason here
-		}
-    else test.Printf(_L("Page allocator does not exist, testes bypassed\n"));
-	}
-
-}
-
-
-
-
-//  Global Functions
-
-GLDEF_C TInt E32Main(void)
-	{
-
-	test.Title();
-	
-	test.Start(_L("Testing Heap Check function"));
-	
-	TestHeapCheck T;
-	
-	T.TestCheck();
-
-	test.End();
-	
-	return(0);
-	}
-