--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dbgsrv/coredumpserver/plugins/formatters/dexc/test/tdexcformatter.cpp Tue Mar 02 10:33:16 2010 +0530
@@ -0,0 +1,522 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <e32std.h>
+#include <e32base.h>
+#include "tdexcformatter.h"
+#include "dexcformatter.h"
+
+CDexcFormatterTest * CDexcFormatterTest::NewL(RTest &itest)
+{
+ CDexcFormatterTest *self = CDexcFormatterTest::NewLC(itest);
+ CleanupStack::Pop();
+ return self;
+}
+
+CDexcFormatterTest * CDexcFormatterTest::NewLC(RTest &itest)
+{
+ CDexcFormatterTest *self = new(ELeave) CDexcFormatterTest(itest);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+}
+
+void CDexcFormatterTest::ConstructL()
+{
+ server = new(ELeave) CTestCrashDataSource;
+ formatter = CDexcFormatter::NewL();
+ writer = CTestDataSave::NewL();
+ formatter->ConfigureDataSourceL(server);
+ formatter->ConfigureDataSaveL(writer);
+}
+
+CDexcFormatterTest::CDexcFormatterTest(RTest &aTest) : itest(aTest) { }
+
+CDexcFormatterTest::~CDexcFormatterTest()
+{
+ delete server;
+ delete writer;
+ delete formatter;
+}
+
+void CDexcFormatterTest::CleanupEComArray(TAny* aArray)
+{
+ (static_cast<RImplInfoPtrArray*> (aArray))->ResetAndDestroy();
+ REComSession::FinalClose();
+}
+
+void CDexcFormatterTest::TestSuiteL(TSuite aSuite) const
+{
+ RDebug::Print(_L("-> TestSuite(%d)\n"), aSuite);
+ TInt err;
+ TBuf<23> name(KTestName);
+ name.AppendNum(aSuite);
+ itest.Next(name);
+
+ switch(aSuite)
+ {
+ case EConfigData:
+ {
+ RDebug::Print(_L("EConfigData starting...\n"));
+ TRAP(err, formatter->ConfigureDataSourceL(server));
+ itest(err == KErrNone);
+ itest(server == formatter->iDataSource);
+
+ TRAP(err, formatter->ConfigureDataSaveL(writer));
+ itest(err == KErrNone);
+ itest(writer == formatter->iDataSave);
+
+ TRAP(err, formatter->ConfigureDataSourceL(NULL));
+ itest(err == KErrNoMemory);
+
+ TRAP(err, formatter->ConfigureDataSaveL(NULL));
+ itest(err == KErrNoMemory);
+ RDebug::Print(_L("EConfigData passed!\n"));
+ break;
+ }
+
+ case EFindImplementation:
+ {
+
+ RDebug::Print(_L("EFindImplementation starting...\n"));
+ RImplInfoPtrArray infoArray;
+ TCleanupItem cleanup(CDexcFormatterTest::CleanupEComArray, (TAny*)&infoArray);
+ CleanupStack::PushL(cleanup);
+
+ TRAPD(err, CDexcFormatter::ListAllImplementationsL(infoArray));
+ itest(err == KErrNone);
+
+ CCoreDumpFormatter* findImpFormatter = 0;
+ RBuf description;
+ description.CreateL(MaxPluginDescription);
+ CleanupClosePushL(description);
+
+ err = KErrNotFound;
+ for (TInt i = 0; i < infoArray.Count(); i++)
+ {
+ TUid uid = infoArray[i]->ImplementationUid();
+ findImpFormatter = CCoreDumpFormatter::NewL(uid);
+ findImpFormatter->GetDescription(description);
+ delete findImpFormatter;
+ RDebug::Print(_L("found plugin[%d]: (%S)\n"), i, &description);
+ if(description == KPluginDescription())
+ {
+ itest(uid == KDexcFormatterUid);
+ err = KErrNone;
+ break;
+ }
+ description.Zero();
+ }
+ CleanupStack::PopAndDestroy();
+ itest(err == KErrNone);
+ CleanupStack::PopAndDestroy(); // infoArray, results in a call to CleanupEComArray
+ break;
+
+ }
+
+ case EConfigParams:
+ {
+ RDebug::Print(_L("EConfigParams starting\n"));
+
+ _LIT( KTrueFalseOpt, "True,False" );
+ _LIT( KFalseOpt, "False" );
+ _LIT( KTrueOpt, "True" );
+
+ TInt err;
+ COptionConfig * param = NULL;
+ TInt paramsCount = formatter->GetNumberConfigParametersL(); //it should be non leaving call
+ itest(paramsCount == formatter->iConfigList.Count());
+
+ TRAP(err, param = formatter->GetConfigParameterL(0));
+ itest(param->Index() == CDexcFormatter::EDumpStack);
+ itest(param->Uid() == KDEXCFormatterUid );
+ itest(param->Source() == COptionConfig::EFormatterPlugin);
+ itest(param->Type() == COptionConfig::ETBool);
+ itest(param->Options() == KTrueFalseOpt);
+ itest(param->ValueAsBool() == 1);
+ param = NULL;
+
+ TRAP(err, param = formatter->GetConfigParameterL(1));
+ itest(param->Index() == CDexcFormatter::EAsciiStack);
+ itest(param->Uid() == KDEXCFormatterUid );
+ itest(param->Source() == COptionConfig::EFormatterPlugin);
+ itest(param->Type() == COptionConfig::ETBool);
+ itest(param->Options() == KTrueFalseOpt);
+ itest(param->ValueAsBool() == 0);
+ param = NULL;
+
+ RDebug::Printf("->TRAP(err, param = formatter->GetConfigParameterL(paramsCount))\n");
+ TRAP(err, param = formatter->GetConfigParameterL(paramsCount));
+ itest(err == KErrBadHandle);
+ param = NULL;
+
+ RDebug::Printf("formatter->SetConfigParameterL( 0, (TInt)EFalse, KFalseOpt );\n");
+ TRAP(err, formatter->SetConfigParameterL( 0, (TInt)EFalse, KFalseOpt ));
+ itest(err == KErrNone);
+ itest(formatter->iConfigList[0]->ValueAsBool() == EFalse);
+ TRAP(err, param = formatter->GetConfigParameterL(0));
+ itest(formatter->iConfigList[0]->ValueAsBool() == EFalse);
+ itest(param->ValueAsDesc() == KFalseOpt);
+
+ RDebug::Printf("formatter->SetConfigParameterL( 0, (TInt)ETrue, KTrueOpt );\n");
+ TRAP(err, formatter->SetConfigParameterL( 0, (TInt)ETrue, KNullDesC ));
+ itest(err == KErrNone);
+ TRAP(err, param = formatter->GetConfigParameterL(0));
+ itest(formatter->iConfigList[0]->ValueAsBool());
+ itest(param->ValueAsDesc() == KTrueOpt);
+
+ RDebug::Print(_L("EConfigParams finished\n"));
+
+ break;
+ }
+
+ case EDumpLog:
+ {
+ RDebug::Print(_L("EDumpLog starting.... \n"));
+ // 0123456789012345678901234567890123456789012345678901234567890123456789012345
+ _LIT8(KLine, "----------------------------------------------------------------------------");
+ // 0 12345678901234567890 1 23456789012345 6 78901234567890 1 2345678901234?
+ _LIT8(KLogDump, "%S\r\nEKA2 USER CRASH LOG\r\nThread Name: %S\r\nThread ID: %u\r\nUser Stack %08X-%08X\r\n");
+ TBuf8<65+76+KMaxName+11+16> reference; //line, thread name, id and 2x 8-digits
+
+ //add newLC
+ CThreadInfo *thread = CThreadInfo::NewL(KCrashTid,
+ KCrashThreadName,
+ KCrashPid,
+ KCrashThreadPriority,
+ KCrashSvcStackPtr,
+ KCrashSvcStackAddr,
+ KCrashSvcStackSize,
+ KCrashUsrStackAddr,
+ KCrashUsrStackSize);
+
+ RDebug::Print(_L(" -> writer->OpenL(_L(\"\"), handle)\n"));
+ writer->OpenL(_L("")); //clear writer buffer
+ formatter->DumpLogL(*thread);
+ delete thread;
+ itest(writer->iData != KLogDump());
+ reference.Format(KLogDump, &KLine, &KCrashThreadName8, KCrashTid, KCrashUsrStackAddr, KCrashUsrStackAddr + KCrashUsrStackSize);
+ itest(writer->iData == reference);
+ RDebug::Print(_L("EDumpLog finished\n"));
+ break;
+ }
+
+ case EDumpPanicInfo:
+ {
+ RDebug::Print(_L("EDumpPanicInfo starting.... \n"));
+ // 0123456 7 8 9 0
+ _LIT8(KPanicDump, "Panic: %S-%d\r\n");
+ RBuf8 reference;
+ reference.CreateL(KPanicDump().Length() + 11 + KMaxExitCategoryName);
+ CleanupClosePushL(reference);
+
+ TCrashInfo crash;
+ crash.iReason = KCrashReason;
+ crash.iCategory = KCrashCategory;
+
+ writer->OpenL(_L("")); //clear writer buffer
+ formatter->DumpPanicInfoL(crash);
+ itest(writer->iData != KPanicDump());
+
+ reference.Format(KPanicDump, &KCrashCategory8, KCrashReason);
+
+ itest(writer->iData == reference);
+
+ CleanupStack::PopAndDestroy(); //reference
+ RDebug::Print(_L("EDumpPanicInfo finished\n"));
+ break;
+ }
+
+ case EDumpExcInfo:
+ {
+ RDebug::Print(_L("EDumpExcInfo starting.... \n"));
+
+ _LIT8(KExcDump, "\r\nUNHANDLED EXCEPTION:\r\ncode=%d PC=%08x FAR=%08x FSR=%08x\r\nR13svc=%08x R14svc=%08x SPSRsvc=%08x\r\n");
+ // 012345 6 7890123456789012345678901234567890123 4 5
+ RBuf8 reference;
+ reference.CreateL(KExcDump().Length() + 11 + 6*4);
+ CleanupClosePushL(reference);
+
+ TCrashInfo crash;
+ crash.iType = TCrashInfo::ECrashException;
+ crash.iContext.iExcCode = KCrashExcCode;
+
+ crash.iContext.iFaultAddress = KCrashFaultAddress;
+ crash.iContext.iFaultStatus = KCrashFaultStatus;
+
+ crash.iContext.iR15 = KRegValue32 + KCrashTid;
+ crash.iContext.iR13Svc = crash.iContext.iR15 + 1;
+ crash.iContext.iR14Svc = crash.iContext.iR15 + 2;
+ crash.iContext.iSpsrSvc = crash.iContext.iR15 + 3;
+
+ writer->Open(_L("")); //clear writer buffer
+ formatter->DumpExcInfoL(crash);
+
+ RDebug::Print( _L("-> itest(writer->iData != KExcDump())\n") );
+ itest(writer->iData != KExcDump());
+
+ TInt32 code = KCrashExcCode;
+ TInt32 pc = KRegValue32 + KCrashTid; //index of r15
+ TInt32 far = KCrashFaultAddress;
+ TInt32 fsr = KCrashFaultStatus;
+ TInt32 r13svc = KRegValue32 + KCrashTid + 1; //index of r13svc
+ TInt32 r14svc = KRegValue32 + KCrashTid + 2; //index of r14svc
+ TInt32 spsr = KRegValue32 + KCrashTid + 3; //index of spsr
+
+ reference.Format(KExcDump, code, pc, far, fsr, r13svc, r14svc, spsr);
+
+ /*
+ RBuf8 referencePrint;
+ referencePrint.CreateL(256);
+ referencePrint.Copy( reference );
+ char *tonp = (char*) referencePrint.PtrZ();
+ LOG_MSG2(" KExcDump=%s\n", tonp);
+ referencePrint.Close();
+ writer->Print();
+ */
+ RDebug::Print( _L("-> itest(writer->iData == reference)\n") );
+ itest(writer->iData == reference);
+
+ CleanupStack::PopAndDestroy(); //reference
+ RDebug::Print(_L("EDumpExcInfo finished\n"));
+
+ break;
+ }
+
+ case EDumpRegisters:
+ {
+ RDebug::Print(_L("EDumpRegisters starting.... \n"));
+
+ _LIT8(KCpsrDump, "\r\nUSER REGISTERS:\r\nCPSR=%08x\r\n");
+ _LIT8(KRegsDump, "r%02d=%08x %08x %08x %08x\r\n");
+ RBuf8 reference;
+ reference.CreateL(KCpsrDump().Length() + 4 + KCoreRegsCount * (KRegsDump().Length() + 4*4));
+ CleanupClosePushL(reference);
+
+ writer->Open(_L("")); //clear writer buffer
+ TRAP(err, formatter->DumpRegistersL(KCrashTid));
+ itest(err == KErrNone);
+ itest(writer->iData != KRegsDump());
+
+ TInt32 cpsr = KRegValue32 + KCrashTid + 16; //index of cpsr
+
+ reference.Format(KCpsrDump, cpsr);
+ TBuf8<41> line;
+ #define REG_VAL(i) ( KRegValue32 + KCrashTid + i )
+ for(TInt i = 0; i < KCoreRegsCount; i+=4)
+ {
+ TInt reg0 = REG_VAL(i);
+ TInt reg1 = REG_VAL(i+1);
+ TInt reg2 = REG_VAL(i+2);
+ TInt reg3 = REG_VAL(i+3);
+ line.Format(KRegsDump, i, reg0, reg1, reg2, reg3);
+ reference.Append(line);
+ }
+ #undef REG_VAL
+ itest(writer->iData == reference);
+ CleanupStack::PopAndDestroy(); //reference
+ RDebug::Print(_L("EDumpRegisters finished\n"));
+
+ break;
+ }
+
+ case EDumpCodeSegs:
+ {
+ RDebug::Print(_L("EDumpCodeSegs starting.... \n"));
+
+ _LIT8(KSegsLine, "%08X-%08X %S\r\n");
+ RBuf8 line;
+ CleanupClosePushL(line);
+ line.CreateL(KSegsLine().Length() + 2*4 + KMaxFileName);
+ // 0123456789012345679012
+ _LIT8(KSegsDump, "\r\nCODE SEGMENTS:\r\n");
+ RBuf8 reference;
+ CleanupClosePushL(reference);
+ reference.CreateL(KSegsDump().Length() + KCodeSegsCount * (line.MaxLength()) + 76);
+
+ writer->Open(_L("")); //clear writer buffer
+ formatter->DumpCodeSegsL(KCrashPid);
+ //writer->Print();
+
+ itest(writer->iData != KSegsDump());
+ RDebug::Print( _L(" writer->iData.Length() = %d\n"), writer->iData.Length() );
+
+ reference = KSegsDump();
+ TUint base;
+ TUint size;
+
+ // See CTestCrashDataSource::GetCodeSegmentsL()
+
+ base = KCrashCodeRunAddr + KCrashPid;
+ size= KCrashCodeSize + KCrashPid;
+ line.Format(KSegsLine, base, base + size, &KCrashProcessName8);
+ reference.Append(line);
+
+ base = KCrashCodeRunAddr + KCrashPid + 1;
+ size= KCrashCodeSize + KCrashPid + 1;
+ line.Format(KSegsLine, base, base + size, &KLibName1_8);
+ reference.Append(line);
+
+ base = KCrashCodeRunAddr + KCrashPid + 2;
+ size= KCrashCodeSize + KCrashPid + 2;
+ line.Format(KSegsLine, base, base + size, &KLibName2_8);
+ reference.Append(line);
+
+ reference.Append(_L8("\r\n"));
+
+ /*
+ RBuf8 referencePrint;
+ referencePrint.CreateL(256);
+ referencePrint.Copy( reference );
+ char *tonp = (char*) referencePrint.PtrZ();
+ LOG_MSG2(" KCodeSeg=%s\n", tonp);
+ referencePrint.Close();
+ writer->Print();
+ */
+
+ itest(writer->iData == reference);
+ CleanupStack::PopAndDestroy(2);
+ RDebug::Print(_L("EDumpCodeSegs finished\n"));
+ break;
+ }
+
+ case EDumpStack:
+ {
+ RDebug::Print(_L("EDumpStack starting.... \n"));
+ _LIT( KFalseOpt, "False" );
+
+ CThreadInfo *thread = CThreadInfo::NewL(KCrashTid,
+ KCrashThreadName,
+ KCrashPid,
+ KCrashThreadPriority,
+ KCrashSvcStackPtr,
+ KCrashSvcStackAddr,
+ KCrashSvcStackSize,
+ KCrashUsrStackAddr,
+ KCrashUsrStackSize);
+
+ CleanupStack::PushL(thread);
+
+ RBuf8 stack;
+ stack.CreateL(KCrashUsrStackSize*5);
+ CleanupClosePushL(stack);
+
+ writer->Open(_L("")); //clear writer buffer
+ formatter->SetConfigParameterL( 1, (TInt32)EFalse, KFalseOpt ); //binary dump
+ formatter->DumpStackL(KCrashTid, *thread);
+
+ for( TInt i = 0; i < KCrashUsrStackSize; i++ )
+ {
+ stack.Append((TUint8*)&i, 1);
+ }
+
+ RDebug::Printf("itest(writer->iData == stack);");
+ itest(writer->iData == stack);
+ itest(writer->iData != _L8(""));
+ stack.Zero();
+
+ for(TInt i = 0; i < KCrashUsrStackSize; i+=16)
+ {
+ stack.AppendNumFixedWidth(KCrashUsrStackAddr + i, EHex, 8);
+ stack.Append(_L8(": "));
+ for(TInt j = 0; j < 16; ++j)
+ {
+ stack.AppendNumFixedWidth(i+j, EHex, 2);
+ stack.Append(' ');
+ }
+ for(TInt j = 0; j < 16; ++j)
+ {
+ TInt c = i+j;
+ if(c < 0x20 || c >= 0x7f) //something writable
+ c = 0x2e; //.
+ stack.Append(TChar(c));
+ }
+ stack.AppendFormat(_L8("\r\n"));
+ }
+
+ writer->OpenL(_L("")); //clear writer buffer
+ RDebug::Printf("formatter->SetConfigParameterL( 1, (TInt)ETrue, KNullDesC );");
+ formatter->SetConfigParameterL( 1, (TInt)ETrue, KNullDesC ); //ascii dump
+
+ RDebug::Printf("formatter->DumpStackL(KCrashTid, *thread);");
+ formatter->DumpStackL(KCrashTid, *thread);
+
+ RDebug::Printf("itest(writer->iData == stack);");
+ itest(writer->iData == stack);
+ itest(writer->iData != _L8(""));
+ CleanupStack::PopAndDestroy();
+ CleanupStack::PopAndDestroy(thread);
+ RDebug::Print(_L("EDumpStack finished\n"));
+ break;
+ }
+
+ default:
+ break;
+ }
+ RDebug::Print(_L("<- TestSuite(%d)\n"), aSuite);
+}
+
+void RunTestsL()
+{
+ RDebug::Print(_L("-> RunTestsL()\n"));
+
+ CDexcFormatterTest::TSuite suite[] = {
+ CDexcFormatterTest::ENone,
+ CDexcFormatterTest::EConfigData,
+ CDexcFormatterTest::EFindImplementation,
+ CDexcFormatterTest::EConfigParams,
+ CDexcFormatterTest::EGetDescription,
+ CDexcFormatterTest::EDumpLog,
+ CDexcFormatterTest::EDumpPanicInfo,
+ CDexcFormatterTest::EDumpExcInfo,
+ CDexcFormatterTest::EDumpRegisters,
+ CDexcFormatterTest::EDumpCodeSegs,
+ CDexcFormatterTest::EDumpStack,
+ CDexcFormatterTest::ECrash
+ };
+
+ RTest rtest(KTestTitle);
+ rtest.Title();
+ rtest.Start(_L(""));
+ CDexcFormatterTest::TSuite *test = suite;
+
+ while(*test != CDexcFormatterTest::ECrash)
+ {
+ CDexcFormatterTest *itester = CDexcFormatterTest::NewLC(rtest);
+ itester->TestSuiteL(*test++);
+ CleanupStack::PopAndDestroy();
+ }
+
+ rtest.End();
+ rtest.Close();
+ RDebug::Print(_L("<- RunTestsL()\n"));
+}
+
+TInt E32Main()
+{
+ RDebug::Print(_L("-> E32Main()\n"));
+ __UHEAP_MARK;
+ CTrapCleanup* cleanup = CTrapCleanup::New();
+ __ASSERT_ALWAYS(cleanup, User::Panic(_L("D_EXC_TEST-NO_CLEANUP"), KErrNoMemory));
+
+ TRAPD(err, RunTestsL());
+ __ASSERT_ALWAYS(!err, User::Panic(_L("D_EXC_TEST-RunTestsL trapped with error: "), err));
+
+ delete cleanup;
+ __UHEAP_MARKEND;
+ RDebug::Print(_L("<- E32Main()\n"));
+ return err;
+}
+