kerneltest/e32test/debug/t_heapcorruption.cpp
changeset 109 b3a1d9898418
parent 0 a41df078684a
child 257 3e88ff8f41d5
equal deleted inserted replaced
102:ef2a444a7410 109:b3a1d9898418
    21 #include "t_heapcorruption.h"
    21 #include "t_heapcorruption.h"
    22 #include <e32base.h>
    22 #include <e32base.h>
    23 #include <e32base_private.h>
    23 #include <e32base_private.h>
    24 #include <e32cmn.h>
    24 #include <e32cmn.h>
    25 #include <e32cmn_private.h>
    25 #include <e32cmn_private.h>
    26 
    26 #include "dla.h"
    27 
    27 #include "slab.h"
    28 #define __NEXT_CELL(p)				((SCell*)(((TUint8*)p)+p->len))
    28 #include "page_alloc.h"
       
    29 #include "heap_hybrid.h"
    29 
    30 
    30 TBool gEnableMemoryMonitor = EFalse;
    31 TBool gEnableMemoryMonitor = EFalse;
    31 
    32 
       
    33 #ifdef _DEBUG
       
    34 const TInt KDbgHeaderSize = (TInt)RHeap::EDebugHdrSize;
       
    35 #else
       
    36 const TInt KDbgHeaderSize = 0;
       
    37 #endif
    32 
    38 
    33 /**
    39 /**
    34 Test heap that will corrupt some cells to generate BTrace events.
    40 Friend class of RHeapHybrid to access to hybrid heap metadata
    35 */
    41 */
    36 class RMyDummyHeap : public RHeap
    42 class TestHybridHeap
    37 {
    43 {
    38 public:
    44 	public:
    39 	//EBadFreeCellAddress
    45 		TBool Init();
    40 	void CorruptFreeMemory1()
    46 		TBool Check();
    41 		{
    47 		TInt  AllocLen(TAny* aBfr);
    42 		SCell* f = (SCell*)&iFree;
    48 		void  EnableHeavyMemoryMonitoring();
    43 		f->next = (SCell*)iTop;
    49 		void  CorruptFreeDLBfr(TAny* aBfr);
    44 		f->next += sizeof(TUint8);
    50 		void  CorruptFreeDLBfrLth(TAny* aBfr);
    45 		}
    51 		void  CorruptAllocatedDLBfrSize(TAny* aBfr);
    46 	
    52 		TAny* CorruptAllocatedDLMemoryAddress(TAny* aBfr);		
    47 	//EBadFreeCellSize
    53 
    48 	void CorruptFreeMemory2()
    54 	private:
    49 		{
    55 		RHybridHeap* iHybridHeap;
    50 		SCell* p = (SCell*)&iFree;
       
    51 		SCell* n = p->next; 
       
    52 		n->len = iMinCell-1;
       
    53 		}
       
    54 	
       
    55 	//EBadAllocatedCellAddress
       
    56 	void CorruptAllocatedMemory1()
       
    57 		{
       
    58 		SCell* c = (SCell*)iBase;
       
    59 		SCell* f = (SCell*)&iFree;
       
    60 		
       
    61 		f = f->next;
       
    62 		f = f->next;
       
    63 		c->len = (TInt)f->next - (TInt)c;
       
    64 		}
       
    65 	
       
    66 	//additional utilities
       
    67 	void CorruptAllocatedMemorySize(void* aAddress)
       
    68 		{
       
    69 		SCell* addres = GetAddress(aAddress);
       
    70 		SCell* c = (SCell*)iBase;
       
    71 		for(;;)
       
    72 			{
       
    73 			if(c == addres)
       
    74 				{
       
    75 				c->len = iMinCell-1;
       
    76 				break;
       
    77 				}
       
    78 			c = __NEXT_CELL(c);
       
    79 			}
       
    80 		}
       
    81 		
       
    82 	void CorruptAllocatedMemoryAddress(void* aAddress)
       
    83 		{
       
    84 		SCell* pF = &iFree;				// free cells
       
    85 		pF = pF->next;				// next free cell
       
    86 		if (!pF)
       
    87 			pF = (SCell*)iTop;	
       
    88 		SCell* addres = GetAddress(aAddress);
       
    89 		SCell* c = (SCell*)iBase;
       
    90 		for(;;)
       
    91 			{
       
    92 			if(c == addres)
       
    93 				{
       
    94 				c->len = (TInt)pF->next - (TInt)c;
       
    95 				break;
       
    96 				}
       
    97 			c = __NEXT_CELL(c);
       
    98 			}
       
    99 		}
       
   100 	
       
   101 	void EnableHeavyMemoryMonitoring()
       
   102 		{
       
   103 		iFlags |= EMonitorMemory;
       
   104 		}
       
   105 };
    56 };
   106 
    57 
   107 
    58 
       
    59 
       
    60 TBool TestHybridHeap::Init()
       
    61 {
       
    62 	RHybridHeap::STestCommand cmd;
       
    63 	cmd.iCommand = RHybridHeap::EHeapMetaData;
       
    64 	RAllocator& heap = User::Allocator();
       
    65 	TInt ret = heap.DebugFunction(RHeap::EHybridHeap, &cmd, 0);
       
    66 	if (ret != KErrNone)
       
    67 		return EFalse;
       
    68 	iHybridHeap = (RHybridHeap*) cmd.iData;
       
    69 
       
    70 	return ETrue;
       
    71 }
       
    72 
       
    73 TBool TestHybridHeap::Check()
       
    74 {
       
    75 	if ( iHybridHeap )
       
    76 		{
       
    77 		iHybridHeap->Check();  
       
    78 		}
       
    79 
       
    80 	return EFalse;
       
    81 }
       
    82 
       
    83 TInt TestHybridHeap::AllocLen(TAny* aBfr)
       
    84 {
       
    85 	if ( iHybridHeap )
       
    86 		{
       
    87 		return iHybridHeap->AllocLen(aBfr);  
       
    88 		}
       
    89 	return 0;
       
    90 }
       
    91 
       
    92 void TestHybridHeap::EnableHeavyMemoryMonitoring()
       
    93 {
       
    94 	if ( iHybridHeap )
       
    95 		{
       
    96 		iHybridHeap->iFlags |= RAllocator::EMonitorMemory;
       
    97 		}
       
    98 
       
    99 }
       
   100 
       
   101 
       
   102 void TestHybridHeap::CorruptFreeDLBfr(TAny* aBfr)
       
   103 {
       
   104 
       
   105 	if ( aBfr )
       
   106 		{
       
   107 		mchunkptr p	= MEM2CHUNK((TUint8*)aBfr-KDbgHeaderSize);
       
   108 		p->iHead |= CINUSE_BIT;
       
   109 		}
       
   110 }
       
   111 
       
   112 void TestHybridHeap::CorruptFreeDLBfrLth(TAny* aBfr)
       
   113 {
       
   114 
       
   115 	if ( aBfr )
       
   116 		{
       
   117 		mchunkptr p	= MEM2CHUNK((TUint8*)aBfr-KDbgHeaderSize);
       
   118 		p->iHead &= INUSE_BITS; // Set zero length
       
   119 		}
       
   120 }
       
   121 
       
   122 void TestHybridHeap::CorruptAllocatedDLBfrSize(TAny* aBfr)
       
   123 {
       
   124 
       
   125 	if ( aBfr )
       
   126 		{
       
   127 		mchunkptr p	= MEM2CHUNK((TUint8*)aBfr-KDbgHeaderSize);
       
   128 		TInt size = CHUNKSIZE(p);
       
   129 		size  >>= 1;  // Set double length
       
   130 		p->iHead = size | INUSE_BITS; 
       
   131 		}
       
   132 }
       
   133 
       
   134 TAny* TestHybridHeap::CorruptAllocatedDLMemoryAddress(TAny* aBfr)
       
   135 {
       
   136 
       
   137 	if ( aBfr )
       
   138 		{
       
   139 		TUint8* p = (TUint8*)aBfr;
       
   140 		p += 3;
       
   141 		aBfr = (TAny*)p;
       
   142 		}
       
   143 	return aBfr;
       
   144 }
       
   145 
       
   146 
   108 /**
   147 /**
   109 Heap corruption 2:
   148 Heap corruption 0:
   110 - Overrunning an array using memset 
   149 - Allocate (DL) buffer, corrupt it and free
   111 (EHeapCorruption - EBadAllocatedCellSize)
       
   112 */
   150 */
   113 void Memory_Corruption2()
   151 void Memory_Corruption0(TestHybridHeap& aHeap)
   114 	{
   152 	{
   115 	if(gEnableMemoryMonitor)
   153 	if(gEnableMemoryMonitor)
   116 		{
   154 		aHeap.EnableHeavyMemoryMonitoring();	
   117 		RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
       
   118 		h->EnableHeavyMemoryMonitoring();	
       
   119 		}
       
   120 	
   155 	
   121 	char* buf = new char[10];  //will be aligned to 12
   156 	char* buf = new char[10];  //will be aligned to 12
   122 	char* buf2 = new char[10]; //will be aligned to 12
   157 	char* buf2 = new char[10]; //will be aligned to 12
   123 	TInt a = User::Heap().AllocLen(buf);
   158 	TInt a = aHeap.AllocLen(buf);
   124 	memset(buf, 255, a+1); //memory corruption
   159 	memset(buf, 0xfc, a+a); //memory corruption
   125 	
   160 	
   126 	if(!gEnableMemoryMonitor)
   161 	if(!gEnableMemoryMonitor)
   127 			User::Heap().Check(); //force 'heap walker' to check the heap
   162 		aHeap.Check(); //force 'heap walker' to check the heap
   128 	
   163 	
   129 	delete buf2;
   164 	delete buf2;
   130 	delete buf; //when heavy monitoring is ON should send trace
   165 	delete buf; //when heavy monitoring is ON should send trace and panic
   131 	}
   166 	}
   132 
   167 
   133 
   168 //Corrupt free DL memory and Check()
   134 //causes EBadFreeCellAddress corruption type
   169 void Memory_Corruption1(TestHybridHeap& aHeap)
   135 void Memory_Corruption3()
       
   136 	{
   170 	{
   137 	TInt* p1 = new TInt();
   171 	TInt* p1 = new TInt();
   138 	TInt* p2 = new TInt();
   172 	TInt* p2 = new TInt();
   139 	TInt* p3 = new TInt();
   173 	TInt* p3 = new TInt();
   140 	TInt* p4 = new TInt();
   174 	TInt* p4 = new TInt();
   142 	TInt* p6 = new TInt();
   176 	TInt* p6 = new TInt();
   143 	delete p2;
   177 	delete p2;
   144 	delete p4;
   178 	delete p4;
   145 	delete p6;
   179 	delete p6;
   146 	
   180 	
   147 	RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
   181 	aHeap.CorruptFreeDLBfr(p4);
   148 	h->CorruptFreeMemory1();
   182 	aHeap.Check();  // Should panic here
   149 	User::Heap().Check();
       
   150 	
   183 	
   151 	delete p5;
   184 	delete p5;
   152 	delete p3;
   185 	delete p3;
   153 	delete p1;
   186 	delete p1;
   154 	}
   187 	}
   155 
   188 
   156 
   189 
   157 //causes EBadFreeCellSize RHeap corruption type
   190 //corrupt free DL buffer length 
   158 void Memory_Corruption4()
   191 void Memory_Corruption2(TestHybridHeap& aHeap)
   159 	{
   192 	{
   160 	TInt* p1 = new TInt();
   193 	TInt* p1 = new TInt();
   161 	TInt* p2 = new TInt();
   194 	TInt* p2 = new TInt();
   162 	TInt* p3 = new TInt();
   195 	TInt* p3 = new TInt();
   163 	delete p2;
   196 	delete p2;
   164 	
   197 	
   165 	RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
   198 	aHeap.CorruptFreeDLBfrLth(p2);
   166 	h->CorruptFreeMemory2();
   199 	aHeap.Check(); // Should panic here
   167 	User::Heap().Check();
       
   168 	
   200 	
   169 	delete p3;
   201 	delete p3;
   170 	
   202 	
   171 	delete p1;
   203 	delete p1;
   172 	}
   204 	}
   173 
   205 
   174 
   206 
   175 //causes EBadAllocatedCellAddress corruption type
   207 //Corrupt allocated DL buffer size
   176 void Memory_Corruption5()
   208 void Memory_Corruption3(TestHybridHeap& aHeap)
   177 	{
   209 	{
   178 	TInt* p1 = new TInt;
   210 	TInt* p1 = new TInt;
   179 	TInt* p2 = new TInt;
   211 	TInt* p2 = new TInt;
   180 	TInt* p3 = new TInt;
   212 	TInt* p3 = new TInt;
   181 	TInt* p4 = new TInt;
   213 	TInt* p4 = new TInt;
   184 	TInt* p7 = new TInt;
   216 	TInt* p7 = new TInt;
   185 	delete p2;
   217 	delete p2;
   186 	delete p4;
   218 	delete p4;
   187 	delete p6;
   219 	delete p6;
   188 	
   220 	
   189 	RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
   221 	aHeap.CorruptAllocatedDLBfrSize(p7);
   190 	//h->CorruptAllocatedMemory1();
   222 	aHeap.Check();
   191 	h->CorruptAllocatedMemoryAddress((void*)p7);
       
   192 	User::Heap().Check();
       
   193 	
   223 	
   194 	delete p7;
   224 	delete p7;
   195 	delete p5;
   225 	delete p5;
   196 	delete p3;
   226 	delete p3;
   197 	delete p1;
   227 	delete p1;
   198 	}
   228 	}
   199 
   229 
   200 
   230 
   201 void Memory_Corruption_Special1()
   231 void Memory_Corruption4(TestHybridHeap& aHeap)
   202 	{
   232 	{
   203 	char* buf = new char;
   233 	char* buf = new char;
   204 	RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
   234 	aHeap.EnableHeavyMemoryMonitoring();
   205 	h->EnableHeavyMemoryMonitoring();
   235 	buf = (char*)aHeap.CorruptAllocatedDLMemoryAddress((TAny*)buf);
   206 	h->CorruptAllocatedMemoryAddress((void*)buf);
       
   207 	delete buf;// should output EHeapCorruption trace
   236 	delete buf;// should output EHeapCorruption trace
   208 	}
   237 	}
   209 
   238 
   210 
   239 
   211 
   240 
   212 //  Local Functions
   241 //  Local Functions
   213 LOCAL_D TInt threadTraceHeapCorruptionTestThread(TAny* param)
   242 LOCAL_D TInt threadTraceHeapCorruptionTestThread(TAny* param)
   214 	{
   243 	{
       
   244 	TestHybridHeap heap;
       
   245 	heap.Init();
       
   246 	
   215 	TInt t = *((TInt*)param);
   247 	TInt t = *((TInt*)param);
   216 	switch(t)
   248 	switch(t)
   217 		{
   249 		{
   218 		case RHeap::EBadAllocatedCellSize:
   250 		case 0:  // Corrupt allocated buffer and free it
   219 			Memory_Corruption2();
   251 			Memory_Corruption0(heap);
   220 			break;
   252 			break;
   221 		case RHeap::EBadFreeCellAddress:
   253 		case 1:
   222 			Memory_Corruption3();
   254 			Memory_Corruption1(heap);
   223 			break;
   255 			break;
   224 		case RHeap::EBadFreeCellSize:
   256 		case 2:
   225 			Memory_Corruption4();
   257 			Memory_Corruption2(heap);
   226 			break;
   258 			break;
   227 		case RHeap::EBadAllocatedCellAddress:
   259 		case 3:
   228 			Memory_Corruption5();
   260 			Memory_Corruption3(heap);
   229 			break;
   261 			break;
   230 		case 1000:
   262 		case 1000:
   231 			Memory_Corruption_Special1();
   263 			Memory_Corruption4(heap);
   232 			break;
   264 			break;
   233 		default:
   265 		default:
   234 			User::Invariant();
   266 			User::Invariant();
   235 			break;
   267 			break;
   236 		}
   268 		}
   247 	TInt r = KErrNone;
   279 	TInt r = KErrNone;
   248 	gEnableMemoryMonitor = EFalse;
   280 	gEnableMemoryMonitor = EFalse;
   249 	
   281 	
   250 	switch(aTestType)
   282 	switch(aTestType)
   251 		{
   283 		{
   252 		case 0: ////RHeap::EBadAllocatedCellSize with heavy monitoring enabled
   284 		case 0: ////Corrupt allocated DL buffer and free it with heavy monitoring enabled
   253 			type = RHeap::EBadAllocatedCellSize;
   285 			type = 0;
   254 			gEnableMemoryMonitor = ETrue;
   286 			gEnableMemoryMonitor = ETrue;
   255 			r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread, 
   287 			r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread, 
   256 					               KDefaultStackSize, 0x2000, 0x2000, &type);
   288 					               KDefaultStackSize, 0x2000, 0x2000, &type);
   257 			thread.Logon(stat);
   289 			thread.Logon(stat);
   258 			thread.Resume();
   290 			thread.Resume();
   259 			User::WaitForRequest(stat);
   291 			User::WaitForRequest(stat);
   260 			thread.Close();
   292 			thread.Close();
   261 			break;
   293 			break;
   262 			
   294 			
   263 		case 1: //RHeap::EBadFreeCellAddress:
   295 		case 1: //RHeap::EBadFreeCellAddress:
   264 			type = RHeap::EBadFreeCellAddress;
   296 			type = 1;
   265 			r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread, 
   297 			r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread, 
   266 					               KDefaultStackSize, 0x2000, 0x2000, &type);
   298 					               KDefaultStackSize, 0x2000, 0x2000, &type);
   267 			thread.Logon(stat);
   299 			thread.Logon(stat);
   268 			thread.Resume();
   300 			thread.Resume();
   269 			User::WaitForRequest(stat);
   301 			User::WaitForRequest(stat);
   270 			thread.Close();
   302 			thread.Close();
   271 		break;
   303 		break;
   272 		
   304 		
   273 		case 2: //RHeap::EBadFreeCellSize:
   305 		case 2: //RHeap::EBadFreeCellSize:
   274 			type = RHeap::EBadFreeCellSize;
   306 			type = 2;
   275 			r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread, 
   307 			r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread, 
   276 			                KDefaultStackSize, 0x2000, 0x2000, &type);
   308 			                KDefaultStackSize, 0x2000, 0x2000, &type);
   277 			thread.Logon(stat);
   309 			thread.Logon(stat);
   278 			thread.Resume();
   310 			thread.Resume();
   279 			User::WaitForRequest(stat);
   311 			User::WaitForRequest(stat);
   280 			thread.Close();
   312 			thread.Close();
   281 		break;
   313 		break;
   282 		
   314 		
   283 		case 3: //RHeap::EBadAllocatedCellSize:
   315 		case 3: //RHeap::EBadAllocatedCellSize:
   284 			type = RHeap::EBadAllocatedCellSize;
   316 			type = 0;    // Without memory monitorin this time
   285 			r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread, 
   317 			r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread, 
   286 						               KDefaultStackSize, 0x2000, 0x2000, &type);
   318 						               KDefaultStackSize, 0x2000, 0x2000, &type);
   287 			thread.Logon(stat);
   319 			thread.Logon(stat);
   288 			thread.Resume();
   320 			thread.Resume();
   289 			User::WaitForRequest(stat);
   321 			User::WaitForRequest(stat);
   290 			thread.Close();
   322 			thread.Close();
   291 		break;
   323 		break;
   292 		
   324 		
   293 		case 4: //RHeap::EBadAllocatedCellAddress:
   325 		case 4: //RHeap::EBadAllocatedCellAddress:
   294 			type = RHeap::EBadAllocatedCellAddress;
   326 			type = 3;
   295 			r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread, 
   327 			r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread, 
   296 						               KDefaultStackSize, 0x2000, 0x2000, &type);
   328 						               KDefaultStackSize, 0x2000, 0x2000, &type);
   297 			thread.Logon(stat);
   329 			thread.Logon(stat);
   298 			thread.Resume();
   330 			thread.Resume();
   299 			User::WaitForRequest(stat);
   331 			User::WaitForRequest(stat);