1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/debug/t_heapcorruption.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,382 @@
1.4 +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test\debug\t_heapcorruption.cpp
1.18 +// This is a test application that will cause heap corruption
1.19 +// to generate BTrace events (EHeapCorruption).
1.20 +//
1.21 +//
1.22 +
1.23 +// Include Files
1.24 +#include "t_heapcorruption.h"
1.25 +#include <e32base.h>
1.26 +#include <e32base_private.h>
1.27 +#include <e32cmn.h>
1.28 +#include <e32cmn_private.h>
1.29 +
1.30 +
1.31 +#define __NEXT_CELL(p) ((SCell*)(((TUint8*)p)+p->len))
1.32 +
1.33 +TBool gEnableMemoryMonitor = EFalse;
1.34 +
1.35 +
1.36 +/**
1.37 +Test heap that will corrupt some cells to generate BTrace events.
1.38 +*/
1.39 +class RMyDummyHeap : public RHeap
1.40 +{
1.41 +public:
1.42 + //EBadFreeCellAddress
1.43 + void CorruptFreeMemory1()
1.44 + {
1.45 + SCell* f = (SCell*)&iFree;
1.46 + f->next = (SCell*)iTop;
1.47 + f->next += sizeof(TUint8);
1.48 + }
1.49 +
1.50 + //EBadFreeCellSize
1.51 + void CorruptFreeMemory2()
1.52 + {
1.53 + SCell* p = (SCell*)&iFree;
1.54 + SCell* n = p->next;
1.55 + n->len = iMinCell-1;
1.56 + }
1.57 +
1.58 + //EBadAllocatedCellAddress
1.59 + void CorruptAllocatedMemory1()
1.60 + {
1.61 + SCell* c = (SCell*)iBase;
1.62 + SCell* f = (SCell*)&iFree;
1.63 +
1.64 + f = f->next;
1.65 + f = f->next;
1.66 + c->len = (TInt)f->next - (TInt)c;
1.67 + }
1.68 +
1.69 + //additional utilities
1.70 + void CorruptAllocatedMemorySize(void* aAddress)
1.71 + {
1.72 + SCell* addres = GetAddress(aAddress);
1.73 + SCell* c = (SCell*)iBase;
1.74 + for(;;)
1.75 + {
1.76 + if(c == addres)
1.77 + {
1.78 + c->len = iMinCell-1;
1.79 + break;
1.80 + }
1.81 + c = __NEXT_CELL(c);
1.82 + }
1.83 + }
1.84 +
1.85 + void CorruptAllocatedMemoryAddress(void* aAddress)
1.86 + {
1.87 + SCell* pF = &iFree; // free cells
1.88 + pF = pF->next; // next free cell
1.89 + if (!pF)
1.90 + pF = (SCell*)iTop;
1.91 + SCell* addres = GetAddress(aAddress);
1.92 + SCell* c = (SCell*)iBase;
1.93 + for(;;)
1.94 + {
1.95 + if(c == addres)
1.96 + {
1.97 + c->len = (TInt)pF->next - (TInt)c;
1.98 + break;
1.99 + }
1.100 + c = __NEXT_CELL(c);
1.101 + }
1.102 + }
1.103 +
1.104 + void EnableHeavyMemoryMonitoring()
1.105 + {
1.106 + iFlags |= EMonitorMemory;
1.107 + }
1.108 +};
1.109 +
1.110 +
1.111 +/**
1.112 +Heap corruption 2:
1.113 +- Overrunning an array using memset
1.114 +(EHeapCorruption - EBadAllocatedCellSize)
1.115 +*/
1.116 +void Memory_Corruption2()
1.117 + {
1.118 + if(gEnableMemoryMonitor)
1.119 + {
1.120 + RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
1.121 + h->EnableHeavyMemoryMonitoring();
1.122 + }
1.123 +
1.124 + char* buf = new char[10]; //will be aligned to 12
1.125 + char* buf2 = new char[10]; //will be aligned to 12
1.126 + TInt a = User::Heap().AllocLen(buf);
1.127 + memset(buf, 255, a+1); //memory corruption
1.128 +
1.129 + if(!gEnableMemoryMonitor)
1.130 + User::Heap().Check(); //force 'heap walker' to check the heap
1.131 +
1.132 + delete buf2;
1.133 + delete buf; //when heavy monitoring is ON should send trace
1.134 + }
1.135 +
1.136 +
1.137 +//causes EBadFreeCellAddress corruption type
1.138 +void Memory_Corruption3()
1.139 + {
1.140 + TInt* p1 = new TInt();
1.141 + TInt* p2 = new TInt();
1.142 + TInt* p3 = new TInt();
1.143 + TInt* p4 = new TInt();
1.144 + TInt* p5 = new TInt();
1.145 + TInt* p6 = new TInt();
1.146 + delete p2;
1.147 + delete p4;
1.148 + delete p6;
1.149 +
1.150 + RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
1.151 + h->CorruptFreeMemory1();
1.152 + User::Heap().Check();
1.153 +
1.154 + delete p5;
1.155 + delete p3;
1.156 + delete p1;
1.157 + }
1.158 +
1.159 +
1.160 +//causes EBadFreeCellSize RHeap corruption type
1.161 +void Memory_Corruption4()
1.162 + {
1.163 + TInt* p1 = new TInt();
1.164 + TInt* p2 = new TInt();
1.165 + TInt* p3 = new TInt();
1.166 + delete p2;
1.167 +
1.168 + RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
1.169 + h->CorruptFreeMemory2();
1.170 + User::Heap().Check();
1.171 +
1.172 + delete p3;
1.173 +
1.174 + delete p1;
1.175 + }
1.176 +
1.177 +
1.178 +//causes EBadAllocatedCellAddress corruption type
1.179 +void Memory_Corruption5()
1.180 + {
1.181 + TInt* p1 = new TInt;
1.182 + TInt* p2 = new TInt;
1.183 + TInt* p3 = new TInt;
1.184 + TInt* p4 = new TInt;
1.185 + TInt* p5 = new TInt;
1.186 + TInt* p6 = new TInt;
1.187 + TInt* p7 = new TInt;
1.188 + delete p2;
1.189 + delete p4;
1.190 + delete p6;
1.191 +
1.192 + RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
1.193 + //h->CorruptAllocatedMemory1();
1.194 + h->CorruptAllocatedMemoryAddress((void*)p7);
1.195 + User::Heap().Check();
1.196 +
1.197 + delete p7;
1.198 + delete p5;
1.199 + delete p3;
1.200 + delete p1;
1.201 + }
1.202 +
1.203 +
1.204 +void Memory_Corruption_Special1()
1.205 + {
1.206 + char* buf = new char;
1.207 + RMyDummyHeap* h = (RMyDummyHeap*)&User::Heap();
1.208 + h->EnableHeavyMemoryMonitoring();
1.209 + h->CorruptAllocatedMemoryAddress((void*)buf);
1.210 + delete buf;// should output EHeapCorruption trace
1.211 + }
1.212 +
1.213 +
1.214 +
1.215 +// Local Functions
1.216 +LOCAL_D TInt threadTraceHeapCorruptionTestThread(TAny* param)
1.217 + {
1.218 + TInt t = *((TInt*)param);
1.219 + switch(t)
1.220 + {
1.221 + case RHeap::EBadAllocatedCellSize:
1.222 + Memory_Corruption2();
1.223 + break;
1.224 + case RHeap::EBadFreeCellAddress:
1.225 + Memory_Corruption3();
1.226 + break;
1.227 + case RHeap::EBadFreeCellSize:
1.228 + Memory_Corruption4();
1.229 + break;
1.230 + case RHeap::EBadAllocatedCellAddress:
1.231 + Memory_Corruption5();
1.232 + break;
1.233 + case 1000:
1.234 + Memory_Corruption_Special1();
1.235 + break;
1.236 + default:
1.237 + User::Invariant();
1.238 + break;
1.239 + }
1.240 + return 0;
1.241 + }
1.242 +
1.243 +
1.244 +//Function to execute corruption cases.
1.245 +TInt ExecuteTest(TInt aTestType)
1.246 + {
1.247 + RThread thread;
1.248 + TInt type;
1.249 + TRequestStatus stat;
1.250 + TInt r = KErrNone;
1.251 + gEnableMemoryMonitor = EFalse;
1.252 +
1.253 + switch(aTestType)
1.254 + {
1.255 + case 0: ////RHeap::EBadAllocatedCellSize with heavy monitoring enabled
1.256 + type = RHeap::EBadAllocatedCellSize;
1.257 + gEnableMemoryMonitor = ETrue;
1.258 + r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread,
1.259 + KDefaultStackSize, 0x2000, 0x2000, &type);
1.260 + thread.Logon(stat);
1.261 + thread.Resume();
1.262 + User::WaitForRequest(stat);
1.263 + thread.Close();
1.264 + break;
1.265 +
1.266 + case 1: //RHeap::EBadFreeCellAddress:
1.267 + type = RHeap::EBadFreeCellAddress;
1.268 + r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread,
1.269 + KDefaultStackSize, 0x2000, 0x2000, &type);
1.270 + thread.Logon(stat);
1.271 + thread.Resume();
1.272 + User::WaitForRequest(stat);
1.273 + thread.Close();
1.274 + break;
1.275 +
1.276 + case 2: //RHeap::EBadFreeCellSize:
1.277 + type = RHeap::EBadFreeCellSize;
1.278 + r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread,
1.279 + KDefaultStackSize, 0x2000, 0x2000, &type);
1.280 + thread.Logon(stat);
1.281 + thread.Resume();
1.282 + User::WaitForRequest(stat);
1.283 + thread.Close();
1.284 + break;
1.285 +
1.286 + case 3: //RHeap::EBadAllocatedCellSize:
1.287 + type = RHeap::EBadAllocatedCellSize;
1.288 + r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread,
1.289 + KDefaultStackSize, 0x2000, 0x2000, &type);
1.290 + thread.Logon(stat);
1.291 + thread.Resume();
1.292 + User::WaitForRequest(stat);
1.293 + thread.Close();
1.294 + break;
1.295 +
1.296 + case 4: //RHeap::EBadAllocatedCellAddress:
1.297 + type = RHeap::EBadAllocatedCellAddress;
1.298 + r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread,
1.299 + KDefaultStackSize, 0x2000, 0x2000, &type);
1.300 + thread.Logon(stat);
1.301 + thread.Resume();
1.302 + User::WaitForRequest(stat);
1.303 + thread.Close();
1.304 + break;
1.305 +
1.306 + case 1000:
1.307 + type = 1000;
1.308 + gEnableMemoryMonitor = ETrue;
1.309 + r = thread.Create(_L("t_tbrace_heapcorruption"), threadTraceHeapCorruptionTestThread,
1.310 + KDefaultStackSize, 0x2000, 0x2000, &type);
1.311 + thread.Logon(stat);
1.312 + thread.Resume();
1.313 + User::WaitForRequest(stat);
1.314 + thread.Close();
1.315 + break;
1.316 +
1.317 + default:
1.318 + User::Invariant();
1.319 + break;
1.320 + }
1.321 +
1.322 + return r;
1.323 + }
1.324 +
1.325 +
1.326 +LOCAL_C void MainL ()
1.327 + {
1.328 + //reading command line
1.329 + TInt testType = 0; //unknown test
1.330 + TInt cmdLength = User::CommandLineLength();
1.331 + HBufC* cmdLine = HBufC::NewLC(cmdLength);
1.332 + TPtr clp(cmdLine->Des());
1.333 + User::CommandLine(clp);
1.334 + TLex argv(clp);
1.335 + for(TInt i=0; !argv.Eos(); i++)
1.336 + {
1.337 + TPtrC token(argv.NextToken());
1.338 +
1.339 + if(token.Compare(_L("0")) == 0)
1.340 + testType = 0;
1.341 + if(token.Compare(_L("1")) == 0)
1.342 + testType = 1;
1.343 + else if(token.Compare(_L("2")) == 0)
1.344 + testType = 2;
1.345 + else if(token.Compare(_L("3")) == 0)
1.346 + testType = 3;
1.347 + else if(token.Compare(_L("4")) == 0)
1.348 + testType = 4;
1.349 + else if(token.Compare(_L("1000")) == 0)
1.350 + testType = 1000;
1.351 + }
1.352 + CleanupStack::PopAndDestroy(); //cmdLine
1.353 +
1.354 + ExecuteTest(testType);
1.355 + }
1.356 +
1.357 +LOCAL_C void DoStartL ()
1.358 + {
1.359 + // Create active scheduler (to run active objects)
1.360 + CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
1.361 + CleanupStack::PushL (scheduler);
1.362 + CActiveScheduler::Install (scheduler);
1.363 +
1.364 + MainL ();
1.365 +
1.366 + // Delete active scheduler
1.367 + CleanupStack::PopAndDestroy (scheduler);
1.368 + }
1.369 +
1.370 +// Global Functions
1.371 +
1.372 +GLDEF_C TInt E32Main()
1.373 + {
1.374 + // Create cleanup stack
1.375 + CTrapCleanup* cleanup = CTrapCleanup::New();
1.376 +
1.377 + // Run application code inside TRAP harness, wait keypress when terminated
1.378 + TRAPD(mainError, DoStartL());
1.379 + if (mainError)
1.380 + return mainError;
1.381 +
1.382 + delete cleanup;
1.383 + return KErrNone;
1.384 + }
1.385 +