kerneltest/e32test/system/t_ctrap.cpp
branchRCL_3
changeset 257 3e88ff8f41d5
parent 256 c1f20ce4abcf
equal deleted inserted replaced
256:c1f20ce4abcf 257:3e88ff8f41d5
    37 // closed when it goes out of scope, push it on the cleanup stack,
    37 // closed when it goes out of scope, push it on the cleanup stack,
    38 // verify cleanup results are as expected.
    38 // verify cleanup results are as expected.
    39 // - Test that the Cleanup stack can go re-entrant.
    39 // - Test that the Cleanup stack can go re-entrant.
    40 // - Ensure that the stack is properly balanced with and without
    40 // - Ensure that the stack is properly balanced with and without
    41 // leaving.
    41 // leaving.
    42 // - Test creating cleanup with CCleanup::NewL in normal
       
    43 // memory conditions and condition where heap is full (panic)
       
    44 // Platforms/Drives/Compatibility:
    42 // Platforms/Drives/Compatibility:
    45 // All.
    43 // All.
    46 // Assumptions/Requirement/Pre-requisites:
    44 // Assumptions/Requirement/Pre-requisites:
    47 // Failures and causes:
    45 // Failures and causes:
    48 // Base Port information:
    46 // Base Port information:
    55 #include <e32panic.h>
    53 #include <e32panic.h>
    56 #include <e32debug.h>
    54 #include <e32debug.h>
    57 #include <e32def.h>
    55 #include <e32def.h>
    58 #include <e32def_private.h>
    56 #include <e32def_private.h>
    59 
    57 
    60 #if defined(_DEBUG)
    58 
    61 	const TInt KInitialCount=2;
    59 const TInt KInitialCount=2;
    62 	const TInt KInitialCountAll=3;
    60 const TInt KInitialCountAll=3;
    63 #endif
       
    64 
       
    65 const TInt KLeaveValue=0x12345678;
    61 const TInt KLeaveValue=0x12345678;
    66 const TInt KMaxAlloc=6;	
    62 const TInt KMaxAlloc=6;	
    67 const TInt KTableSize = 1000;
       
    68 
    63 
    69 static const TInt KHeapSize = 0x2000;
    64 static const TInt KHeapSize = 0x2000;
    70 
       
    71 
    65 
    72 enum TWhat {EPop,EPopAndDestroy,EMulti,ENull};
    66 enum TWhat {EPop,EPopAndDestroy,EMulti,ENull};
    73 
    67 
    74 class CTest : public CBase
    68 class CTest : public CBase
    75 	{
    69 	{
   110 LOCAL_D CBufFlat* gP2;
   104 LOCAL_D CBufFlat* gP2;
   111 
   105 
   112 
   106 
   113 LOCAL_C void ReallocateStackL()
   107 LOCAL_C void ReallocateStackL()
   114 	{
   108 	{
       
   109 	TInt n = 0;
   115 	for(TInt i = 0; i < KMaxAlloc; ++i)
   110 	for(TInt i = 0; i < KMaxAlloc; ++i)
   116 		{
   111 		{
   117 		(void)HBufC::NewLC(4);   //Stack re-allocation will be performed due to the additional objects pushed
   112 		HBufC *p1 = HBufC::NewLC(4);   //Stack re-allocation will be performed due to the additional objects pushed
   118 									   //into the cleanup stack
   113 									   //into the cleanup stack
       
   114 		n = p1->Length();			   //include this line to avoid warnigs for unused "p1" variable
   119 		}
   115 		}
   120 	test.Printf(_L("ReallocateStackL(): PopAndDestroy KMaxAlloc pointers\n"));
   116 	test.Printf(_L("ReallocateStackL(): PopAndDestroy KMaxAlloc pointers\n"));
   121 	CleanupStack::PopAndDestroy(KMaxAlloc);
   117 	CleanupStack::PopAndDestroy(KMaxAlloc);
   122 	}
   118 	}
   123 
   119 
   132 
   128 
   133 CTest3::~CTest3()
   129 CTest3::~CTest3()
   134 	{
   130 	{
   135 	RDebug::Printf("~CTest3(): Modify Cleanup stack by pushing items");
   131 	RDebug::Printf("~CTest3(): Modify Cleanup stack by pushing items");
   136 	
   132 	
       
   133 	TInt n = 0;
   137 	for(TInt i = 0; i < KMaxAlloc; ++i)
   134 	for(TInt i = 0; i < KMaxAlloc; ++i)
   138 		{
   135 		{
   139 		HBufC::NewLC(4);   //Stack re-allocation will be performed due to the additional objects pushed
   136 		HBufC *p1 = HBufC::NewLC(4);   //Stack re-allocation will be performed due to the additional objects pushed
   140 									   //into the cleanup stack
   137 									   //into the cleanup stack
       
   138 		n = p1->Length();			   //include this line to avoid warnigs for unused "p1" variable
   141 		}
   139 		}
   142 	}
   140 	}
   143 
   141 
   144 LOCAL_C void ModifyStack()
   142 LOCAL_C void ModifyStack()
   145 	{
   143 	{
   148 
   146 
   149 	RDebug::Printf("ModifyStack(): PopAndDestroy ptr6");
   147 	RDebug::Printf("ModifyStack(): PopAndDestroy ptr6");
   150 	CleanupStack::PopAndDestroy();
   148 	CleanupStack::PopAndDestroy();
   151 	}
   149 	}
   152 
   150 
   153 LOCAL_C TInt PanicStackModifiedFn(TAny* /*aNopFn*/)
   151 LOCAL_C TInt PanicStackModifiedFn(TAny* aNopFn)
   154 	{
   152 	{
   155 	__UHEAP_MARK;
   153 	__UHEAP_MARK;
   156 	CTrapCleanup* cleanup = CTrapCleanup::New();
   154 	CTrapCleanup* cleanup = CTrapCleanup::New();
       
   155 
       
   156 	aNopFn = NULL;		//avoid warnings for unused "aNopFn" variable
   157 
   157 
   158 	TInt err = KErrNoMemory;
   158 	TInt err = KErrNoMemory;
   159 
   159 
   160 	RDebug::Printf("PanicStackModifiedFn(): call TRAP(err, ModifyStack())");
   160 	RDebug::Printf("PanicStackModifiedFn(): call TRAP(err, ModifyStack())");
   161 
   161 
  1089 // since room is always made for a free slot. We set the allocator
  1089 // since room is always made for a free slot. We set the allocator
  1090 // to fail so that we can test that the free slot is re-established
  1090 // to fail so that we can test that the free slot is re-established
  1091 // when we do the cleanup. This test only works in debug mode.
  1091 // when we do the cleanup. This test only works in debug mode.
  1092 //
  1092 //
  1093 	__UHEAP_FAILNEXT(1);
  1093 	__UHEAP_FAILNEXT(1);
       
  1094 	TRAPD(r,pC->PushL(p6));
  1094 #if defined(_DEBUG)
  1095 #if defined(_DEBUG)
  1095 	TRAPD(r,pC->PushL(p6));
       
  1096 	test(r==KErrNoMemory);
  1096 	test(r==KErrNoMemory);
  1097 #else
       
  1098 	TRAP_IGNORE(pC->PushL(p6));
       
  1099 #endif
  1097 #endif
  1100 	__UHEAP_CHECK(KInitialCount+6);
  1098 	__UHEAP_CHECK(KInitialCount+6);
  1101 	pC->PopAndDestroyAll();
  1099 	pC->PopAndDestroyAll();
  1102 	__UHEAP_CHECK(KInitialCount);
  1100 	__UHEAP_CHECK(KInitialCount);
  1103 //
  1101 //
  1300 LOCAL_C void reentrantCleanup(TAny*)
  1298 LOCAL_C void reentrantCleanup(TAny*)
  1301 //
  1299 //
  1302 // A cleanup operation which uses a trap harness and the cleanup stack
  1300 // A cleanup operation which uses a trap harness and the cleanup stack
  1303 //
  1301 //
  1304 	{
  1302 	{
  1305 	TRAP_IGNORE(useCleanupStackL());
  1303 	TRAPD(ignore,useCleanupStackL())
  1306 	}
  1304 	}
  1307 
  1305 
  1308 LOCAL_C void addReentrantItemL()
  1306 LOCAL_C void addReentrantItemL()
  1309 	{
  1307 	{
  1310 	CleanupStack::PushL(TCleanupItem(reentrantCleanup));
  1308 	CleanupStack::PushL(TCleanupItem(reentrantCleanup));
  1424 		test.Next(_L("Let it fall out of scope"));
  1422 		test.Next(_L("Let it fall out of scope"));
  1425 		}
  1423 		}
  1426 	test.Next(_L("Check the object has closed"));
  1424 	test.Next(_L("Check the object has closed"));
  1427 	__KHEAP_CHECK(0);
  1425 	__KHEAP_CHECK(0);
  1428 
  1426 
  1429 	TRAP_IGNORE(testAutoCloseL());
  1427 	TRAPD(r, testAutoCloseL());
  1430 	test.Next(_L("Check object has been closed and cleaned up after leave"));
  1428 	test.Next(_L("Check object has been closed and cleaned up after leave"));
  1431 	__KHEAP_MARKEND;
  1429 	__KHEAP_MARKEND;
  1432 	test.End();
  1430 	test.End();
  1433 	}
  1431 	}
  1434 
  1432 
  1537 		User::Leave(KErrGeneral);
  1535 		User::Leave(KErrGeneral);
  1538 		);
  1536 		);
  1539 	test(count==1);
  1537 	test(count==1);
  1540 
  1538 
  1541 	delete pC;
  1539 	delete pC;
  1542 	test.End();
       
  1543 	}
       
  1544 
       
  1545 void testCCleanupNewL()
       
  1546 	{
       
  1547 	// don't want just in time debugging as we trap panics
       
  1548 	TBool justInTime=User::JustInTime(); 
       
  1549 	User::SetJustInTime(EFalse); 
       
  1550 
       
  1551 	// no need to test otherwise, since this calls only
       
  1552 	// CCleanup::New and that has been tested.
       
  1553 	test.Start(_L("Create cleanup NewL"));
       
  1554 	CCleanup* pC=CCleanup::NewL();
       
  1555 	test(pC!=NULL);
       
  1556 	delete pC;
       
  1557 
       
  1558 	TAny* ptrTable[KTableSize];
       
  1559 	TInt allocSize=sizeof(CCleanup);
       
  1560 	TAny* ptr=0;
       
  1561 
       
  1562 	__UHEAP_MARK;
       
  1563 
       
  1564 	TInt i=0;
       
  1565 	// first alloc 4Kb bits
       
  1566 	do
       
  1567 		{
       
  1568 		ptr=User::Alloc(0x1000);
       
  1569 		if(ptr!=NULL)
       
  1570 			{
       
  1571 			ptrTable[i]=ptr;
       
  1572 			i++;
       
  1573 			}
       
  1574 		}
       
  1575 		while (ptr!=NULL && i<KTableSize);
       
  1576 
       
  1577 	// then eat memory with size of CCleanup object granurality
       
  1578 	do
       
  1579 		{
       
  1580 		ptr=User::Alloc(allocSize);
       
  1581 		if(ptr!=NULL)
       
  1582 			{
       
  1583 			ptrTable[i]=ptr;
       
  1584 			i++;
       
  1585 			}
       
  1586 		}
       
  1587 		while (ptr!=NULL && i<KTableSize);
       
  1588 	
       
  1589 	i--; // last one failed, so lets adjust this to last successfull entry
       
  1590 
       
  1591 	TInt r=KErrNone;
       
  1592 	test.Next(_L("Create cleanup NewL while no room in heap"));
       
  1593 	TRAP(r,pC=CCleanup::NewL());
       
  1594 	test_Equal(KErrNoMemory,r);
       
  1595 
       
  1596 	for (;i>=0;i--)
       
  1597 		{
       
  1598 		User::Free(ptrTable[i]);
       
  1599 		}
       
  1600 	
       
  1601 	__UHEAP_MARKEND;
       
  1602 
       
  1603 	//restore settings
       
  1604 	User::SetJustInTime(justInTime); 
       
  1605 
       
  1606 	test.End();
  1540 	test.End();
  1607 	}
  1541 	}
  1608 
  1542 
  1609 GLDEF_C TInt E32Main()
  1543 GLDEF_C TInt E32Main()
  1610     {
  1544     {
  1663 	testStackBalance();
  1597 	testStackBalance();
  1664 
  1598 
  1665 	test.Next(_L("Test TRAP_IGNORE"));
  1599 	test.Next(_L("Test TRAP_IGNORE"));
  1666 	testTrapIgnore();
  1600 	testTrapIgnore();
  1667 
  1601 
  1668 	test.Next(_L("Test CCleanup::NewL"));
       
  1669 	testCCleanupNewL();
       
  1670 
       
  1671 	delete pT;
       
  1672 
       
  1673 	test.End();
  1602 	test.End();
  1674 	return(0);
  1603 	return(0);
  1675     }
  1604     }
  1676 
  1605