--- 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);