kerneltest/e32test/debug/t_heapcorruption.cpp
changeset 109 b3a1d9898418
parent 0 a41df078684a
child 257 3e88ff8f41d5
--- a/kerneltest/e32test/debug/t_heapcorruption.cpp	Mon May 03 13:47:38 2010 +0300
+++ b/kerneltest/e32test/debug/t_heapcorruption.cpp	Fri May 14 17:13:29 2010 +0300
@@ -23,116 +23,150 @@
 #include <e32base_private.h>
 #include <e32cmn.h>
 #include <e32cmn_private.h>
+#include "dla.h"
+#include "slab.h"
+#include "page_alloc.h"
+#include "heap_hybrid.h"
+
+TBool gEnableMemoryMonitor = EFalse;
+
+#ifdef _DEBUG
+const TInt KDbgHeaderSize = (TInt)RHeap::EDebugHdrSize;
+#else
+const TInt KDbgHeaderSize = 0;
+#endif
+
+/**
+Friend class of RHeapHybrid to access to hybrid heap metadata
+*/
+class TestHybridHeap
+{
+	public:
+		TBool Init();
+		TBool Check();
+		TInt  AllocLen(TAny* aBfr);
+		void  EnableHeavyMemoryMonitoring();
+		void  CorruptFreeDLBfr(TAny* aBfr);
+		void  CorruptFreeDLBfrLth(TAny* aBfr);
+		void  CorruptAllocatedDLBfrSize(TAny* aBfr);
+		TAny* CorruptAllocatedDLMemoryAddress(TAny* aBfr);		
+
+	private:
+		RHybridHeap* iHybridHeap;
+};
+
 
 
-#define __NEXT_CELL(p)				((SCell*)(((TUint8*)p)+p->len))
+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;
+}
+
+TInt TestHybridHeap::AllocLen(TAny* aBfr)
+{
+	if ( iHybridHeap )
+		{
+		return iHybridHeap->AllocLen(aBfr);  
+		}
+	return 0;
+}
+
+void TestHybridHeap::EnableHeavyMemoryMonitoring()
+{
+	if ( iHybridHeap )
+		{
+		iHybridHeap->iFlags |= RAllocator::EMonitorMemory;
+		}
+
+}
+
 
-TBool gEnableMemoryMonitor = EFalse;
+void TestHybridHeap::CorruptFreeDLBfr(TAny* aBfr)
+{
+
+	if ( aBfr )
+		{
+		mchunkptr p	= MEM2CHUNK((TUint8*)aBfr-KDbgHeaderSize);
+		p->iHead |= CINUSE_BIT;
+		}
+}
+
+void TestHybridHeap::CorruptFreeDLBfrLth(TAny* aBfr)
+{
+
+	if ( aBfr )
+		{
+		mchunkptr p	= MEM2CHUNK((TUint8*)aBfr-KDbgHeaderSize);
+		p->iHead &= INUSE_BITS; // Set zero length
+		}
+}
+
+void TestHybridHeap::CorruptAllocatedDLBfrSize(TAny* aBfr)
+{
+
+	if ( aBfr )
+		{
+		mchunkptr p	= MEM2CHUNK((TUint8*)aBfr-KDbgHeaderSize);
+		TInt size = CHUNKSIZE(p);
+		size  >>= 1;  // Set double length
+		p->iHead = size | INUSE_BITS; 
+		}
+}
+
+TAny* TestHybridHeap::CorruptAllocatedDLMemoryAddress(TAny* aBfr)
+{
+
+	if ( aBfr )
+		{
+		TUint8* p = (TUint8*)aBfr;
+		p += 3;
+		aBfr = (TAny*)p;
+		}
+	return aBfr;
+}
 
 
 /**
-Test heap that will corrupt some cells to generate BTrace events.
+Heap corruption 0:
+- Allocate (DL) buffer, corrupt it and free
 */
-class RMyDummyHeap : public RHeap
-{
-public:
-	//EBadFreeCellAddress
-	void CorruptFreeMemory1()
-		{
-		SCell* f = (SCell*)&iFree;
-		f->next = (SCell*)iTop;
-		f->next += sizeof(TUint8);
-		}
-	
-	//EBadFreeCellSize
-	void CorruptFreeMemory2()
-		{
-		SCell* p = (SCell*)&iFree;
-		SCell* n = p->next; 
-		n->len = iMinCell-1;
-		}
-	
-	//EBadAllocatedCellAddress
-	void CorruptAllocatedMemory1()
-		{
-		SCell* c = (SCell*)iBase;
-		SCell* f = (SCell*)&iFree;
-		
-		f = f->next;
-		f = f->next;
-		c->len = (TInt)f->next - (TInt)c;
-		}
-	
-	//additional utilities
-	void CorruptAllocatedMemorySize(void* aAddress)
-		{
-		SCell* addres = GetAddress(aAddress);
-		SCell* c = (SCell*)iBase;
-		for(;;)
-			{
-			if(c == addres)
-				{
-				c->len = iMinCell-1;
-				break;
-				}
-			c = __NEXT_CELL(c);
-			}
-		}
-		
-	void CorruptAllocatedMemoryAddress(void* aAddress)
-		{
-		SCell* pF = &iFree;				// free cells
-		pF = pF->next;				// next free cell
-		if (!pF)
-			pF = (SCell*)iTop;	
-		SCell* addres = GetAddress(aAddress);
-		SCell* c = (SCell*)iBase;
-		for(;;)
-			{
-			if(c == addres)
-				{
-				c->len = (TInt)pF->next - (TInt)c;
-				break;
-				}
-			c = __NEXT_CELL(c);
-			}
-		}
-	
-	void EnableHeavyMemoryMonitoring()
-		{
-		iFlags |= EMonitorMemory;
-		}
-};
-
-
-/**
-Heap corruption 2:
-- Overrunning an array using memset 
-(EHeapCorruption - EBadAllocatedCellSize)
-*/
-void Memory_Corruption2()
+void Memory_Corruption0(TestHybridHeap& aHeap)
 	{
 	if(gEnableMemoryMonitor)
-		{
-		RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
-		h->EnableHeavyMemoryMonitoring();	
-		}
+		aHeap.EnableHeavyMemoryMonitoring();	
 	
 	char* buf = new char[10];  //will be aligned to 12
 	char* buf2 = new char[10]; //will be aligned to 12
-	TInt a = User::Heap().AllocLen(buf);
-	memset(buf, 255, a+1); //memory corruption
+	TInt a = aHeap.AllocLen(buf);
+	memset(buf, 0xfc, a+a); //memory corruption
 	
 	if(!gEnableMemoryMonitor)
-			User::Heap().Check(); //force 'heap walker' to check the heap
+		aHeap.Check(); //force 'heap walker' to check the heap
 	
 	delete buf2;
-	delete buf; //when heavy monitoring is ON should send trace
+	delete buf; //when heavy monitoring is ON should send trace and panic
 	}
 
-
-//causes EBadFreeCellAddress corruption type
-void Memory_Corruption3()
+//Corrupt free DL memory and Check()
+void Memory_Corruption1(TestHybridHeap& aHeap)
 	{
 	TInt* p1 = new TInt();
 	TInt* p2 = new TInt();
@@ -144,9 +178,8 @@
 	delete p4;
 	delete p6;
 	
-	RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
-	h->CorruptFreeMemory1();
-	User::Heap().Check();
+	aHeap.CorruptFreeDLBfr(p4);
+	aHeap.Check();  // Should panic here
 	
 	delete p5;
 	delete p3;
@@ -154,17 +187,16 @@
 	}
 
 
-//causes EBadFreeCellSize RHeap corruption type
-void Memory_Corruption4()
+//corrupt free DL buffer length 
+void Memory_Corruption2(TestHybridHeap& aHeap)
 	{
 	TInt* p1 = new TInt();
 	TInt* p2 = new TInt();
 	TInt* p3 = new TInt();
 	delete p2;
 	
-	RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
-	h->CorruptFreeMemory2();
-	User::Heap().Check();
+	aHeap.CorruptFreeDLBfrLth(p2);
+	aHeap.Check(); // Should panic here
 	
 	delete p3;
 	
@@ -172,8 +204,8 @@
 	}
 
 
-//causes EBadAllocatedCellAddress corruption type
-void Memory_Corruption5()
+//Corrupt allocated DL buffer size
+void Memory_Corruption3(TestHybridHeap& aHeap)
 	{
 	TInt* p1 = new TInt;
 	TInt* p2 = new TInt;
@@ -186,10 +218,8 @@
 	delete p4;
 	delete p6;
 	
-	RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
-	//h->CorruptAllocatedMemory1();
-	h->CorruptAllocatedMemoryAddress((void*)p7);
-	User::Heap().Check();
+	aHeap.CorruptAllocatedDLBfrSize(p7);
+	aHeap.Check();
 	
 	delete p7;
 	delete p5;
@@ -198,12 +228,11 @@
 	}
 
 
-void Memory_Corruption_Special1()
+void Memory_Corruption4(TestHybridHeap& aHeap)
 	{
 	char* buf = new char;
-	RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
-	h->EnableHeavyMemoryMonitoring();
-	h->CorruptAllocatedMemoryAddress((void*)buf);
+	aHeap.EnableHeavyMemoryMonitoring();
+	buf = (char*)aHeap.CorruptAllocatedDLMemoryAddress((TAny*)buf);
 	delete buf;// should output EHeapCorruption trace
 	}
 
@@ -212,23 +241,26 @@
 //  Local Functions
 LOCAL_D TInt threadTraceHeapCorruptionTestThread(TAny* param)
 	{
+	TestHybridHeap heap;
+	heap.Init();
+	
 	TInt t = *((TInt*)param);
 	switch(t)
 		{
-		case RHeap::EBadAllocatedCellSize:
-			Memory_Corruption2();
+		case 0:  // Corrupt allocated buffer and free it
+			Memory_Corruption0(heap);
 			break;
-		case RHeap::EBadFreeCellAddress:
-			Memory_Corruption3();
+		case 1:
+			Memory_Corruption1(heap);
 			break;
-		case RHeap::EBadFreeCellSize:
-			Memory_Corruption4();
+		case 2:
+			Memory_Corruption2(heap);
 			break;
-		case RHeap::EBadAllocatedCellAddress:
-			Memory_Corruption5();
+		case 3:
+			Memory_Corruption3(heap);
 			break;
 		case 1000:
-			Memory_Corruption_Special1();
+			Memory_Corruption4(heap);
 			break;
 		default:
 			User::Invariant();
@@ -249,8 +281,8 @@
 	
 	switch(aTestType)
 		{
-		case 0: ////RHeap::EBadAllocatedCellSize with heavy monitoring enabled
-			type = RHeap::EBadAllocatedCellSize;
+		case 0: ////Corrupt allocated DL buffer and free it with heavy monitoring enabled
+			type = 0;
 			gEnableMemoryMonitor = ETrue;
 			r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread, 
 					               KDefaultStackSize, 0x2000, 0x2000, &type);
@@ -261,7 +293,7 @@
 			break;
 			
 		case 1: //RHeap::EBadFreeCellAddress:
-			type = RHeap::EBadFreeCellAddress;
+			type = 1;
 			r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread, 
 					               KDefaultStackSize, 0x2000, 0x2000, &type);
 			thread.Logon(stat);
@@ -271,7 +303,7 @@
 		break;
 		
 		case 2: //RHeap::EBadFreeCellSize:
-			type = RHeap::EBadFreeCellSize;
+			type = 2;
 			r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread, 
 			                KDefaultStackSize, 0x2000, 0x2000, &type);
 			thread.Logon(stat);
@@ -281,7 +313,7 @@
 		break;
 		
 		case 3: //RHeap::EBadAllocatedCellSize:
-			type = RHeap::EBadAllocatedCellSize;
+			type = 0;    // Without memory monitorin this time
 			r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread, 
 						               KDefaultStackSize, 0x2000, 0x2000, &type);
 			thread.Logon(stat);
@@ -291,7 +323,7 @@
 		break;
 		
 		case 4: //RHeap::EBadAllocatedCellAddress:
-			type = RHeap::EBadAllocatedCellAddress;
+			type = 3;
 			r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread, 
 						               KDefaultStackSize, 0x2000, 0x2000, &type);
 			thread.Logon(stat);