First public contribution.
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\debug\t_heapcorruption.cpp
15 // This is a test application that will cause heap corruption
16 // to generate BTrace events (EHeapCorruption).
21 #include "t_heapcorruption.h"
23 #include <e32base_private.h>
25 #include <e32cmn_private.h>
28 #define __NEXT_CELL(p) ((SCell*)(((TUint8*)p)+p->len))
30 TBool gEnableMemoryMonitor = EFalse;
34 Test heap that will corrupt some cells to generate BTrace events.
36 class RMyDummyHeap : public RHeap
40 void CorruptFreeMemory1()
42 SCell* f = (SCell*)&iFree;
43 f->next = (SCell*)iTop;
44 f->next += sizeof(TUint8);
48 void CorruptFreeMemory2()
50 SCell* p = (SCell*)&iFree;
55 //EBadAllocatedCellAddress
56 void CorruptAllocatedMemory1()
58 SCell* c = (SCell*)iBase;
59 SCell* f = (SCell*)&iFree;
63 c->len = (TInt)f->next - (TInt)c;
66 //additional utilities
67 void CorruptAllocatedMemorySize(void* aAddress)
69 SCell* addres = GetAddress(aAddress);
70 SCell* c = (SCell*)iBase;
82 void CorruptAllocatedMemoryAddress(void* aAddress)
84 SCell* pF = &iFree; // free cells
85 pF = pF->next; // next free cell
88 SCell* addres = GetAddress(aAddress);
89 SCell* c = (SCell*)iBase;
94 c->len = (TInt)pF->next - (TInt)c;
101 void EnableHeavyMemoryMonitoring()
103 iFlags |= EMonitorMemory;
110 - Overrunning an array using memset
111 (EHeapCorruption - EBadAllocatedCellSize)
113 void Memory_Corruption2()
115 if(gEnableMemoryMonitor)
117 RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
118 h->EnableHeavyMemoryMonitoring();
121 char* buf = new char[10]; //will be aligned to 12
122 char* buf2 = new char[10]; //will be aligned to 12
123 TInt a = User::Heap().AllocLen(buf);
124 memset(buf, 255, a+1); //memory corruption
126 if(!gEnableMemoryMonitor)
127 User::Heap().Check(); //force 'heap walker' to check the heap
130 delete buf; //when heavy monitoring is ON should send trace
134 //causes EBadFreeCellAddress corruption type
135 void Memory_Corruption3()
137 TInt* p1 = new TInt();
138 TInt* p2 = new TInt();
139 TInt* p3 = new TInt();
140 TInt* p4 = new TInt();
141 TInt* p5 = new TInt();
142 TInt* p6 = new TInt();
147 RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
148 h->CorruptFreeMemory1();
149 User::Heap().Check();
157 //causes EBadFreeCellSize RHeap corruption type
158 void Memory_Corruption4()
160 TInt* p1 = new TInt();
161 TInt* p2 = new TInt();
162 TInt* p3 = new TInt();
165 RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
166 h->CorruptFreeMemory2();
167 User::Heap().Check();
175 //causes EBadAllocatedCellAddress corruption type
176 void Memory_Corruption5()
189 RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
190 //h->CorruptAllocatedMemory1();
191 h->CorruptAllocatedMemoryAddress((void*)p7);
192 User::Heap().Check();
201 void Memory_Corruption_Special1()
203 char* buf = new char;
204 RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
205 h->EnableHeavyMemoryMonitoring();
206 h->CorruptAllocatedMemoryAddress((void*)buf);
207 delete buf;// should output EHeapCorruption trace
213 LOCAL_D TInt threadTraceHeapCorruptionTestThread(TAny* param)
215 TInt t = *((TInt*)param);
218 case RHeap::EBadAllocatedCellSize:
219 Memory_Corruption2();
221 case RHeap::EBadFreeCellAddress:
222 Memory_Corruption3();
224 case RHeap::EBadFreeCellSize:
225 Memory_Corruption4();
227 case RHeap::EBadAllocatedCellAddress:
228 Memory_Corruption5();
231 Memory_Corruption_Special1();
241 //Function to execute corruption cases.
242 TInt ExecuteTest(TInt aTestType)
248 gEnableMemoryMonitor = EFalse;
252 case 0: ////RHeap::EBadAllocatedCellSize with heavy monitoring enabled
253 type = RHeap::EBadAllocatedCellSize;
254 gEnableMemoryMonitor = ETrue;
255 r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread,
256 KDefaultStackSize, 0x2000, 0x2000, &type);
259 User::WaitForRequest(stat);
263 case 1: //RHeap::EBadFreeCellAddress:
264 type = RHeap::EBadFreeCellAddress;
265 r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread,
266 KDefaultStackSize, 0x2000, 0x2000, &type);
269 User::WaitForRequest(stat);
273 case 2: //RHeap::EBadFreeCellSize:
274 type = RHeap::EBadFreeCellSize;
275 r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread,
276 KDefaultStackSize, 0x2000, 0x2000, &type);
279 User::WaitForRequest(stat);
283 case 3: //RHeap::EBadAllocatedCellSize:
284 type = RHeap::EBadAllocatedCellSize;
285 r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread,
286 KDefaultStackSize, 0x2000, 0x2000, &type);
289 User::WaitForRequest(stat);
293 case 4: //RHeap::EBadAllocatedCellAddress:
294 type = RHeap::EBadAllocatedCellAddress;
295 r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread,
296 KDefaultStackSize, 0x2000, 0x2000, &type);
299 User::WaitForRequest(stat);
305 gEnableMemoryMonitor = ETrue;
306 r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread,
307 KDefaultStackSize, 0x2000, 0x2000, &type);
310 User::WaitForRequest(stat);
323 LOCAL_C void MainL ()
325 //reading command line
326 TInt testType = 0; //unknown test
327 TInt cmdLength = User::CommandLineLength();
328 HBufC* cmdLine = HBufC::NewLC(cmdLength);
329 TPtr clp(cmdLine->Des());
330 User::CommandLine(clp);
332 for(TInt i=0; !argv.Eos(); i++)
334 TPtrC token(argv.NextToken());
336 if(token.Compare(_L("0")) == 0)
338 if(token.Compare(_L("1")) == 0)
340 else if(token.Compare(_L("2")) == 0)
342 else if(token.Compare(_L("3")) == 0)
344 else if(token.Compare(_L("4")) == 0)
346 else if(token.Compare(_L("1000")) == 0)
349 CleanupStack::PopAndDestroy(); //cmdLine
351 ExecuteTest(testType);
354 LOCAL_C void DoStartL ()
356 // Create active scheduler (to run active objects)
357 CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
358 CleanupStack::PushL (scheduler);
359 CActiveScheduler::Install (scheduler);
363 // Delete active scheduler
364 CleanupStack::PopAndDestroy (scheduler);
369 GLDEF_C TInt E32Main()
371 // Create cleanup stack
372 CTrapCleanup* cleanup = CTrapCleanup::New();
374 // Run application code inside TRAP harness, wait keypress when terminated
375 TRAPD(mainError, DoStartL());