// Copyright (c) 2005-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:
// Example CTestStep derived implementation
//
/**
@file SELFusersidestrace.cpp
@internalTechnology
*/
#include "SELFusersidetrace.h"
#include "tcoredumpserverSuiteDefs.h"
#include "tcoredumpserverSuiteServer.h"
#include "optionconfig.h"
#include <coredumpserverapi.h>
#include <e32property.h>
#include <crashdatasave.h>
CSELFUserSideTrace::~CSELFUserSideTrace()
/**
* Destructor
*/
{
}
CSELFUserSideTrace::CSELFUserSideTrace()
/**
* Constructor
*/
{
// **MUST** call SetTestStepName in the constructor as the controlling
// framework uses the test step name immediately following construction to set
// up the step's unique logging ID.
SetTestStepName(KSELFUserSideTrace);
}
TVerdict CSELFUserSideTrace::doTestStepPreambleL()
/**
* @return - TVerdict code
* Override of base class virtual
*/
{
TInt ret = KErrNone;
ret = iCoreDumpSession.Connect();
if(ret != KErrNone)
{
SetTestStepResult( EFail );
INFO_PRINTF2(_L("Error %d from iCoreDumpSession->Connect()/n"), ret);
}
else
{
SetTestStepResult(EPass);
}
ret = iFsSession.Connect();
if(ret != KErrNone)
{
SetTestStepResult( EFail );
INFO_PRINTF2(_L("Error %d from iFsSession->Connect()/n"), ret);
}
else
{
SetTestStepResult(EPass);
}
return TestStepResult();
}
TVerdict CSELFUserSideTrace::doTestStepL()
/**
* @return - TVerdict code
* Override of base class pure virtual
* Our implementation only gets called if the base class doTestStepPreambleL() did
* not leave. That being the case, the current test result value will be EPass.
*/
{
if (TestStepResult()==EPass)
{
TInt ret = KErrNone;
__UHEAP_MARK;
TRAP(ret, ClientAppL());
if(KErrNone != ret)
{
SetTestStepResult(EFail);
INFO_PRINTF2(_L("Error %d from CSELFStep->ClientAppL()"), ret);
}
__UHEAP_MARKEND;
}
return TestStepResult();
}
void CSELFUserSideTrace::ClientAppL()
/**
* @return void
* This calls each stage of the test
*/
{
INFO_PRINTF1(_L("Starting SELF Test Suite") );
HandleCrashL();
//CheckParameters();
}
void CSELFUserSideTrace::HandleCrashL()
/**
* @return void
* Tests handling a crash
*/
{
iTraceFlag = EFalse;
if(TestStepResult()==EPass)
{
TPtrC crashAppParam;
TInt tracePresent;
if(!GetStringFromConfig(ConfigSection(), KTe_CrashAppParam, crashAppParam) ||
!GetIntFromConfig(ConfigSection(), KTrace, tracePresent))
{
INFO_PRINTF1(_L("Failed to get data from ini file"));
SetTestStepResult(EFail);
User::Leave(KErrGeneral);
}
INFO_PRINTF3(_L("The CrashApp Param is %S, Ok so the trace parameter is %d"), &crashAppParam, &tracePresent); // Block end
if(tracePresent == 1)
iTraceFlag = ETrue; //trace is present
else
iTraceFlag = EFalse; //trace not present
INFO_PRINTF2(_L("iTraceFlag %d"), iTraceFlag);
//Start the process that we intend to crash....
RProcess crashProcess;
CleanupClosePushL(crashProcess);
TInt ret = crashProcess.Create( KCrashAppFileName, crashAppParam);
if(ret != KErrNone)
{
INFO_PRINTF2(_L("Error %d from RProcess .Create(z:\\sys\\bin\\crashapp.exe)/n"), ret);
SetTestStepResult(EFail);
User::Leave(ret);
}
INFO_PRINTF1(_L("Started userside crash app"));
//Load SELF and Writer Formatter
DoCmdLoadPluginsL();
//configure the CDS and File Writer
DoCmdConfigurePluginsL();
//configure the SELF formatter accordingly for trace/no trace
ConfigureSELF(iTraceFlag);
// Observe the process and wait for a crash
TRAP(ret, iCoreDumpSession.ObservationRequestL( KCrashAppFileName, KCrashAppFileName, ETrue) );
if(ret != KErrNone)
{
INFO_PRINTF2(_L("Error %d iCoreDumpSession.ObservationRequestL(z:\\sys\\bin\\crashapp.exe)\n"), ret);
SetTestStepResult(EFail);
User::Leave( ret );
}
//start the crash process
crashProcess.Resume();
CleanupStack::PopAndDestroy(&crashProcess); //this is for crashProcess
//Monitor the progress of the crash file being generated...
MonitorProgressL();
User::After(5000000);
iFsSession.SetSessionPath(KDir); //set the default path to e:\\ MMC card
//Use wildcard utilities to search for the SELF FIle Created
TBuf<32> buf;
buf = KDir;
TUidType uid1;
TUidType uid2(uid1.MostDerived());
CFindFileByType* obj = new(ELeave) CFindFileByType(iFsSession);
CleanupStack::PushL(obj);
ret = obj->FindFirst(KCrashWildCard, buf, uid2);
if (ret != KErrNone)
{
ERR_PRINTF2(
_L("GenerateElfFileL Error finding the SELF File %d"),
ret);
SetTestStepResult(EFail);
User::Leave(ret);
}
iSELFFileName = obj->Entry().iName;
CleanupStack::PopAndDestroy(); //CFindFileByType
INFO_PRINTF2(_L("SELF File found: %S"),&iSELFFileName);
//test for a valid Trace section
DoTestTraceSectionSELFFileL(iTraceFlag);
INFO_PRINTF1(_L("SUCCESS Trace Data Presence/Absence verified!"));
}
}
/**
* Validates the presence of the trace data in the SELF file generated
*/
void CSELFUserSideTrace::DoTestTraceSectionSELFFileL(TBool aFlag)
{
TInt err = iSELFFile.Open(iFsSession, iSELFFileName, EFileStream|EFileRead);
if (err != KErrNone)
{
ERR_PRINTF2(
_L("CProcessCrashWrapper::ProcessELFFile Error opening the SELF File %d"),
err);
SetTestStepResult(EFail);
User::Leave(err);
}
//validate the SELF Header Format
ValidateHeaderELFFileL();
//validate the Program Header and store information about the string section Sections
ValidateProgramHeaderELFFileL();
//validate the trace section to be present
ValidateTraceSectionELFFileL(aFlag);
//do the necessary clean up
CleanupMethod(iSELFFileName);
}
/**
* Validates the Header Format Elf32_Ehdr for the SELF file
*/
void CSELFUserSideTrace::ValidateHeaderELFFileL()
{// Elf32_Ehdr
INFO_PRINTF1(_L("CSELFUserSideTrace::ValidateHeaderELFFileL validating Elf32_Ehdr"));
TInt sizeofELFHeader = sizeof(Elf32_Ehdr); //size of Elf32_Ehdr structure
// allocate buffer Elf32_Ehdr
TUint8* SELFHeader = new TUint8[sizeofELFHeader];
TPtr8 elfHeaderPointer(SELFHeader, sizeofELFHeader, sizeofELFHeader);
CleanupStack::PushL(SELFHeader);
//read the SELF file for Elf32_Ehdr
TInt ret = iSELFFile.Read(0, elfHeaderPointer, sizeofELFHeader);
if (ret != KErrNone)
{
ERR_PRINTF2(
_L("CSELFUserSideTrace::ValidateHeaderELFFile Error reading the SELF Header Elf32_Ehdr %d"),
ret);
SetTestStepResult(EFail);
User::Leave(ret);
}
//
Elf32_Ehdr* eh=(Elf32_Ehdr *)SELFHeader;
//VALIDATE THE Elf32_Ehdr
if (eh->e_ident[EI_MAG0] !=0x7f || eh->e_ident[EI_MAG1] != 0x45
|| eh->e_ident[EI_MAG2] !=0x4c || eh->e_ident[EI_MAG3] != 0x46)
{
// EI_MAG0 to EI_MAG3 - A files' first 4 bytes hold a 'magic number', identifying the file as an ELF object file.
ERR_PRINTF1(_L("Error: is not a valid ELF file"));
SetTestStepResult(EFail);
User::Leave(KErrGeneral);
}
if (eh->e_ident[EI_DATA] == 2)
{
// ELF Header size should be 52 bytes or converted into Big-Endian system 13312
if (eh->e_ehsize != 13312)
{
ERR_PRINTF1(_L("Error: ELF Header contains invalid file typ"));
SetTestStepResult(EFail);
User::Leave(KErrGeneral);
}
// e_ident[EI_DATA] specifies the data encoding of the processor-specific data in the object file.
ERR_PRINTF1(_L("Error: Data encoding ELFDATA2MSB (Big-Endian) not supported"));
SetTestStepResult(EFail);
User::Leave(KErrGeneral);
}
if (eh->e_ehsize != 52)
{
// ELF Header size should be 52 bytes
ERR_PRINTF1(_L("Error: ELF Header contains invalid file type"));
SetTestStepResult(EFail);
User::Leave(KErrGeneral);
}
//Number of entries in the program header table
if ((eh->e_phnum) == 0)
{
ERR_PRINTF1(_L("Error: ELF Header contains zero program headers"));
SetTestStepResult(EFail);
User::Leave(KErrGeneral);
}
//store number of program header entries
iPHEntries = eh->e_phnum;
INFO_PRINTF2(_L("Program header entries:%d"), iPHEntries);
//Offset in bytes from the start of the file to the section header table
if ((eh->e_phoff) == 0)
{
ERR_PRINTF1(_L("Error: ELF Header contains zero offset to the section header table"));
SetTestStepResult(EFail);
User::Leave(KErrGeneral);
}
//store program header offset
iPHOffset = eh->e_phoff;
INFO_PRINTF2(_L("Program header offsett:%d"), iPHOffset);
CleanupStack::PopAndDestroy(SELFHeader);
INFO_PRINTF1(_L("Validation of Elf32_Ehdr successful"));
}
/**
* Validates the Program Header Entries Elf32_Phdr of the SELF file
*/
void CSELFUserSideTrace::ValidateProgramHeaderELFFileL()
{//Elf32_Phdr
INFO_PRINTF1(_L("CSELFUserSideTrace::ValidateProgramHeaderELFFileL validating the program header Entries"));
TInt sizeofELFProgramHeader = sizeof(Elf32_Phdr); //size of Elf32_Phdr
TInt totalsizeofELFProgramHeader = iPHEntries * sizeofELFProgramHeader;
//allocate buffer Elf32_Phdr
iSELFPHHeader = new TUint8[totalsizeofELFProgramHeader];
TPtr8 elfPHHeaderPointer(iSELFPHHeader, totalsizeofELFProgramHeader,
totalsizeofELFProgramHeader);
//read the SELF for the whole Program Header Table
TInt ret = iSELFFile.Read(iPHOffset, elfPHHeaderPointer,
totalsizeofELFProgramHeader);
if (ret != KErrNone)
{
ERR_PRINTF2(
_L("CSELFUserSideTrace::ValidateProgramHeaderELFFileL Error reading the SELF Header Elf32_Phdr %d"),
ret);
SetTestStepResult(EFail);
User::Leave(ret);
}
Elf32_Phdr* phdr = (Elf32_Phdr*) iSELFPHHeader;//Elf32_Phdr Program Header
//Prepare for each of the DHDR buffers
TInt sizeofDhdr = sizeof(Sym32_dhdr);
//loop through the program headers to find out more information on the String section
for (TInt i = 0; i < iPHEntries; i++)
{
//allocate DHDR buffers Sym32_dhdr
iDHDRBuffer[i] = new TUint8[sizeofDhdr];
TPtr8 dhdrPointer(iDHDRBuffer[i], sizeofDhdr, sizeofDhdr);
//read SELF file for the Sym32_dhdr
TInt ret = iSELFFile.Read(phdr[i].p_offset, dhdrPointer, sizeofDhdr);
if (ret != KErrNone)
{
ERR_PRINTF2(
_L("CSELFUserSideTrace::ValidateHeaderELFFile Error reading the SELF Header Sym32_dhdr %d"),
ret);
SetTestStepResult(EFail);
User::Leave(ret);
}
idhdr[i] = (Sym32_dhdr*) iDHDRBuffer[i];//array of Sym32_dhdr store it
//find information about the String Info section
if (phdr[i].p_type == PT_NOTE)
{
// Intend to store information about the string section ESYM_NOTE_STR
//the srting section is to be accessed for all sectiosn to be parsed
if (idhdr[i]->d_type == ESYM_NOTE_STR)
{
INFO_PRINTF2(_L("ESYM_NOTE_STR Header offset %d"),
phdr[i].p_offset);
INFO_PRINTF2(
_L("ESYM_NOTE_STR Size of single descriptor element %d "),
idhdr[i]->d_descrsz);
iOffsetStringSection = phdr[i].p_offset + sizeof(Sym32_dhdr);
iSizeofStringSection = idhdr[i]->d_descrsz;
}//if ESYM_NOTE_STR
}//if PT_NOTE
}//for loop
}//end of function
/**
* Validates the Trace Section Sym32_tracedata of the SELF file
*/
void CSELFUserSideTrace::ValidateTraceSectionELFFileL(TBool aTraceCheck)
{
INFO_PRINTF1(_L("CSELFUserSideTrace::ValidateTraceSectionELFFileL validating the Trace Section"));
Elf32_Phdr* phdr = (Elf32_Phdr*) iSELFPHHeader;//Elf32_Phdr Program Header
TBool dataPresent = EFalse;
//loop through the program headers to get information about the Symbian Info section
for (TInt i = 0; i < iPHEntries; i++)
{
if (phdr[i].p_type == PT_NOTE)
{
if (idhdr[i]->d_type == ESYM_NOTE_TRACE) //Trace Info
{
TInt sizeoftraceinfo = sizeof(Sym32_tracedata);
INFO_PRINTF2(_L("ESYM_NOTE_TRACE Size of trace section %d"), sizeoftraceinfo);
INFO_PRINTF2(_L("ESYM_NOTE_TRACE Header offset %d"), phdr[i].p_offset);
INFO_PRINTF2(_L("ESYM_NOTE_TRACE Size of single descriptor element %d"),
idhdr[i]->d_descrsz);
INFO_PRINTF2(_L("ESYM_NOTE_TRACE Number of elements %d"), idhdr[i]->d_elemnum);
if (sizeof(Sym32_tracedata) != (idhdr[i]->d_descrsz))
{
ERR_PRINTF1(_L("CSELFUserSideTrace::ValidateTraceSectionELFFileL sizeof(Sym32_tracedata) %d is different from descriptor size") );
SetTestStepResult(EFail);
User::Leave(KErrGeneral);
}
TInt offsettotraceinfod = phdr[i].p_offset + sizeof(Sym32_dhdr);
//allocate buffer for Sym32_tracedata
TUint8* symbianTraceSection = new TUint8[sizeoftraceinfo];
CleanupStack::PushL(symbianTraceSection);
TPtr8 ptrSymbianTraceSection(symbianTraceSection, sizeoftraceinfo,
sizeoftraceinfo);
TInt ret = iSELFFile.Read(offsettotraceinfod, ptrSymbianTraceSection, sizeoftraceinfo);
if (ret != KErrNone)
{
ERR_PRINTF2(
_L("CSELFUserSideTrace::ValidateTraceSectionELFFileL Error reading the SELF Header Sym32_thrdinfod %d"), ret);
SetTestStepResult(EFail);
User::Leave(ret);
}
Sym32_tracedata *traceInfo =
(Sym32_tracedata*) symbianTraceSection;
INFO_PRINTF2(_L("Size of trace buffer: %d"), traceInfo->tr_size);
INFO_PRINTF2(_L("Offset of trace buffer:%d"), traceInfo->tr_data);
//checking for the presence of trace data
if(traceInfo->tr_size != 0)//trace data present
{
dataPresent = ETrue;
//read the trace buffer
//unsigned char* data = ADDR(unsigned char, aElfHdr, aTraceData->tr_data);
RBuf8 tracebufferString;
tracebufferString.CleanupClosePushL();
//create trace buffer of size traceInfo->tr_size
tracebufferString.CreateL(traceInfo->tr_size);
TInt ret = iSELFFile.Read(traceInfo->tr_data, tracebufferString, traceInfo->tr_size);
if (ret != KErrNone)
{
ERR_PRINTF2(
_L("CSELFUserSideTrace::ValidateTraceSectionELFFileL Error reading the Trace Information %d"),
ret);
SetTestStepResult(EFail);
User::Leave(ret);
}
INFO_PRINTF1(_L("Validate the trace buffer now"));
ValidateTraceBufferL(tracebufferString);
CleanupStack::PopAndDestroy();//tracebufferString
CleanupStack::PopAndDestroy();//symbianTraceSection
break;
}
else //expecting trace data to be present otherwise complain
{
ERR_PRINTF1(
_L("CSELFUserSideTrace::ValidateTraceSectionELFFileL Error found trace size to be zero"));
SetTestStepResult(EFail);
User::Leave(KErrGeneral);
}
}
}
}
if(!aTraceCheck && dataPresent )
{
ERR_PRINTF1(
_L("CSELFUserSideTrace::ValidateTraceSectionELFFileL Error found trace section when there shouldnt be one"));
SetTestStepResult(EFail);
User::Leave(KErrGeneral);
}
if(aTraceCheck && !dataPresent )
{
ERR_PRINTF1(
_L("CSELFUserSideTrace::ValidateTraceSectionELFFileL Error did not find the trace section"));
SetTestStepResult(EFail);
User::Leave(KErrGeneral);
}
}
/**
* Utility Function to do trace data verification
*/
void CSELFUserSideTrace::ValidateTraceBufferL(const TDesC8& aBuffer)
{
INFO_PRINTF2(_L("CSELFUserSideTrace::ValidateTraceBufferL: size: %d"), aBuffer.Length());
const TUint8* tracePtr = aBuffer.Ptr();
TInt traceSize = aBuffer.Length();
/* TUint8 recSize = 0;
TUint8 flags = 0;
TUint8 subCategory = 0;*/
TUint8 category = 0;
TInt cateogryCount = 0;
TInt totalCount = 0;
const TUint8* endPtr = tracePtr+traceSize;
while(tracePtr < endPtr)
{
//count of the total number of records
totalCount++;
category = 0;
/*
* for keeping a record of other fields in the Trace
recSize = flags = subCategory = 0;
recSize = tracePtr[BTrace::ESizeIndex];
flags = tracePtr[BTrace::EFlagsIndex];
subCategory = tracePtr[BTrace::ESubCategoryIndex];*/
/*
* printing the values
* INFO_PRINTF2(_L("recSize: %d"), recSize);
INFO_PRINTF2(_L("flags: %d"), flags);
INFO_PRINTF2(_L("subCategory: %d"), subCategory);
INFO_PRINTF2(_L("category: %d"), category);*/
//read trace header and parse for the Category
category = tracePtr[BTrace::ECategoryIndex];
//check the parameter Category
if(category == KTraceCategory)
{
cateogryCount++;//count the number of times the category 200 has appeared
}
// go to the next trace packet
tracePtr = BTrace::NextRecord((TAny*)tracePtr);
}
if(category == 0)
{// no Category KTraceCategory trace found out
ERR_PRINTF2(
_L("CSELFUserSideTrace::ValidateTraceBufferL Category %d trace data NOT found!"), KTraceCategory);
INFO_PRINTF2(_L("Total Number of trace records found: %d"), totalCount);
SetTestStepResult(EFail);
User::Leave(KErrGeneral);
}
if(category % KTRACENUMBER != 0)
{//checking for KTRACENUMBER number of KTraceCategory
ERR_PRINTF3(
_L("CSELFUserSideTrace::ValidateTraceBufferL %d number of Category type %d trace data NOT found!"), KTRACENUMBER, KTraceCategory);
INFO_PRINTF3(_L("Total number of Category type %d trace data found: %d"), KTraceCategory, cateogryCount);
INFO_PRINTF2(_L("Total Number of trace records found: %d"), totalCount);
SetTestStepResult(EFail);
User::Leave(KErrGeneral);
}
INFO_PRINTF3(_L("Total number of Category type %d trace data found: %d"), KTraceCategory, cateogryCount);
INFO_PRINTF2(_L("Total Number of trace records found: %d"), totalCount);
INFO_PRINTF1(_L("Validation of Trace Buffer Successful!!!"));
}
/**
* @return void
* @param aIndex Internal index to the component that owns the object
* @param aUID UID of the component that owns the object
* @param aSource Type of component that owns the object
* @param aType Type of parameter
* @param aPrompt Prompt to present to user
* @param aNumOptions Number of options that the parameter can be set to. Only applies if type is ETMultiEntryEnum.
* @param aOptions Comma separated list of options. Applies to ETMultiEntryEnum and ETBool
* @param aVal Integer value. Applies to ETInt, ETUInt, ETBool
* @param aStrValue String value. Applies to ETString, ETFileName, ETMultiEntry, ETBool
*/
void CSELFUserSideTrace::DoConfigureL(const TUint32& aIndex,
const TUint32& aUID,
const COptionConfig::TParameterSource& aSource,
const COptionConfig::TOptionType& aType,
const TDesC& aPrompt,
const TUint32& aNumOptions,
const TDesC& aOptions,
const TInt32& aVal,
const TDesC& aStrValue,
const TUint aInstance)
{
COptionConfig * config;
config = COptionConfig::NewL( aIndex,
aUID,
aSource,
aType,
aPrompt,
aNumOptions,
aOptions,
aVal,
aStrValue);
CleanupStack::PushL(config);
config->Instance(aInstance);
//Configure now...
TRAPD(ret, iCoreDumpSession.SetConfigParameterL(*config) );
if(ret != KErrNone)
{
INFO_PRINTF2(_L("Error %d changing param/n"), ret );
SetTestStepResult(EFail);
User::Leave(ret);
}
CleanupStack::PopAndDestroy(config);
}
/**
* @return void
* This method monitors the RProperty for the crash progress. There are several states of this but we are
* only interested in the start and finish of these properties
*/
void CSELFUserSideTrace::MonitorProgressL()
{
RProperty crashProgress;
User::LeaveIfError(crashProgress.Attach(KCoreDumpServUid, ECrashProgress));
TBuf<50> crashProg;
TRequestStatus status;
crashProgress.Subscribe(status);
User::WaitForRequest(status);
//Subscribe for next one again...
crashProgress.Subscribe(status);
//First one should be the start string = "-"
User::LeaveIfError(crashProgress.Get(crashProg ));
if(crashProg != KStartOfSELFProc)
{
INFO_PRINTF1(_L("SELF formatter has not started processing the data"));
}
INFO_PRINTF1(_L("SELF formatters have started processing the data"));
INFO_PRINTF1(_L("Waiting to be notified of the timeout of the processing. A timeout here is a fail"));
//Now we wait until its finished
do
{
User::WaitForRequest(status);
crashProgress.Subscribe(status);
User::LeaveIfError(crashProgress.Get(crashProg ));
}
while(crashProg != KEndOfProcessing);
INFO_PRINTF1(_L("SELF formatter has finished processing the data"));
}
/**
* Loads the SELF Formatter and the File Writer plugin
*/
void CSELFUserSideTrace::DoCmdLoadPluginsL()
{
INFO_PRINTF1(_L("\nCProcessCrashWrapperloading SELF Formatter and File Writer!!!"));
TPluginRequest loadSELFReq;
loadSELFReq.iPluginType = TPluginRequest::EFormatter;
loadSELFReq.iLoad = ETrue;
loadSELFReq.iUid = KUidSELFFormatterV2;
TPluginRequest loadWriterReq;
loadWriterReq.iPluginType = TPluginRequest::EWriter;
loadWriterReq.iLoad = ETrue;
loadWriterReq.iUid = WRITER_UID;
// loading Symbian ELF formatter
TRAPD(ret, iCoreDumpSession.PluginRequestL(loadSELFReq));
if (ret != KErrNone)
{
ERR_PRINTF2(
_L("CSELFUserSideTrace::DoCmdLoadPluginsL: Could not load SELF plugin!, err:%d\n"),
ret);
SetTestStepResult(EFail);
User::Leave(ret);
}
// loading Symbian File writer
TRAP(ret, iCoreDumpSession.PluginRequestL(loadWriterReq));
if (ret != KErrNone)
{
ERR_PRINTF2(
_L("CSELFUserSideTrace::DoCmdLoadPluginsL: Could not load writer plugin!, err:%d\n"),
ret);
SetTestStepResult(EFail);
User::Leave(ret);
}
//intend to check for the loaded SELF formatter and File Writer
RPluginList pluginLists;
CleanupClosePushL(pluginLists);
TRAP(ret, iCoreDumpSession.GetPluginListL(pluginLists));
if (ret != KErrNone)
{
ERR_PRINTF2(
_L("CSELFUserSideTrace::DoCmdLoadPluginsL: Could not get plugin list!, err:%d\n"),
ret);
SetTestStepResult(EFail);
User::Leave(ret);
}
//Now we look through the list, until we find our plugin, its a fail
for (TInt i = 0; i < pluginLists.Count(); i++)
{
if (pluginLists[i].iUid == KUidSELFFormatterV2 && !(pluginLists[i].iLoaded))
{
ERR_PRINTF1(
_L("SELF Plugin Not loaded !\n"));
SetTestStepResult(EFail);
User::Leave(KErrNotFound);
}
}
for (TInt i = 0; i < pluginLists.Count(); i++)
{
if (pluginLists[i].iUid == WRITER_UID && !(pluginLists[i].iLoaded))
{
ERR_PRINTF1(
_L("Writer Plugin Not loaded !\n"));
SetTestStepResult(EFail);
User::Leave(KErrNotFound);
}
}
INFO_PRINTF1(_L("SELF Formatter and File Writer loaded successfully"));
CleanupStack::PopAndDestroy();//pluginLists
}
/**
* Configuring the Core Dump Server and the File Writer
*/
void CSELFUserSideTrace::DoCmdConfigurePluginsL()
{
INFO_PRINTF1(_L("CSELFUserSideTrace DoCmdConfigurePlugins configuring the Core dump server and File Writer plugin"));
//Configuring the Core Dump Server
TRAPD(ret, DoConfigureL(2, CDS_UID.iUid, COptionConfig::ECoreDumpServer,
COptionConfig::ETUInt, KPostCrashEventActionPrompt, 1, KNullDesC,
4, KNullDesC, 0));
if (ret != KErrNone)
{
ERR_PRINTF2(
_L("CSELFUserSideTrace::DoConfigureL for CDS Error %d changing param"),
ret);
SetTestStepResult(EFail);
User::Leave(ret);
}
//Configuring the file writer plugin to have a specified crash file name
TRAPD(err, DoConfigureL((TInt)(CCrashDataSave::ECoreFilePath),
WRITER_UID.iUid, COptionConfig::EWriterPlugin,
COptionConfig::ETFileName, KFilePathPrompt, 1, KNullDesC, 0,
KCrashFileName, 0));
if (err != KErrNone)
{
ERR_PRINTF2(_L("CSELFUserSideTrace::DoConfigureL for File Writer Error %d changing param"),
err);
SetTestStepResult(EFail);
User::Leave(err);
}
}
/**
* Utility Function to do SELF Configurations
*/
void CSELFUserSideTrace::ConfigureSELF(TBool aTracePresent)
{
INFO_PRINTF2(_L("CProcessCrashWrapper::ConfigureSELF confiugring SELF for Trace presence %d"), aTracePresent);
if(aTracePresent)
{//configure to have trace segments upto have 10KB data
DoConfigureL(8, KUidSELFFormatterV2.iUid, COptionConfig::EFormatterPlugin,
COptionConfig::ETInt, KCreateTraceData,
1, KNullDesC, 10, KNullDesC, 0);
}
else
{//configure NOT to have trace segments
DoConfigureL(8, KUidSELFFormatterV2.iUid, COptionConfig::EFormatterPlugin,
COptionConfig::ETInt, KCreateTraceData,
1, KNullDesC, 0, KNullDesC, 0);
}
}
/**
* Utility Function to do cleanup activities
*/
void CSELFUserSideTrace::CleanupMethod(const TDesC& aDes)
{
RBuf fileDelete;
fileDelete.CreateL(aDes);
fileDelete.SetMax();
fileDelete.CleanupClosePushL();
INFO_PRINTF2(_L("Entered deletion routine for file %S"), &fileDelete);
//close the file
iSELFFile.Close();
TInt ret = iFsSession.Delete(fileDelete);
if (ret != KErrNone)
{
ERR_PRINTF2(
_L("CSELFUserSideTrace::SELF File delete returned error %d"),
ret);
SetTestStepResult(EFail);
User::Leave(ret);
}
CleanupStack::PopAndDestroy();//fileDelete
//delete the buffers
if (iSELFPHHeader)
{
delete [] iSELFPHHeader;
iSELFPHHeader = NULL;
}
for (TInt i = 0; i < iPHEntries; i++)
{
delete [] iDHDRBuffer[i];
}
INFO_PRINTF1(_L("Cleanup Done"));
}
/**
* @return - TVerdict code
* Override of base class virtual
*/
TVerdict CSELFUserSideTrace::doTestStepPostambleL()
{
iCoreDumpSession.Disconnect();
User::After(7000000); //ensure we give enough time for session to close
iFsSession.Close();
return EPass;
}