|
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". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // e32test\debug\t_heapcorruption.cpp |
|
15 // This is a test application that will cause heap corruption |
|
16 // to generate BTrace events (EHeapCorruption). |
|
17 // |
|
18 // |
|
19 |
|
20 // Include Files |
|
21 #include <e32test.h> |
|
22 #include <e32base.h> |
|
23 #include <e32panic.h> |
|
24 #include <e32cmn.h> |
|
25 #include "dla.h" |
|
26 #include "slab.h" |
|
27 #include "page_alloc.h" |
|
28 #include "heap_hybrid.h" |
|
29 |
|
30 LOCAL_D RTest test(_L("T_HEAPCHECK")); |
|
31 |
|
32 TUint32 gSeed = 0xb504f334; |
|
33 |
|
34 _LIT(KLitHeapCheck,"Heap Check"); |
|
35 |
|
36 |
|
37 TUint32 Random() |
|
38 { |
|
39 gSeed *= 69069; |
|
40 gSeed += 41; |
|
41 return gSeed; |
|
42 } |
|
43 |
|
44 TInt RandomNumber(TInt aMin, TInt aMax) |
|
45 { |
|
46 TInt y = aMax - aMin; |
|
47 if ( y <= 0 ) |
|
48 return aMax; |
|
49 TUint32 x = Random() & 0xff; |
|
50 TInt s = 0; |
|
51 while ( y > (0x100 << s) ) |
|
52 { |
|
53 s++; |
|
54 } |
|
55 return (aMin + (x << s) % y); |
|
56 } |
|
57 |
|
58 |
|
59 /** |
|
60 Friend class of RHeapHybrid to access to hybrid heap metadata |
|
61 */ |
|
62 class TestHybridHeap |
|
63 { |
|
64 public: |
|
65 TBool Init(); |
|
66 TBool Check(); |
|
67 TUint8* Alloc(TInt aLth); |
|
68 TUint8* ReAlloc(TAny* aBfr, TInt aLth, TInt aMode); |
|
69 void Free(TAny* aBfr); |
|
70 TInt AllocLen(TAny* aBfr); |
|
71 TInt AllocSize(TInt& aTotalAllocSize); |
|
72 TBool SlabAllocatorExists(); |
|
73 TBool PageAllocatorExists(); |
|
74 TBool SlabsCreated(); |
|
75 TBool CorruptSmallBin(); |
|
76 TBool CorruptTreeBin(); |
|
77 TBool ConfigurePageAllocator(); |
|
78 TInt CopyPageBitmap(TUint8* aBitmap, TInt aLth); |
|
79 TBool RestorePageBitmap(TUint8* aBitmap, TInt aLth); |
|
80 void AllocateSomeBuffers(TUint8** aBfrs, TInt aMinLth, TInt MaxLth, TInt aCount); |
|
81 TBool PrintHeapInitData(); |
|
82 |
|
83 private: |
|
84 RHybridHeap* iHybridHeap; |
|
85 }; |
|
86 |
|
87 |
|
88 |
|
89 TBool TestHybridHeap::Init() |
|
90 { |
|
91 RHybridHeap::STestCommand cmd; |
|
92 cmd.iCommand = RHybridHeap::EHeapMetaData; |
|
93 RAllocator& heap = User::Allocator(); |
|
94 TInt ret = heap.DebugFunction(RHeap::EHybridHeap, &cmd, 0); |
|
95 if (ret != KErrNone) |
|
96 return EFalse; |
|
97 iHybridHeap = (RHybridHeap*) cmd.iData; |
|
98 |
|
99 return ETrue; |
|
100 } |
|
101 |
|
102 TBool TestHybridHeap::Check() |
|
103 { |
|
104 if ( iHybridHeap ) |
|
105 { |
|
106 iHybridHeap->Check(); |
|
107 } |
|
108 |
|
109 return EFalse; |
|
110 } |
|
111 |
|
112 TUint8* TestHybridHeap::Alloc(TInt aLth) |
|
113 { |
|
114 if ( iHybridHeap ) |
|
115 { |
|
116 return (TUint8*)iHybridHeap->Alloc(aLth); |
|
117 } |
|
118 |
|
119 return NULL; |
|
120 } |
|
121 |
|
122 TUint8* TestHybridHeap::ReAlloc(TAny* aBfr, TInt aLth, TInt aMode) |
|
123 { |
|
124 if ( iHybridHeap ) |
|
125 { |
|
126 return (TUint8*)iHybridHeap->ReAlloc(aBfr, aLth, aMode); |
|
127 } |
|
128 |
|
129 return NULL; |
|
130 } |
|
131 |
|
132 void TestHybridHeap::Free(TAny* aBfr) |
|
133 { |
|
134 if ( iHybridHeap ) |
|
135 { |
|
136 iHybridHeap->Free(aBfr); |
|
137 } |
|
138 } |
|
139 |
|
140 TInt TestHybridHeap::AllocLen(TAny* aBfr) |
|
141 { |
|
142 if ( iHybridHeap ) |
|
143 { |
|
144 return iHybridHeap->AllocLen(aBfr); |
|
145 } |
|
146 return 0; |
|
147 } |
|
148 |
|
149 TInt TestHybridHeap::AllocSize(TInt& aTotalAllocSize) |
|
150 { |
|
151 aTotalAllocSize = 0; |
|
152 if ( iHybridHeap ) |
|
153 { |
|
154 return iHybridHeap->AllocSize(aTotalAllocSize); |
|
155 } |
|
156 return 0; |
|
157 } |
|
158 |
|
159 TBool TestHybridHeap::SlabAllocatorExists() |
|
160 { |
|
161 TBool status = EFalse; |
|
162 if ( iHybridHeap ) |
|
163 { |
|
164 status = !iHybridHeap->iDLOnly; |
|
165 } |
|
166 |
|
167 return status; |
|
168 } |
|
169 |
|
170 TBool TestHybridHeap::PageAllocatorExists() |
|
171 { |
|
172 TBool status = EFalse; |
|
173 if ( iHybridHeap ) |
|
174 { |
|
175 status = (!iHybridHeap->iDLOnly && (iHybridHeap->iPageThreshold < 31)); |
|
176 } |
|
177 |
|
178 return status; |
|
179 } |
|
180 |
|
181 TBool TestHybridHeap::SlabsCreated() |
|
182 { |
|
183 TBool status = EFalse; |
|
184 if ( iHybridHeap ) |
|
185 { |
|
186 status = (iHybridHeap->iSlabThreshold != 0); |
|
187 } |
|
188 |
|
189 return status; |
|
190 } |
|
191 |
|
192 TBool TestHybridHeap::ConfigurePageAllocator() |
|
193 { |
|
194 TBool status = EFalse; |
|
195 if ( iHybridHeap ) |
|
196 { |
|
197 RHybridHeap::STestCommand conf; |
|
198 conf.iCommand = RHybridHeap::ESetConfig; |
|
199 conf.iConfig.iPagePower = 14; // 16 Kb |
|
200 if ( iHybridHeap->DebugFunction(RHeap::EHybridHeap, (TAny*)&conf ) == KErrNone ) |
|
201 status = ETrue; |
|
202 } |
|
203 |
|
204 return status; |
|
205 } |
|
206 |
|
207 |
|
208 TBool TestHybridHeap::CorruptTreeBin() |
|
209 { |
|
210 TBool status = EFalse; |
|
211 if ( iHybridHeap ) |
|
212 { |
|
213 TUint i; |
|
214 for (i = 0; i < NTREEBINS; ++i) |
|
215 { |
|
216 tbinptr* tb = TREEBIN_AT(&iHybridHeap->iGlobalMallocState, i); |
|
217 tchunkptr t = *tb; |
|
218 if ( t ) |
|
219 { |
|
220 // Corrupt tree bin by writing erroneous index value |
|
221 t->iIndex ++; |
|
222 return ETrue; |
|
223 } |
|
224 } |
|
225 } |
|
226 |
|
227 return status; |
|
228 } |
|
229 |
|
230 TBool TestHybridHeap::CorruptSmallBin() |
|
231 { |
|
232 TBool status = EFalse; |
|
233 if ( iHybridHeap ) |
|
234 { |
|
235 TUint i; |
|
236 for (i = 0; i < NSMALLBINS; ++i) |
|
237 { |
|
238 sbinptr b = SMALLBIN_AT(&iHybridHeap->iGlobalMallocState, i); |
|
239 mchunkptr p = b->iBk; |
|
240 if ( p != b ) |
|
241 { |
|
242 b->iBk = b; |
|
243 status = ETrue; |
|
244 } |
|
245 } |
|
246 } |
|
247 |
|
248 return status; |
|
249 } |
|
250 |
|
251 TInt TestHybridHeap::CopyPageBitmap(TUint8* aBitmap, TInt aLth) |
|
252 { |
|
253 TInt lth = 0; |
|
254 if ( iHybridHeap && (aLth > (TInt) sizeof(iHybridHeap->iBitMapBuffer)) ) |
|
255 {// Dirty version |
|
256 memcpy(aBitmap, &iHybridHeap->iBitMapBuffer[0], sizeof(iHybridHeap->iBitMapBuffer)); |
|
257 lth = sizeof(iHybridHeap->iBitMapBuffer) << 3; |
|
258 } |
|
259 |
|
260 return lth; |
|
261 } |
|
262 |
|
263 TBool TestHybridHeap::RestorePageBitmap(TUint8* aBitmap, TInt aLth) |
|
264 { |
|
265 TBool status = EFalse; |
|
266 if ( iHybridHeap && ((aLth >> 3) <= (TInt) sizeof(iHybridHeap->iBitMapBuffer)) ) |
|
267 {// Dirty version |
|
268 memcpy(&iHybridHeap->iBitMapBuffer[0], aBitmap, (aLth >> 3)); |
|
269 status = ETrue; |
|
270 } |
|
271 |
|
272 return status; |
|
273 } |
|
274 |
|
275 void TestHybridHeap::AllocateSomeBuffers(TUint8** aBfrs, TInt aMinLth, TInt MaxLth, TInt aCount ) |
|
276 { |
|
277 |
|
278 TInt loop = RandomNumber(2, 8); |
|
279 |
|
280 while ( loop ) |
|
281 { |
|
282 // allocate all buffers |
|
283 TInt i; |
|
284 for (i=0; i<aCount; ++i) |
|
285 { |
|
286 if (!aBfrs[i]) |
|
287 { |
|
288 aBfrs[i] = (TUint8*)Alloc(RandomNumber(aMinLth, MaxLth)); |
|
289 } |
|
290 } |
|
291 |
|
292 // free some cells |
|
293 TInt n = RandomNumber(2, aCount); |
|
294 while (--n) |
|
295 { |
|
296 i = RandomNumber(2, aCount); |
|
297 if (aBfrs[i]) |
|
298 { |
|
299 Free(aBfrs[i]); |
|
300 aBfrs[i] = NULL; |
|
301 } |
|
302 } |
|
303 |
|
304 // realloc some cells |
|
305 n = RandomNumber(2, aCount); |
|
306 while (--n) |
|
307 { |
|
308 TInt new_len = RandomNumber(aMinLth, MaxLth); |
|
309 if (aBfrs[i]) |
|
310 { |
|
311 TUint8* p = (TUint8*)ReAlloc(aBfrs[i], new_len, Random()); |
|
312 if (p) |
|
313 { |
|
314 aBfrs[i] = p; |
|
315 } |
|
316 } |
|
317 } |
|
318 |
|
319 loop --; |
|
320 } |
|
321 |
|
322 } |
|
323 |
|
324 TBool TestHybridHeap::PrintHeapInitData() |
|
325 { |
|
326 TInt total; |
|
327 TInt count = AllocSize(total); |
|
328 RDebug::Printf("Heap initialised for test, alloc count: %d , alloc size: %d\n", count, total); |
|
329 if ( iHybridHeap ) |
|
330 RDebug::Printf("Heap initialised for test, iCellCount: %d , iTotalAllocSize: %d\n", iHybridHeap->iCellCount, iHybridHeap->iTotalAllocSize); |
|
331 return (count != 0); |
|
332 } |
|
333 |
|
334 |
|
335 // Local Functions |
|
336 LOCAL_D TInt HeapCheckTestThread(TAny* param) |
|
337 { |
|
338 TInt t = *((TInt*)param); |
|
339 TUint8* bfrs[256]; |
|
340 Mem::FillZ(bfrs, sizeof(bfrs)); |
|
341 TestHybridHeap heap; |
|
342 test(heap.Init()); |
|
343 |
|
344 switch( t ) |
|
345 { |
|
346 case 1: |
|
347 { |
|
348 // Overwrite Doug Lea buffer and check() |
|
349 heap.AllocateSomeBuffers(bfrs, 0x40, 0xfff0, 256); |
|
350 test(heap.PrintHeapInitData()); |
|
351 TUint8 *p = heap.Alloc(64); |
|
352 test( p != NULL ); |
|
353 Mem::FillZ(p, 80); // Heap corrupted |
|
354 heap.Check(); // This should cause panic |
|
355 break; |
|
356 } |
|
357 |
|
358 case 2: |
|
359 // Corrupt a smallbin and check |
|
360 { |
|
361 TInt i = 0; |
|
362 TBool smallbin_corrupted = EFalse; |
|
363 while ( !smallbin_corrupted ) |
|
364 { |
|
365 heap.AllocateSomeBuffers(bfrs, 0x4, 0xff, 256); |
|
366 smallbin_corrupted = heap.CorruptSmallBin(); |
|
367 i ++; |
|
368 if ( i > 9 ) |
|
369 break; |
|
370 } |
|
371 test(smallbin_corrupted); |
|
372 test(heap.PrintHeapInitData()); |
|
373 heap.Check(); // This should cause panic |
|
374 } |
|
375 break; |
|
376 |
|
377 case 3: |
|
378 // Corrupt a treebin and check |
|
379 { |
|
380 TInt i = 0; |
|
381 TBool treebin_corrupted = EFalse; |
|
382 while ( !treebin_corrupted ) |
|
383 { |
|
384 heap.AllocateSomeBuffers(bfrs, 0x100, 0x4000, 256); |
|
385 treebin_corrupted = heap.CorruptTreeBin(); |
|
386 i ++; |
|
387 if ( i > 9 ) |
|
388 break; |
|
389 } |
|
390 test(treebin_corrupted); |
|
391 test(heap.PrintHeapInitData()); |
|
392 heap.Check(); // This should cause panic |
|
393 break; |
|
394 } |
|
395 |
|
396 case 10: |
|
397 // Overwrite slab buffer and check |
|
398 { |
|
399 TInt i = 0; |
|
400 TBool slabs_created = EFalse; |
|
401 if ( !heap.SlabAllocatorExists() ) |
|
402 { |
|
403 User::Panic(KLitHeapCheck, ETHeapDebugUnmatchedCallToCheckHeap); |
|
404 } |
|
405 |
|
406 while ( !slabs_created ) |
|
407 { |
|
408 // Allocate enough buffers to cause slab allocator to be |
|
409 // initialised |
|
410 heap.AllocateSomeBuffers(bfrs, 0x4, 0x2000, 256); |
|
411 slabs_created = heap.SlabsCreated(); |
|
412 i ++; |
|
413 if ( i > 9 ) |
|
414 break; |
|
415 } |
|
416 test(slabs_created); |
|
417 test(heap.PrintHeapInitData()); |
|
418 i = 0; |
|
419 TUint8* p[10]; |
|
420 while ( i < 10 ) |
|
421 { |
|
422 p[i] = heap.Alloc(24); |
|
423 test( p[i] != NULL ); |
|
424 i ++; |
|
425 } |
|
426 i = 0; |
|
427 while ( i < 10 ) |
|
428 { |
|
429 heap.Free(p[i]); |
|
430 i +=2; |
|
431 } |
|
432 p[0] = heap.Alloc(24); |
|
433 test( p[0] != NULL ); |
|
434 memset((TUint8*)(Floor(p[0], SLABSIZE) + sizeof(slabhdr)), 0xee, KMaxSlabPayload); // Heap corrupted |
|
435 heap.Check(); // This should cause panic |
|
436 break; |
|
437 } |
|
438 |
|
439 case 11: |
|
440 // Corrupt slab header |
|
441 { |
|
442 TInt i = 0; |
|
443 TBool slabs_created = EFalse; |
|
444 if ( !heap.SlabAllocatorExists() ) |
|
445 { |
|
446 User::Panic(KLitHeapCheck, ETHeapDebugUnmatchedCallToCheckHeap); |
|
447 } |
|
448 |
|
449 while ( !slabs_created ) |
|
450 { |
|
451 // Allocate enough buffers to cause slab allocator to be |
|
452 // initialised |
|
453 heap.AllocateSomeBuffers(bfrs, 0x4, 0x2000, 256); |
|
454 slabs_created = heap.SlabsCreated(); |
|
455 i ++; |
|
456 if ( i > 9 ) |
|
457 break; |
|
458 } |
|
459 test(slabs_created); |
|
460 test(heap.PrintHeapInitData()); |
|
461 TUint8* p = heap.Alloc(28); |
|
462 test(p != NULL); |
|
463 p = Floor(p, SLABSIZE); |
|
464 *(TUint32*)p = 0xffeeddcc; |
|
465 heap.Check(); // This should cause panic |
|
466 break; |
|
467 } |
|
468 |
|
469 case 20: |
|
470 // Corrupt page bitmap data and check |
|
471 { |
|
472 if ( !heap.PageAllocatorExists() ) |
|
473 { |
|
474 User::Panic(KLitHeapCheck, ETHeapDebugUnmatchedCallToCheckHeap); |
|
475 } |
|
476 test(heap.ConfigurePageAllocator()); |
|
477 // Allocate some buffers to cause slab allocator to be |
|
478 // initialised |
|
479 heap.AllocateSomeBuffers(bfrs, 0x4000, 0x10000, 16); |
|
480 test(heap.PrintHeapInitData()); |
|
481 TUint8* bitmap = heap.Alloc(128); // For saved bitmap |
|
482 test(bitmap != NULL); |
|
483 TInt bit_lth = heap.CopyPageBitmap(bitmap, 128); |
|
484 test(bit_lth != 0); |
|
485 memset(bitmap, 0xee, (bit_lth>>3)); // corrupt bitmap data |
|
486 heap.RestorePageBitmap(bitmap, bit_lth); |
|
487 heap.Check(); // This should cause panic |
|
488 break; |
|
489 } |
|
490 |
|
491 case 21: |
|
492 // Corrupt page bitmap with a earlier freed "ghost" buffer info |
|
493 { |
|
494 if ( !heap.PageAllocatorExists() ) |
|
495 { |
|
496 User::Panic(KLitHeapCheck, ETHeapDebugUnmatchedCallToCheckHeap); |
|
497 } |
|
498 test(heap.ConfigurePageAllocator()); |
|
499 // Allocate some buffers to cause slab allocator to be |
|
500 // initialised |
|
501 heap.AllocateSomeBuffers(bfrs, 0x4000, 0x10000, 16); |
|
502 test(heap.PrintHeapInitData()); |
|
503 TUint8* bitmap = heap.Alloc(128); // For saved bitmap |
|
504 test(bitmap != NULL); |
|
505 TUint8* p = heap.Alloc(0x8000); // One more page buffer |
|
506 TInt bit_lth = heap.CopyPageBitmap(bitmap, 128); |
|
507 test(bit_lth != 0); |
|
508 heap.Free(p); |
|
509 heap.RestorePageBitmap(bitmap, bit_lth); |
|
510 heap.Check(); // This should cause panic |
|
511 break; |
|
512 } |
|
513 |
|
514 default: |
|
515 break; |
|
516 } |
|
517 |
|
518 User::Invariant(); // Should not reach here |
|
519 return 0; |
|
520 } |
|
521 |
|
522 |
|
523 class TestHeapCheck |
|
524 { |
|
525 public: |
|
526 void TestCheck(void); |
|
527 TInt TestThreadExit(RThread& aThread, TExitType aExitType, TInt aExitReason); |
|
528 }; |
|
529 |
|
530 |
|
531 TInt TestHeapCheck::TestThreadExit(RThread& aThread, TExitType aExitType, TInt aExitReason) |
|
532 { |
|
533 // Disable JIT debugging. |
|
534 TBool justInTime=User::JustInTime(); |
|
535 User::SetJustInTime(EFalse); |
|
536 |
|
537 TRequestStatus status; |
|
538 aThread.Logon(status); |
|
539 aThread.Resume(); |
|
540 User::WaitForRequest(status); |
|
541 if (aExitType != aThread.ExitType()) |
|
542 return KErrGeneral; |
|
543 |
|
544 if ( (status.Int() == ETHeapDebugUnmatchedCallToCheckHeap) && (aThread.ExitReason() == ETHeapDebugUnmatchedCallToCheckHeap)) |
|
545 { |
|
546 CLOSE_AND_WAIT(aThread); |
|
547 // Put JIT debugging back to previous status. |
|
548 User::SetJustInTime(justInTime); |
|
549 return KErrNotSupported; |
|
550 } |
|
551 |
|
552 if ( status.Int() == ERTestFailed ) |
|
553 return KErrGeneral; |
|
554 |
|
555 if ( aExitReason > 0 ) |
|
556 { |
|
557 if (aExitReason != status.Int()) |
|
558 return KErrGeneral; |
|
559 |
|
560 if (aExitReason != aThread.ExitReason()) |
|
561 return KErrGeneral; |
|
562 } |
|
563 |
|
564 CLOSE_AND_WAIT(aThread); |
|
565 |
|
566 // Put JIT debugging back to previous status. |
|
567 User::SetJustInTime(justInTime); |
|
568 return KErrNone; |
|
569 |
|
570 } |
|
571 |
|
572 void TestHeapCheck::TestCheck() |
|
573 { |
|
574 TInt type; |
|
575 TInt r; |
|
576 |
|
577 test.Next(_L("Testing Doug Lea allocator check")); |
|
578 { |
|
579 type = 1; |
|
580 RThread thread; |
|
581 test(thread.Create(_L("Check UserHeap"),HeapCheckTestThread, KDefaultStackSize, 0x1000, 0x400000, (TAny*) &type)== KErrNone); |
|
582 test(TestThreadExit(thread, EExitPanic, ETHeapBadCellAddress)==KErrNone); |
|
583 |
|
584 type = 2; |
|
585 test(thread.Create(_L("Check UserHeap"),HeapCheckTestThread, KDefaultStackSize, 0x1000, 0x400000, (TAny*) &type)==KErrNone); |
|
586 test(TestThreadExit(thread, EExitPanic, ETHeapBadCellAddress)==KErrNone); |
|
587 |
|
588 type = 3; |
|
589 test(thread.Create(_L("Check UserHeap"),HeapCheckTestThread, KDefaultStackSize, 0x1000, 0x400000, (TAny*) &type)==KErrNone); |
|
590 test(TestThreadExit(thread, EExitPanic, ETHeapBadCellAddress)==KErrNone); |
|
591 |
|
592 } |
|
593 |
|
594 test.Next(_L("Testing Slab allocator check")); |
|
595 { |
|
596 type = 10; |
|
597 RThread thread; |
|
598 test(thread.Create(_L("Check UserHeap"),HeapCheckTestThread, KDefaultStackSize, 0x1000, 0x400000, (TAny*) &type)==KErrNone); |
|
599 r = TestThreadExit(thread, EExitPanic, ETHeapBadCellAddress); |
|
600 if ( r != KErrNotSupported ) |
|
601 { |
|
602 test(r==KErrNone); |
|
603 |
|
604 type = 11; |
|
605 RThread thread; |
|
606 test(thread.Create(_L("Check UserHeap"),HeapCheckTestThread, KDefaultStackSize, 0x1000, 0x400000, (TAny*) &type)==KErrNone); |
|
607 test(TestThreadExit(thread, EExitPanic, ETHeapBadCellAddress)==KErrNone); |
|
608 } |
|
609 else test.Printf(_L("Slab allocator does not exist, testes bypassed\n")); |
|
610 } |
|
611 |
|
612 test.Next(_L("Testing Page allocator check")); |
|
613 { |
|
614 type = 20; |
|
615 RThread thread; |
|
616 test(thread.Create(_L("Check UserHeap"),HeapCheckTestThread, KDefaultStackSize, 0x1000, 0x800000, (TAny*) &type)==KErrNone); |
|
617 r = TestThreadExit(thread, EExitPanic, KErrNone); // Accept any panic reason here |
|
618 if ( r != KErrNotSupported ) |
|
619 { |
|
620 test(r==KErrNone); |
|
621 |
|
622 type = 21; |
|
623 RThread thread; |
|
624 test(thread.Create(_L("Check UserHeap"),HeapCheckTestThread, KDefaultStackSize, 0x1000, 0x800000, (TAny*) &type)==KErrNone); |
|
625 test(TestThreadExit(thread, EExitPanic, KErrNone)==KErrNone); // Accept any panic reason here |
|
626 } |
|
627 else test.Printf(_L("Page allocator does not exist, testes bypassed\n")); |
|
628 } |
|
629 |
|
630 } |
|
631 |
|
632 |
|
633 |
|
634 |
|
635 // Global Functions |
|
636 |
|
637 GLDEF_C TInt E32Main(void) |
|
638 { |
|
639 |
|
640 test.Title(); |
|
641 |
|
642 test.Start(_L("Testing Heap Check function")); |
|
643 |
|
644 TestHeapCheck T; |
|
645 |
|
646 T.TestCheck(); |
|
647 |
|
648 test.End(); |
|
649 |
|
650 return(0); |
|
651 } |
|
652 |