dbgsrv/coredumpserver/test/automatictests/tcds_kernel/src/cds/t_process_crash.cpp
changeset 0 c6b0df440bee
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dbgsrv/coredumpserver/test/automatictests/tcds_kernel/src/cds/t_process_crash.cpp	Tue Mar 02 10:33:16 2010 +0530
@@ -0,0 +1,2792 @@
+// Copyright (c) 2008-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:
+//
+
+/**
+ @file t_process_crash.cpp
+ @internalTechnology
+*/
+
+#include <bautils.h>
+
+#include "t_process_crash.h"
+
+using namespace Debug;
+
+//Names of functions to be tested - referenced from script file
+_LIT(KProcessCrashNewL, "NewL");
+_LIT(KReadCrashInfo, "ReadCrashInfo");
+_LIT(KDeleteAllCrash, "DeleteAllCrashes");
+_LIT(KLoadPlugins, "LoadPlugins");
+_LIT(KUnLoadPlugins, "UnLoadPlugins");
+_LIT(KConfigurePlugins, "ConfigurePlugins");
+_LIT(KConfigureSCMZeroPriority, "ConfigureSCMZeroPriority");
+_LIT(KCheckMultipleCrashes, "CheckMultipleCrashes");
+_LIT(KValidateSingleELFFile, "ValidateSingleELFFile");
+_LIT(KValidateMultipleSELFFile, "ValidateMultipleSELFFile");
+_LIT(KValidateSelfCPUId, "ValidateSelfCPUID");
+_LIT(KValidateHeapSELFFile, "ValidateHeapSELFFile");
+_LIT(KValidateTraceSELFFile, "ValidateTraceSELFFile");
+_LIT(KPerformanceMeasureSELFFile, "PerformanceMeasureSELFFile");
+_LIT(KValidateCorruptCrash, "ValidateCorruptCrash");
+_LIT(KValidateAsyncProcessCrashLog, "ValidateAsyncProcessCrashLog");
+_LIT(KValidateAsyncProcessAndLiveCrash, "ValidateAsyncProcessAndLiveCrash");
+
+//list of exception to check for
+enum TCheckExecption
+	{
+	ETestDataAbort = 24
+	};
+
+//Max String Read out from the SELF file String scetion
+const TInt KMaxStringLength = 200;
+
+//Minimum amount of crashes we need for multi crash tests
+const TInt KMinimumAcceptableCrashNumber = 2;
+
+// crash type
+enum TCrashType
+	{ECrashException, ECrashKill};
+
+/**
+ * Constructor for test wrapper
+ */
+CProcessCrashWrapper::CProcessCrashWrapper()
+	{
+	}
+
+/**
+ * Destructor
+ */
+CProcessCrashWrapper::~CProcessCrashWrapper()
+	{
+	iCrashList.ResetAndDestroy();
+	iCoreDumpSession.Disconnect();
+	iFsSession.Close();
+	iThreadCrashed.Close();
+	}
+
+/**
+ * Two phase constructor for CProcessCrashWrapper
+ * @return CProcessCrashWrapper object
+ * @leave
+ */
+CProcessCrashWrapper* CProcessCrashWrapper::NewL()
+	{
+	CProcessCrashWrapper* ret = new (ELeave) CProcessCrashWrapper();
+	CleanupStack::PushL(ret);
+	ret->ConstructL();
+	CleanupStack::Pop(ret);
+	return ret;
+	}
+
+/**
+ * Safe construction
+ * @leave
+ */
+void CProcessCrashWrapper::ConstructL()
+	{
+	User::LeaveIfError(iFsSession.Connect());
+	iFsSession.SetSessionPath(KDir);
+	}
+
+/**
+ * Assign the object
+ *
+ * @param aObject TAny* to the object to test
+ * @leave
+ */
+void CProcessCrashWrapper::SetObjectL(TAny* aObject)
+	{}
+
+/**
+ * Runs a test preamble
+ */
+void CProcessCrashWrapper::PrepareTestL()
+	{
+	SetBlockResult(EPass);
+
+	//Delete any crash files from previous tests
+	TBuf<KMaxFileName> name;
+	name.Append(KDir);
+	name.Append(KCrashWildCard);
+	BaflUtils::DeleteFile(iFsSession, name);
+	}
+
+/**
+ * Handle a command invoked from the script
+ *
+ * @param aCommand Is the name of the command
+ *   for a TBuf
+ * @param aSection Is the .ini file section where parameters to the command
+ *   are located
+ * @param aAsyncErrorIndex Is used by the TEF Block framework to handle
+ *   asynchronous commands.
+ */
+
+TBool CProcessCrashWrapper::DoCommandL(const TTEFFunction& aCommand,
+		const TTEFSectionName& aSection, const TInt aAsyncErrorIndex)
+	{
+
+	//__UHEAP_MARK;
+
+	PrepareTestL();
+
+	if (KProcessCrashNewL() == aCommand)
+		{
+		DoCmdNewL();
+		}
+	else if (KReadCrashInfo() == aCommand)
+		{
+		DoCmdReadCrashInfoL();
+		}
+	else if (KCheckMultipleCrashes() == aCommand)
+		{
+		DoCmdCheckMultipleCrashesL();
+		}
+	else if (KDeleteAllCrash() == aCommand)
+		{
+		DoCmdDeleteAllCrashL();
+		}
+	else if (KLoadPlugins() == aCommand)
+		{
+		DoCmdLoadPluginsL();
+		}
+	else if (KUnLoadPlugins() == aCommand)
+		{
+		DoCmdUnLoadPluginsL();
+		}
+	else if (KConfigurePlugins() == aCommand)
+		{
+		DoCmdConfigurePluginsL(KCrashFileName);
+		}
+	else if (KConfigureSCMZeroPriority() == aCommand)
+		{
+		DoCmdConfigureSCMZeroPriorityL();
+		}
+	else if (KValidateSingleELFFile() == aCommand)
+		{
+		DoCmdValidateSingleELFFileL();
+		}
+	else if (KValidateMultipleSELFFile() == aCommand)
+		{
+		DoCmdValidateMultipleELFFileL();
+		}
+	else if (KValidateSelfCPUId() == aCommand)
+		{
+		DoCmdValidateCpuIDL();
+		}
+	else if (KValidateHeapSELFFile() == aCommand)
+		{
+		DoCmdValidateHeapSELFFileL();
+		}
+	else if (KValidateTraceSELFFile() == aCommand)
+		{
+		DoCmdValidateTraceSELFFileL();
+		}
+	else if (KPerformanceMeasureSELFFile() == aCommand)
+		{
+		DoCmdPerformanceMeasureSELFFileL();
+		}
+	else if (KValidateCorruptCrash() == aCommand)
+		{
+		DoCmdValidateCorruptCrashL();
+		}
+	else if (KValidateAsyncProcessCrashLog() == aCommand)
+		{
+		DoCmdValidateAsyncProcessCrashLogL();
+		}
+	else if (KValidateAsyncProcessAndLiveCrash() == aCommand)
+		{
+		DoCmdValidateAsyncProcessAndLiveCrashCrashLogL(aSection);
+		}
+	else
+		{
+		INFO_PRINTF1(_L("NOT ** Inside Command"));
+		return EFalse;
+		}
+
+	//__UHEAP_MARKEND;
+
+	return ETrue;
+	}
+
+/**
+ * The initailization function wherein the sessions to Core Dump Server is established
+ */
+void CProcessCrashWrapper::DoCmdNewL()
+	{
+	INFO_PRINTF1(_L("CProcessCrashWrapper::DoCmdNewL"));
+
+	TInt err = iCoreDumpSession.Connect();
+	if (err != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::DoCmdNewL: iCoreDumpSession->Connect() failed!, err:%d\n"),
+				err);
+		SetBlockResult(EFail);
+		User::Leave(err);
+		}
+
+	}
+
+/**
+ * Reads all the crash information present in the flash
+ */
+void CProcessCrashWrapper::DoCmdReadCrashInfoL()
+	{
+	INFO_PRINTF1(_L("CProcessCrashWrapper:: DoCmdReadCrashInfoL\n"));
+
+	//Do list all the Crash Information here
+	TRAPD(err, iCoreDumpSession.ListCrashesInFlashL(iCrashList));
+	if (err != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::DoCmdReadCrashInfoL: Could not read Crashes in the Flash! err:%d\n"),
+				err);
+		SetBlockResult(EFail);
+		User::Leave(err);
+		}
+
+	INFO_PRINTF2(_L("Number of crash information present: %d"),
+			iCrashList.Count());
+
+	for (TInt i = 0; i < iCrashList.Count(); i++)
+		{
+		INFO_PRINTF3(_L("Crash no: %d, CrashId %d"), i, iCrashList[i]->iCrashId);
+		INFO_PRINTF3(_L("Crash no: %d, Type %ld"), i, iCrashList[i]->iType);
+		INFO_PRINTF3(_L("Crash no: %d, Time %ld"), i, iCrashList[i]->iTime);
+		INFO_PRINTF3(_L("Crash no: %d, Thread ID %ld"), i, iCrashList[i]->iTid);
+		}
+	}
+
+/**
+ * Test case specific to DT-coredump-monitor-010
+ * Reads all the crash information present
+ * Checks for exactly four crashed present
+ * Process the crash without any plugins
+ */
+void CProcessCrashWrapper::DoCmdCheckMultipleCrashesL()
+	{
+	INFO_PRINTF1(_L("CProcessCrashWrapper:: DoCmdCheckMultipleCrashesL"));
+
+	//reads all the crash information present in the flash
+	DoCmdReadCrashInfoL();
+
+	//check for exactly four crashes present in the flash
+	if (iCrashList.Count() < KMinimumAcceptableCrashNumber)
+		{
+		ERR_PRINTF1(_L("CProcessCrashWrapper::DoCmdCheckMultipleCrashesL Could not find multiple crashes"));
+		SetBlockResult(EFail);
+		User::Leave(KErrGeneral);
+		}
+
+	INFO_PRINTF1(_L("Verified that there are multiple crashes present"));
+	INFO_PRINTF1(_L("CProcessCrashWrapper:: Procesing the crashes!!!"));
+
+	for (TInt i = 0; i < iCrashList.Count(); i++)
+		{
+		//process teh crash log for each of the crashes present
+		TRAPD(error, iCoreDumpSession.ProcessCrashLogL(iCrashList[i]->iCrashId));
+		if (error != KErrNone)
+			{
+			ERR_PRINTF2(
+					_L("CProcessCrashWrapper::ProcessCrashLogL: Could not process crash! err:%d\n"),
+					error);
+			SetBlockResult(EFail);
+			User::Leave(error);
+			}
+		}
+	}
+
+/**
+ * Deletes all crashes in the flash
+ * Always called after Reading all crash information present
+ * by CProcessCrashWrapper::DoCmdReadCrashInfoL()
+ */
+void CProcessCrashWrapper::DoCmdDeleteAllCrashL()
+	{
+	INFO_PRINTF1(_L("CProcessCrashWrapper:: DoCmdDeleteAllCrashL deleting all the crashes"));
+
+	TRAPD(err, iCoreDumpSession.DeleteCrashPartitionL());
+	if (err != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::DoCmdDeleteAllCrashL: Could not delete crash! err:%d\n"),
+				err);
+		SetBlockResult(EFail);
+		User::Leave(err);
+		}
+
+	INFO_PRINTF1(_L("Successfully deleted all the crashes"));
+	}
+
+/**
+ * Loads the SELF Formatter and the File Writer plugin
+ */
+void CProcessCrashWrapper::DoCmdLoadPluginsL()
+	{
+	INFO_PRINTF1(_L("CProcessCrashWrapperloading SELF Formatter and File Writer!!!"));
+
+	TPluginRequest loadSELFReq;
+	loadSELFReq.iPluginType = TPluginRequest::EFormatter;
+	loadSELFReq.iLoad = ETrue;
+	loadSELFReq.iUid = KUidELFFormatterV2;
+
+	TPluginRequest loadWriterReq;
+	loadWriterReq.iPluginType = TPluginRequest::EWriter;
+	loadWriterReq.iLoad = ETrue;
+	loadWriterReq.iUid = KUidFileWriter;
+
+	// loading Symbian ELF formatter
+	TRAPD(ret, iCoreDumpSession.PluginRequestL(loadSELFReq));
+	if (ret != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::DoCmdLoadPluginsL: Could not load SELF plugin!, err:%d\n"),
+				ret);
+		SetBlockResult(EFail);
+		User::Leave(ret);
+		}
+
+	// loading Symbian File writer
+	TRAP(ret, iCoreDumpSession.PluginRequestL(loadWriterReq));
+	if (ret != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::DoCmdLoadPluginsL: Could not load writer plugin!, err:%d\n"),
+				ret);
+		SetBlockResult(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("CProcessCrashWrapper::DoCmdLoadPluginsL: Could not get plugin list!, err:%d\n"),
+				ret);
+		SetBlockResult(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 == KUidELFFormatterV2 && !(pluginLists[i].iLoaded))
+			{
+			ERR_PRINTF1(
+					_L("SELF Plugin Not loaded !\n"));
+			SetBlockResult(EFail);
+			User::Leave(KErrNotFound);
+			}
+		}
+
+	for (TInt i = 0; i < pluginLists.Count(); i++)
+		{
+		if (pluginLists[i].iUid == KUidFileWriter && !(pluginLists[i].iLoaded))
+			{
+			ERR_PRINTF1(
+								_L("Writer Plugin Not loaded !\n"));
+			SetBlockResult(EFail);
+			User::Leave(KErrNotFound);
+			}
+		}
+
+	INFO_PRINTF1(_L("SELF Formatter and File Writer loaded successfully \n"));
+	CleanupStack::PopAndDestroy();//pluginLists
+	}
+
+/**
+ * UnLoads the SELF Formatter and the File Writer plugin
+ */
+void CProcessCrashWrapper::DoCmdUnLoadPluginsL()
+	{
+	INFO_PRINTF1(_L("CProcessCrashWrapper DoCmdUnLoadPluginsL unloading SELF Formatter and File Writer"));
+
+	TPluginRequest unloadSELFReq;
+	unloadSELFReq.iPluginType = TPluginRequest::EFormatter;
+	unloadSELFReq.iLoad = EFalse;
+	unloadSELFReq.iUid = KUidELFFormatterV2;
+
+	TPluginRequest unloadWriterReq;
+	unloadWriterReq.iPluginType = TPluginRequest::EWriter;
+	unloadWriterReq.iLoad = EFalse;
+	unloadWriterReq.iUid = KUidFileWriter;
+
+	TRAPD(ret, iCoreDumpSession.PluginRequestL(unloadSELFReq));
+	if (ret != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::DoCmdLoadPluginsL: Could not unload SELF plugin!, err:%d\n"),
+				ret);
+		SetBlockResult(EFail);
+		User::Leave(ret);
+		}
+
+	TRAPD(err, iCoreDumpSession.PluginRequestL(unloadWriterReq));
+	if (err != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::DoCmdLoadPluginsL: Could not unload writer plugin!, err:%d\n"),
+				err);
+		SetBlockResult(EFail);
+		User::Leave(err);
+		}
+
+	INFO_PRINTF1(_L("Successful unloading SELF Formatter and File Writer"));
+	}
+
+/**
+ * Configuring the SCM to have minimal information the flash
+ * Done inorder to incorporate more crashes in the flash
+ */
+void CProcessCrashWrapper::DoCmdConfigureSCMZeroPriorityL()
+	{
+	INFO_PRINTF1(_L("CProcessCrashWrapper::DoCmdConfigureSCMZeroPriority setting all SCM configurations to zero priority"));
+
+	TInt noConfigParams = 0;
+	// this will ultimateley read the config
+    TRAPD(err, noConfigParams = iCoreDumpSession.GetNumberConfigParametersL());
+    if(err != KErrNone)
+        {
+        ERR_PRINTF1(_L("COULD not read number of config params"));
+		User::Leave(KErrGeneral);
+		SetBlockResult(EFail);
+        }
+    else
+    	{
+
+    	INFO_PRINTF2(_L("CProcessCrashWrapper::DoCmdConfigureSCMZeroPriority found %d config params"), noConfigParams);
+		for (TInt i = 0; i < noConfigParams; i++)
+			{
+			TInt priority = 1;//setting priority to one for all
+
+			COptionConfig* conf = iCoreDumpSession.GetConfigParameterL(i);
+			CleanupStack::PushL(conf);
+
+			if (conf->Source()== COptionConfig::ESCMConfig)
+				{
+				TConfigItem::TSCMDataType dataType = (TConfigItem::TSCMDataType) conf->Instance();
+
+//				INFO_PRINTF3(_L("CProcessCrashWrapper::DoCmdConfigureSCMZeroPriority found config data type %d priority %d")
+//						, dataType, conf->Value());
+
+				if(dataType == TConfigItem::EKernelHeap || dataType == TConfigItem::EThreadsUsrStack || dataType == TConfigItem::EThreadsSvrStack )
+					{
+					priority = 0;
+					INFO_PRINTF3(_L("CProcessCrashWrapper::DoCmdConfigureSCMZeroPriority modifying data type %d with priority %d")
+							, dataType, priority);
+					}
+
+				// set the value
+				conf->Value(priority);
+				TRAP(err, iCoreDumpSession.SetConfigParameterL(*conf));
+				if (err != KErrNone)
+					{
+					ERR_PRINTF3(
+							_L("CProcessCrashWrapper::DoCmdConfigureSCMZeroPriority for SCM Configurations failed error code is %d changing param for run no: %d"),
+							err, i);
+					SetBlockResult(EFail);
+					User::Leave(err);
+					}
+				}
+
+			CleanupStack::PopAndDestroy(conf);
+			}
+
+    	}
+
+	INFO_PRINTF1(_L("SCM Configuration successful"));
+	}
+
+/**
+ * Tests that the SELF plugin can handle invalid configuration
+ */
+void CProcessCrashWrapper::DoCmdConfigureSELFPluginWithInvalidnessL()
+	{
+	INFO_PRINTF1(_L("CProcessCrashWrapper::DoCmdConfigureSELFPluginWithInvalidnessL configuring the Core dump server and File Writer plugin"));
+
+	TUint numConfigParams = 0;
+	TRAPD(err, numConfigParams = iCoreDumpSession.GetNumberConfigParametersL());
+	if(KErrNone != err)
+		{
+		ERR_PRINTF2(_L("Unable to get the number of config parameters. Returned %d"), err);
+		SetBlockResult(EFail);
+		return;
+		}
+
+	INFO_PRINTF2(_L("Found %d params"), numConfigParams);
+
+	for (TInt i = 0; i < numConfigParams; i++)
+		{
+		COptionConfig* conf;
+		conf = iCoreDumpSession.GetConfigParameterL(i);
+		CleanupStack::PushL(conf);
+
+		if(conf->Source() == COptionConfig::EFormatterPlugin)
+			{
+			//Try to configure with the old invalidity
+			switch(conf->Type())
+				{
+				}
+			}
+
+		CleanupStack::PopAndDestroy(conf);
+
+		}
+
+	}
+
+/**
+ * Configuring the Core Dump Server and the File Writer
+ * @param aSELFFileName is the SELF File Name configuring the File Writer plugin
+ */
+void CProcessCrashWrapper::DoCmdConfigurePluginsL(const TDesC& aSELFFileName)
+	{
+	INFO_PRINTF1(_L("CProcessCrashWrapper DoCmdConfigurePlugins configuring the Core dump server and File Writer plugin"));
+
+	//Configuring the Core Dump Server
+	TRAPD(ret, DoConfigureL(2, KCDSUid.iUid, COptionConfig::ECoreDumpServer,
+			COptionConfig::ETUInt, KPostCrashEventActionPrompt, 1, KNullDesC,
+			4, KNullDesC, 0));
+	if (ret != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::DoConfigureL for CDS Error %d changing param"),
+				ret);
+		SetBlockResult(EFail);
+		User::Leave(ret);
+		}
+
+	//Configuring the file writer plugin to have a specified crash file name
+	TRAPD(err, DoConfigureL((TInt)(CCrashDataSave::ECoreFilePath),
+			KUidFileWriter.iUid, COptionConfig::EWriterPlugin,
+			COptionConfig::ETFileName, KFilePathPrompt, 1, KNullDesC, 0,
+			aSELFFileName, 0));
+
+	if (err != KErrNone)
+		{
+		ERR_PRINTF2(_L("CProcessCrashWrapper::DoConfigureL for File Writer Error %d changing param"),
+				err);
+		SetBlockResult(EFail);
+		User::Leave(err);
+		}
+
+	}
+/**
+ * @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 CProcessCrashWrapper::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...
+	iCoreDumpSession.SetConfigParameterL(*config);
+
+	CleanupStack::PopAndDestroy(config);
+	}
+
+void CProcessCrashWrapper::DoCmdValidateCpuIDL()
+	{
+	LOG_MSG(_L("CProcessCrashWrapper::DoCmdValidateCpuIDL()"));
+
+	//expects one crash information to be present in the flash otherwise complain
+	if (iCrashList.Count() != 1)
+		{
+		ERR_PRINTF1(_L("More than one crash information present"));
+		SetBlockResult(EFail);
+		User::Leave(KErrGeneral);
+		}
+
+	GenerateElfFileL(iCrashList[0]->iCrashId);
+
+	//open the SELF File for processing
+	TInt err = iSELFFile.Open(iFsSession, iSELFFileName, EFileStream|EFileRead);
+	if (err != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::ProcessELFFile Error opening the SELF File %d"),
+				err);
+		SetBlockResult(EFail);
+		User::Leave(err);
+		}
+
+	//Parse start of ELF file
+	ValidateHeaderELFFileL();
+	ValidateProgramHeaderELFFileL();
+	ValidateSymInfoSectionELFFileL();
+
+	//Validate the CPU Id
+	RDebug::Printf("Looking at CPU ID");
+	ValidateThreadInfoSectionELFFileL(ETrue, KThreadKernelCrash, ETrue);
+
+	TBuf<KMaxFileName> fileName;
+	iSELFFile.Name(fileName);
+
+	INFO_PRINTF2(_L("Finished with %S So im sharking it"), &fileName);
+	iSELFFile.Close();
+	iFsSession.Delete(fileName);
+	}
+/**
+ * Generate the SELF File and search for the generated file
+ * aCrashId  = crash id
+ * aTiming (default value is False) determines the timing measurement
+ */
+void CProcessCrashWrapper::GenerateElfFileL(TUint aCrashId, TBool aTiming)
+	{
+	if(aTiming) HelpStartTestTimer();
+
+	//process the crash with configured SELF formatter and file writer
+	TRAPD(ret, iCoreDumpSession.ProcessCrashLogL(aCrashId));
+	if (ret != KErrNone)
+		{
+		ERR_PRINTF2(_L("CProcessCrashWrapper::ProcessCrashLogL for CDS Error %d"),
+				ret);
+		SetBlockResult(EFail);
+		User::Leave(ret);
+		}
+
+	MonitorProgressL();
+
+	if(aTiming) HelpStopTestTimer();
+
+	INFO_PRINTF1(_L("ProcessCrashLogL Successful"));
+
+	//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);
+		SetBlockResult(EFail);
+		User::Leave(ret);
+		}
+
+	iSELFFileName = obj->Entry().iName;
+
+	CleanupStack::PopAndDestroy(); //CFindFileByType
+	INFO_PRINTF2(_L("The SELF File Found is E:\\%S "), &iSELFFileName);
+	}
+
+/**
+ * Generate the SELF File and Validate the Symbian INFO and executable sections
+ */
+void CProcessCrashWrapper::DoCmdValidateSingleELFFileL()
+	{
+	INFO_PRINTF1(_L("CProcessCrashWrapper DoCmdSingleValidateELFFileL"));
+
+	//expects one crash information to be present in the flash otherwise complain
+	if (iCrashList.Count() != 1)
+		{
+		ERR_PRINTF1(_L("More than one crash information present"));
+		SetBlockResult(EFail);
+		User::Leave(KErrGeneral);
+		}
+
+	//generate the SELF File by calling ProcessCrashLogL
+	GenerateElfFileL(iCrashList[0]->iCrashId);
+
+	//open the SELF File for processing
+	TInt err = iSELFFile.Open(iFsSession, iSELFFileName, EFileStream|EFileRead);
+	if (err != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::ProcessELFFile Error opening the SELF File %d"),
+				err);
+		SetBlockResult(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 Symbian Info section
+	ValidateSymInfoSectionELFFileL();
+
+	//validate Thread name that crashed
+	ValidateThreadInfoSectionELFFileL(EFalse, KThreadKernelCrash, ETrue);
+
+	//do the necessary clean up
+	CleanupMethod(iSELFFileName);
+	}
+
+/**
+ * Process the crash log using the asynchrnous API ProcessCrashLog
+ */
+void CProcessCrashWrapper::DoCmdValidateAsyncProcessCrashLogL()
+	{
+
+	INFO_PRINTF1(_L("CProcessCrashWrapper DoCmdValidateAsyncProcessCrashLogL"));
+
+	//expects one crash information to be present in the flash otherwise complain
+	if (iCrashList.Count() != 1)
+		{
+		ERR_PRINTF1(_L("More than one crash information present"));
+		SetBlockResult(EFail);
+		User::Leave(KErrGeneral);
+		}
+
+	//create the Active Object to process the crash log asynchrnously
+	CAsyncProcessCrash* asyncProcessCrash = CAsyncProcessCrash::NewL(this);
+	CleanupStack::PushL(asyncProcessCrash);
+
+	asyncProcessCrash->IssueProcessCrashRequest(iCrashList[0]->iCrashId);
+
+	CActiveScheduler::Start();// Doesn’t return until it is explicitly
+
+	RDebug::Printf("After CActiveScheduler::Start");
+	CleanupStack::PopAndDestroy();
+	INFO_PRINTF1(_L("DoCmdValidateAsyncProcessCrashLogL Successful with processing the crash log asynchrnouly"));
+
+	}
+
+/**
+ * Process the crash log using the asynchrnous API ProcessCrashLog whilst a user side crash
+ */
+void CProcessCrashWrapper::DoCmdValidateAsyncProcessAndLiveCrashCrashLogL(const TDesC& aSection)
+	{
+
+	INFO_PRINTF1(_L("CProcessCrashWrapper DoCmdValidateAsyncProcessAndLiveCrashCrashLogL"));
+
+	//expects one crash information to be present in the flash otherwise complain
+	if (iCrashList.Count() != 1)
+		{
+		ERR_PRINTF1(_L("More than one crash information present"));
+		SetBlockResult(EFail);
+		User::Leave(KErrGeneral);
+		}
+
+	//generate a live crash using the test application crashapp.exe
+	GenerateLiveCrashL(aSection);
+
+	//start processing the crash log in the flash
+	TRequestStatus asyncSystemCrash;
+    iCoreDumpSession.ProcessCrashLog( (iCrashList[0]->iCrashId), asyncSystemCrash);
+	User::WaitForRequest(asyncSystemCrash);
+
+	//This user after is to ensure the live crash has completed before analysis
+    User::After(3000000);
+
+    //process the two SELF files created
+    DoProcessSELFLiveandKernelL();
+
+	}
+
+/**
+ * Generates a user side crash using the crashapp
+ */
+void CProcessCrashWrapper::GenerateLiveCrashL(const TDesC& aSection)
+	{
+
+	TPtrC crashAppParam;
+	    //read from the INI for crashapp paramemters
+	if(!GetStringFromConfig(aSection, KTe_CrashAppParam, crashAppParam))
+		{
+		ERR_PRINTF1(_L("Failed to get data from ini file"));
+		SetBlockResult(EFail);
+		User::Leave(KErrGeneral);
+	    }
+
+	INFO_PRINTF2(_L("The CrashApp Parameters are: crashapp %S, "), &crashAppParam); // print it to check
+	//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);
+		SetBlockResult(EFail);
+		User::Leave(ret);
+		}
+
+	INFO_PRINTF1(_L("Started userside crash app"));
+
+	// 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);
+		SetBlockResult(EFail);
+		User::Leave( ret );
+		}
+
+	//start the crash process which should go ahead a create a crash
+	crashProcess.Resume();
+	CleanupStack::PopAndDestroy(&crashProcess); //this is for crashProcess
+
+	}
+
+/**
+ * Complete the processing the SELF file generated after the async ProcessCrashLog
+ * called from RunL
+ */
+void CProcessCrashWrapper::ProcessSELFFileCreatedL()
+	{
+
+	INFO_PRINTF1(_L("CProcessCrashWrapper ProcessSELFFileCreatedL called after RunL"));
+
+	//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);
+
+	TInt ret = obj->FindFirst(KCrashWildCard, buf, uid2);
+	if (ret != KErrNone)
+		{
+		ERR_PRINTF2(_L("GenerateElfFileL Error finding the SELF File %d"),
+				ret);
+		SetBlockResult(EFail);
+		User::Leave(ret);
+		}
+
+	iSELFFileName = obj->Entry().iName;
+	CleanupStack::PopAndDestroy();//CFindFileByType* obj
+
+	INFO_PRINTF2(_L("The SELF File Found is E:\\%S "), &iSELFFileName);
+
+	//open the SELF File for processing
+	TInt err = iSELFFile.Open(iFsSession, iSELFFileName, EFileStream|EFileRead);
+	if (err != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::ProcessSELFFileCreatedL Error opening the SELF File %d"),
+				err);
+		SetBlockResult(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 Symbian Info section
+	ValidateSymInfoSectionELFFileL();
+
+	//validate Thread name that crashed
+	ValidateThreadInfoSectionELFFileL(EFalse, KThreadKernelCrash, ETrue);
+
+	//do the necessary clean up
+	CleanupMethod(iSELFFileName);
+
+	}
+
+/**
+ * Process the two SELF files created for user and kernel side crashes
+ */
+void CProcessCrashWrapper::DoProcessSELFLiveandKernelL()
+	{
+	INFO_PRINTF1(_L("CProcessCrashWrapper DoProcessSELFLiveandKernel about process user and kernel crashes"));
+
+	TBool systemcrash = EFalse;
+
+	//Use wildcard utilities to search for the two SELF File Created
+	TBuf<32> buf;
+	buf = KDir;
+	TUidType uid1;
+	TUidType uid2(uid1.MostDerived());
+
+	CFindFileByType* obj = new(ELeave) CFindFileByType(iFsSession);
+	CleanupStack::PushL(obj);
+
+	TInt ret = obj->FindFirst(KCrashWildCard, buf, uid2);
+	if (ret != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("DoProcessSELFLiveandKernelL Error finding the SELF File %d"),
+				ret);
+		SetBlockResult(EFail);
+		User::Leave(ret);
+		}
+
+	iSELFFileName = obj->Entry().iName;
+	INFO_PRINTF2(_L("The SELF File Found is E:\\%S "), &iSELFFileName);
+
+    ret = iSELFFile.Open(iFsSession, iSELFFileName, EFileStream|EFileRead);
+	if (ret != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("DoProcessSELFLiveandKernelL Error opening the SELF File %d"),
+				ret);
+		SetBlockResult(EFail);
+		User::Leave(ret);
+		}
+
+	//validate the SELF Header Format
+	ValidateHeaderELFFileL();
+
+	//validate the Program Header and store information about the string section Sections
+	ValidateProgramHeaderELFFileL();
+
+	//validate the Symbian Info section
+	ValidateSymInfoSectionELFFileL();
+
+	//validate the Register Info Section also verifies the CPSR to check on the type of the crash
+	ValidateRegisterInfoSectionELFFileL();
+
+	if(iSystemCrash)//if it is a System Crash
+		{
+		//checking this SELF file for the kernel crash
+		ValidateThreadInfoSectionELFFileL(EFalse, KThreadKernelCrash, ETrue);
+		}
+	else
+		{
+		//checking this one for user crash
+		ValidateThreadInfoSectionELFFileL(EFalse, KThreadUserCrash, ETrue);
+		}
+
+	systemcrash = iSystemCrash;
+	//do the necessary clean up
+	CleanupMethod(iSELFFileName);
+
+	//Find the next SELF file
+	ret = obj->FindNext();
+
+	if (ret != KErrNone)
+		{
+		ERR_PRINTF1(
+				_L("DoProcessSELFLiveandKernelL Expecting Two SELF files to be created"));
+		SetBlockResult(EFail);
+		User::Leave(ret);
+		}
+
+	iSELFFileName = obj->Entry().iName;
+	INFO_PRINTF2(_L("The SELF File Found is E:\\%S "), &iSELFFileName);
+
+	CleanupStack::PopAndDestroy(); //CFindFileByType
+
+	//open the SELF File for processing
+	ret = iSELFFile.Open(iFsSession, iSELFFileName, EFileStream|EFileRead);
+	if (ret != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("DoProcessSELFLiveandKernelL Error opening the SELF File %d"),
+				ret);
+		SetBlockResult(EFail);
+		User::Leave(ret);
+		}
+
+	//validate the SELF Header Format
+	ValidateHeaderELFFileL();
+
+	//validate the Program Header and store information about the string section Sections
+	ValidateProgramHeaderELFFileL();
+
+	//validate the Symbian Info section
+	ValidateSymInfoSectionELFFileL();
+
+	//validate the Register Info Section also verifies the CPSR to check on the type of the crash
+	ValidateRegisterInfoSectionELFFileL();
+
+	if(iSystemCrash == systemcrash)
+		{
+		ERR_PRINTF1( _L("Expecting to have two different types of crashes one User side and the other one as System Crash"));
+		SetBlockResult(EFail);
+		User::Leave(KErrGeneral);
+		}
+
+	if(iSystemCrash)//if it is a System Crash
+		{
+		//checking this SELF file for the kernel crash
+		ValidateThreadInfoSectionELFFileL(EFalse, KThreadKernelCrash, ETrue);
+		}
+	else
+		{
+		//checking this one for user crash
+		ValidateThreadInfoSectionELFFileL(EFalse, KThreadUserCrash, ETrue);
+		}
+
+	//do the necessary clean up
+	CleanupMethod(iSELFFileName);
+
+	}
+/**
+ * Generate multiple SELF File and Validate the Symbian INFO and executable sections
+ */
+void CProcessCrashWrapper::DoCmdValidateMultipleELFFileL()
+	{
+	INFO_PRINTF1(_L("CProcessCrashWrapper::DoCmdValidateMultipleELFFileL parsing multiple SELF files"));
+
+	//expects MULTIPLECRASHNUMBERCHECK to be present in the flash otherwise complain
+	if (iCrashList.Count() < KMinimumAcceptableCrashNumber)
+		{
+		ERR_PRINTF1(_L("Did not find multiple crashes"));
+		SetBlockResult(EFail);
+		User::Leave(KErrGeneral);
+		}
+
+	for (TInt i = 0; i < iCrashList.Count(); i++)
+		{
+		//generate the SELF File(s) by calling ProcessCrashLogL
+		GenerateElfFileL(iCrashList[i]->iCrashId);
+
+		TInt err = iSELFFile.Open(iFsSession, iSELFFileName, EFileStream|EFileRead);
+		if (err != KErrNone)
+			{
+			ERR_PRINTF2(
+					_L("CProcessCrashWrapper::ProcessELFFile Error opening the SELF File %d"),
+					err);
+			SetBlockResult(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 Symbian Info section
+		ValidateSymInfoSectionELFFileL();
+
+		//validate Thread name that crashed
+		ValidateThreadInfoSectionELFFileL(EFalse, KThreadKernelCrash, ETrue);
+
+		//do the necessary clean up
+		CleanupMethod(iSELFFileName);
+
+		}
+
+/*
+ * code to check on multiple files in the directory and storing them
+ * commented for future reference
+ * RBuf selfname;
+	selfname.CreateL(obj->Entry().iName);
+	selfname.SetMax();
+
+	TBufC<100> selfnamebuffer = obj->Entry().iName;
+	HBufC* selfname = selfnamebuffer.AllocL();
+
+	iArray.Append(selfname);
+
+	INFO_PRINTF2(_L("The SELF File Found is E:\\%S "), &iArray[0]);
+
+	for (TInt i = 0; i < iCrashList.Count() - 1; i++)
+		{
+
+		ret = obj->FindNext();
+		if (ret != KErrNone)
+			{
+			ERR_PRINTF2(
+					_L("CProcessCrashWrapper::CFindFileByType Error finding the SELF File %d"),
+					ret);
+			SetBlockResult(EFail);
+			User::Leave(ret);
+			}
+
+		RBuf selfname2;
+		selfname2.CreateL(obj->Entry().iName);
+		selfname2.SetMax();
+
+		TBufC<100> selfnamebuffer2 = obj->Entry().iName;
+		HBufC* selfname2 = selfnamebuffer2.AllocL();
+
+		iArray.Append(selfname2);// no close
+
+		INFO_PRINTF2(_L("The SELF File Found is E:\\%S "), &iArray[i]);
+	*/
+
+	}
+
+/**
+ * Validates the presence of the heap data in the SELF file
+ */
+void CProcessCrashWrapper::DoCmdValidateHeapSELFFileL()
+	{
+	INFO_PRINTF1(_L("\nDoCmdValidateHeapSELFFileL intend to validate the Heap Section of SELF File"));
+
+	//expects one crash information to be present in the flash otherwise complain
+	if (iCrashList.Count() != 1)
+		{
+		ERR_PRINTF1(_L("More than one crash information present"));
+		SetBlockResult(EFail);
+		User::Leave(KErrGeneral);
+		}
+
+	/*
+	 * POSITIVE TEST CASE
+	 * Test for the positive case let the Heap Section be present
+	 */
+
+	//configuring the SELF Formatter to have the date segment
+    ConfigureSELF(ETrue, EHeap);
+
+	//generate the SELF File by calling ProcessCrashLogL
+	GenerateElfFileL(iCrashList[0]->iCrashId);
+
+	//open the SELF File for processing
+	TInt err = iSELFFile.Open(iFsSession, iSELFFileName, EFileStream|EFileRead);
+	if (err != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::ProcessELFFile Error opening the SELF File %d"),
+				err);
+		SetBlockResult(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 Symbian Info section
+	ValidateSymInfoSectionELFFileL();
+
+	//validate Thread name that crashed
+	ValidateThreadInfoSectionELFFileL(EFalse, KThreadKernelCrash, ETrue);
+
+	//validate the heap section to be present
+	ValidateHeapSectionELFFileL(ETrue);
+
+	//clean up of the generated SELF file
+	iSELFFile.Close();
+    TInt ret = iFsSession.Delete(iSELFFileName);
+	if (ret != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::SELF File delete returned error %d"),
+				ret);
+		SetBlockResult(EFail);
+		User::Leave(ret);
+		}
+
+	INFO_PRINTF1(_L("Validation of the Positive Heap Test Case Successful!!!\n\n"));
+
+	/*
+	 * NEGATIVE TEST CASE
+	 * Test for the negative test case let the Heap Section be NOT present
+	 */
+
+	//configuring the SELF NOT to have data segment/heap
+	ConfigureSELF(EFalse, EHeap);
+
+	//generate the SELF File by calling ProcessCrashLogL
+	GenerateElfFileL(iCrashList[0]->iCrashId);
+
+	//open the SELF File for processing
+	err = iSELFFile.Open(iFsSession, iSELFFileName, EFileStream|EFileRead);
+	if (err != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::ProcessELFFile Error opening the SELF File %d"),
+				err);
+		SetBlockResult(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 Symbian Info section
+	ValidateSymInfoSectionELFFileL();
+
+	//validate Thread name that crashed
+	ValidateThreadInfoSectionELFFileL(EFalse, KThreadKernelCrash, ETrue);
+
+	//validate the heap section NOT to be present this time
+	ValidateHeapSectionELFFileL(EFalse);
+
+	//do necessary clean up
+	CleanupMethod(iSELFFileName);
+
+	INFO_PRINTF1(_L("Validation of the Negative Heap Test Case Successful!!!\n\n"));
+	}
+
+/**
+ * Validates the presence of the trace data in the SELF file
+ */
+void CProcessCrashWrapper::DoCmdValidateTraceSELFFileL()
+	{
+	INFO_PRINTF1(_L("\nDoCmdValidateTraceSELFFileL intend to validate the Trace Section of SELF File"));
+
+	//expects one crash information to be present in the flash otherwise complain
+	if (iCrashList.Count() != 1)
+		{
+		ERR_PRINTF1(_L("More than one crash information present"));
+		SetBlockResult(EFail);
+		User::Leave(KErrGeneral);
+		}
+
+	/*
+	 * POSITIVE TEST CASE
+	 * Test for the positive case let the Trace Section be present
+	 */
+
+	//configuring the SELF Formatter to have the trace segment
+    ConfigureSELF(ETrue, ETrace);
+
+    //generate the SELF File by calling ProcessCrashLogL
+    GenerateElfFileL(iCrashList[0]->iCrashId);
+
+	//open the SELF File for processing
+	TInt err = iSELFFile.Open(iFsSession, iSELFFileName, EFileStream|EFileRead);
+	if (err != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::ProcessELFFile Error opening the SELF File %d"),
+				err);
+		SetBlockResult(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 Symbian Info section
+	ValidateSymInfoSectionELFFileL();
+
+	//validate Thread name that crashed
+	ValidateThreadInfoSectionELFFileL(EFalse, KThreadKernelCrash, ETrue);
+
+	//validate the trace section to be present
+	ValidateTraceSectionELFFileL(ETrue);
+
+	//clean up of the generated SELF file
+	iSELFFile.Close();
+	TInt ret = iFsSession.Delete(iSELFFileName);
+	if (ret != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::SELF File delete returned error %d"),
+				ret);
+		SetBlockResult(EFail);
+		User::Leave(ret);
+		}
+
+	INFO_PRINTF1(_L("Validation of the Positive Test Case Successful!!!\n\n"));
+
+	/*
+	 * NEGATIVE TEST CASE
+	 * Test for the negative test case let the Trace Section be NOT present
+	 */
+
+	//configuring the SELF NOT to have trace segment
+	ConfigureSELF(EFalse, ETrace);
+
+    //generate the SELF File by calling ProcessCrashLogL
+    GenerateElfFileL(iCrashList[0]->iCrashId);
+
+	//open the SELF File for processing
+	err = iSELFFile.Open(iFsSession, iSELFFileName, EFileStream|EFileRead);
+	if (err != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::ProcessELFFile Error opening the SELF File %d"),
+				err);
+		SetBlockResult(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 Symbian Info section
+	ValidateSymInfoSectionELFFileL();
+
+	//validate Thread name that crashed
+	ValidateThreadInfoSectionELFFileL(EFalse, KThreadKernelCrash, ETrue);
+
+	//validate the heap section NOT to be present this time
+	ValidateTraceSectionELFFileL(EFalse);
+
+	//do necessary clean up
+	CleanupMethod(iSELFFileName);
+
+	INFO_PRINTF1(_L("Validation of the Negative Test Case Successful!!!\n\n"));
+
+	}
+
+/**
+ * Benchmark test of SELF files
+ */
+void CProcessCrashWrapper::DoCmdPerformanceMeasureSELFFileL()
+	{
+	INFO_PRINTF1(_L("CProcessCrashWrapper::DoCmdPerformanceMeasureSELFFileL performing Performance measurement on various SELF file(s)"));
+
+	//expects one crash information to be present in the flash otherwise complain
+	if (iCrashList.Count() != 1)
+		{
+		ERR_PRINTF1(_L("More than one crash information present"));
+		SetBlockResult(EFail);
+		User::Leave(KErrGeneral);
+		}
+
+	/*
+	 * WITH OR WITHOUT HEAP DATA
+	 */
+
+	//configuring SELF to have the Heap section
+	ConfigureSELF(ETrue, EHeap);
+
+	//Generate the SELF File keeping a record of the time
+	GenerateElfFileL(iCrashList[0]->iCrashId , ETrue);
+
+	INFO_PRINTF1(_L("SELF File has Heap Data"));
+	ValidatePerformanceELFFile();
+
+	//configuring SELF NOT to have the Heap section
+	ConfigureSELF(EFalse, EHeap);
+
+	//Generate the SELF File keeping a record of the time
+	GenerateElfFileL(iCrashList[0]->iCrashId , ETrue);
+
+	INFO_PRINTF1(_L("SELF File has NO Heap Data"));
+	ValidatePerformanceELFFile();
+
+	/*
+	 * WITH OR WITHOUT CODE SEGEMENT
+	 */
+
+	//configuring SELF to have the Code Segment
+	ConfigureSELF(ETrue, ECode);
+	//putting back the heap data as well
+	ConfigureSELF(ETrue, EHeap);
+
+	//Generate the SELF File keeping a record of the time
+	GenerateElfFileL(iCrashList[0]->iCrashId , ETrue);
+
+	INFO_PRINTF1(_L("SELF File has Code Segement"));
+	ValidatePerformanceELFFile();
+
+	//configuring SELF NOT to have the Code segment
+	ConfigureSELF(EFalse, ECode);
+
+	//Generate the SELF File keeping a record of the time
+	GenerateElfFileL(iCrashList[0]->iCrashId , ETrue);
+
+	INFO_PRINTF1(_L("SELF File has NO Code Segement"));
+	ValidatePerformanceELFFile();
+
+	/*
+	 * WITH OR WITHOUT THREAD SEGEMENT
+	 */
+
+	//configuring SELF to have the Thread Segment
+	ConfigureSELF(ETrue, EThread);
+	//putting back the code segement as well
+	ConfigureSELF(ETrue, ECode);
+
+	//Generate the SELF File keeping a record of the time
+	GenerateElfFileL(iCrashList[0]->iCrashId , ETrue);
+
+	INFO_PRINTF1(_L("SELF File has Thread Segement"));
+	ValidatePerformanceELFFile();
+
+	//configuring SELF NOT to have the Thread segment
+	ConfigureSELF(EFalse, EThread);
+
+	//Generate the SELF File keeping a record of the time
+	GenerateElfFileL(iCrashList[0]->iCrashId , ETrue);
+
+	INFO_PRINTF1(_L("SELF File has NO Thread Segement"));
+	ValidatePerformanceELFFile();
+
+	INFO_PRINTF1(_L("Benchmarking of SELF files successful"));
+	}
+
+/**
+ * Validates the Corrupted Crash Information
+ * Part of neagtive test on ProcessCrashLog
+ */
+void CProcessCrashWrapper::DoCmdValidateCorruptCrashL()
+	{
+	LOG_MSG(_L("CProcessCrashWrapper::DoCmdValidateCorruptCrashL() validating the Corrupted Crash"));
+
+	//reads all the crash information present in the flash
+	DoCmdReadCrashInfoL();
+
+	//expects one crash information to be present in the flash otherwise complain
+	if (iCrashList.Count() != 1)
+		{
+		ERR_PRINTF1(_L("More than one crash information present"));
+		SetBlockResult(EFail);
+		User::Leave(KErrGeneral);
+		}
+
+	INFO_PRINTF1(_L("Able to read crash log now start processing the crash"));
+
+	TRAPD(error, iCoreDumpSession.ProcessCrashLogL(iCrashList[0]->iCrashId));
+	if (error == KErrCorrupt)
+		{
+		INFO_PRINTF2(_L("Success!!! The crash information is corrupted returns error %d\n"), error);
+		}
+	else
+		{
+		ERR_PRINTF2(
+				_L("Returns error %d which is NOT  KErrCorrupt\n"),
+				error);
+		SetBlockResult(EFail);
+		User::Leave(error);
+		}
+	}
+
+/**
+ * Validates the Header Format Elf32_Ehdr for the SELF file
+ */
+void CProcessCrashWrapper::ValidateHeaderELFFileL()
+	{// Elf32_Ehdr
+	INFO_PRINTF1(_L("CProcessCrashWrapper::ValidateHeaderELFFileL validating Elf32_Ehdr"));
+	RDebug::Printf("Validating the ELF file");
+
+	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("CProcessCrashWrapper::ValidateHeaderELFFile Error reading the SELF Header Elf32_Ehdr %d"),
+				ret);
+		SetBlockResult(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"));
+		SetBlockResult(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"));
+			SetBlockResult(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"));
+		SetBlockResult(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"));
+		SetBlockResult(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"));
+		SetBlockResult(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"));
+		SetBlockResult(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 CProcessCrashWrapper::ValidateProgramHeaderELFFileL()
+	{//Elf32_Phdr
+	INFO_PRINTF1(_L("CProcessCrashWrapper::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("CProcessCrashWrapper::ValidateProgramHeaderELFFileL Error reading the SELF Header Elf32_Phdr %d"),
+				ret);
+		SetBlockResult(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("CProcessCrashWrapper::ValidateHeaderELFFile Error reading the SELF Header Sym32_dhdr %d"),
+					ret);
+			SetBlockResult(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 Symbian Info Section Sym32_syminfod of the SELF file
+ */
+void CProcessCrashWrapper::ValidateSymInfoSectionELFFileL()
+	{//Sym32_syminfod
+	INFO_PRINTF1(_L("CProcessCrashWrapper::ValidateSymInfoSection validating the Symbian Info Section"));
+
+	Elf32_Phdr* phdr = (Elf32_Phdr*) iSELFPHHeader;//Elf32_Phdr Program Header
+
+	//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_SYM) //SYMBIAN INFO SEGMENT
+				{
+				if (sizeof(Sym32_syminfod) != (idhdr[i]->d_descrsz))
+					{
+					ERR_PRINTF1(_L("CProcessCrashWrapper::ValidateProgramHeaderELFFileL sizeof(Sym32_syminfod)is different from descriptor size") );
+					SetBlockResult(EFail);
+					User::Leave(KErrGeneral);
+					}
+				TInt sizeofsyminfo = sizeof(Sym32_syminfod);
+				INFO_PRINTF2(_L("ESYM_NOTE_SYM Header offset %d"), phdr[i].p_offset);
+				INFO_PRINTF2(_L("ESYM_NOTE_SYM Size of single descriptor element %d"),
+						idhdr[i]->d_descrsz);
+
+				TInt offsettosyminfod = phdr[i].p_offset + sizeof(Sym32_dhdr);
+
+				//allocate buffer for Sym32_syminfod
+				TUint8* symbianInfoSection = new TUint8[sizeofsyminfo];
+				CleanupStack::PushL(symbianInfoSection);
+
+				TPtr8 ptrSymbianInfoSection(symbianInfoSection, sizeofsyminfo,
+						sizeofsyminfo);
+
+				TInt ret = iSELFFile.Read(offsettosyminfod, ptrSymbianInfoSection, sizeofsyminfo);
+				if (ret != KErrNone)
+					{
+					ERR_PRINTF2(
+							_L("CProcessCrashWrapper::ValidateProgramHeaderELFFileL Error reading the SELF Header Sym32_syminfod %d"), ret);
+					SetBlockResult(EFail);
+					User::Leave(ret);
+					}
+				Sym32_syminfod *syminfod = (Sym32_syminfod*) symbianInfoSection; //Symbian Info Section Sym32_syminfod
+
+				// Validation Phase of the Symbian Info section
+				INFO_PRINTF2(_L("Executable Crc32 %X"), syminfod->sd_execid.exec_crc);
+				INFO_PRINTF2(_L("Crashed Thread %ld"), syminfod->sd_thread_id);
+				INFO_PRINTF2(_L("Owning Process %ld"), syminfod->sd_proc_id);
+
+				iCrashedThreadId = syminfod->sd_thread_id;
+				if (ECrashException == syminfod->sd_exit_type)
+					{
+					INFO_PRINTF2(_L("Hardware Exception Number:%d"),
+							syminfod->sd_exit_reason);
+					ValidateExceptionL(syminfod->sd_exit_reason, ETestDataAbort, EFalse); //print the exception string
+					}
+				else
+					if (ECrashKill == syminfod->sd_exit_type)
+						{
+						INFO_PRINTF2(_L("Exit Type\t\t\t:%d"),
+								syminfod->sd_exit_reason);
+						switch (syminfod->sd_exit_reason)
+							{
+							case 0:
+								INFO_PRINTF1(_L(":EExitKill\n"));
+								break;
+							case 1:
+								INFO_PRINTF1(_L(":EExitTerminate\n"));
+								break;
+							case 2:
+								INFO_PRINTF1(_L(":EExitPanic\n"));
+								break;
+							case 3:
+								INFO_PRINTF1(_L(":EExitPending\n"));
+								break;
+							default:
+								INFO_PRINTF1(_L(":Unknown\n"));
+								break;
+							}
+						}
+					else
+						{
+						INFO_PRINTF1(_L("\tUnknown Crash Type\n"));
+						}
+
+				CleanupStack::PopAndDestroy(symbianInfoSection);
+
+				}//if ESYM_NOTE_SYM
+
+			if (idhdr[i]->d_type == ESYM_NOTE_EXEC) //EXECUTABLE INFO SEGMENT
+				{
+				if (sizeof(Sym32_execinfod) != (idhdr[i]->d_descrsz))
+					{
+					ERR_PRINTF1(_L("CProcessCrashWrapper::ValidateProgramHeaderELFFileL sizeof(Sym32_execinfod))is different from descriptor size") );
+					User::Leave(KErrGeneral);
+					}
+
+				TInt sizeofsymexecinfo = sizeof(Sym32_execinfod);
+				INFO_PRINTF2(_L("ESYM_NOTE_EXEC Header offset %d"),
+						phdr[i].p_offset);
+				INFO_PRINTF2(
+						_L("ESYM_NOTE_EXEC Size of single descriptor element %d"),
+						idhdr[i]->d_descrsz);
+
+				//Sym32_execinfod *execinfod = ADDR(Sym32_execinfod,eh,data+sizeof(Sym32_dhdr));
+				TInt offsettosymexecinfod = phdr[i].p_offset
+						+ sizeof(Sym32_dhdr);
+
+				TUint8* symbianExecInfoSection = new TUint8[sizeofsymexecinfo];
+				CleanupStack::PushL(symbianExecInfoSection);
+
+				TPtr8 ptrSymbianExecInfoSection(symbianExecInfoSection,
+						sizeofsymexecinfo, sizeofsymexecinfo);
+
+				TInt ret = iSELFFile.Read(offsettosymexecinfod,
+						ptrSymbianExecInfoSection, sizeofsymexecinfo);
+				if (ret != KErrNone)
+					{
+					ERR_PRINTF2(
+							_L("CProcessCrashWrapper::ValidateProgramHeaderELFFileL Error reading the SELF Header Sym32_execinfod %d"),
+							ret);
+					User::Leave(ret);
+					}
+				Sym32_execinfod *execinfod =
+						(Sym32_execinfod*) symbianExecInfoSection; //Symbian Info Section Sym32_syminfod
+
+				TBufC<30> nameToCheck(KCrashAppFileName);
+
+				ValidateStringL(EValExecutable, execinfod->ed_name, nameToCheck, EFalse);
+
+				CleanupStack::PopAndDestroy();
+				}//if ESYM_NOTE_EXEC
+
+			}//if PT_NOTE
+
+		}//for loop PHEntries
+	INFO_PRINTF1(_L("Sym_Info validated"));
+	}
+
+/**
+ * Validates the Symbian Thread Section Sym32_thrdinfod of the SELF file
+ * @param aValidateCpuId If this is true, this test will fail if all the CPU Id's are not the same
+ */
+void CProcessCrashWrapper::ValidateThreadInfoSectionELFFileL(TBool aValidateCpuId, const TDesC& aThreadCrashed, TBool aCheck)
+	{
+	INFO_PRINTF1(_L("Validating the Symbian Thread Info Section"));
+
+	Elf32_Phdr* phdr = (Elf32_Phdr*) iSELFPHHeader;//Elf32_Phdr Program Header
+	TInt cpuId = -1;
+
+	//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_THRD) //SYMBIAN INFO SEGMENT
+				{
+				if (sizeof(Sym32_thrdinfod) != (idhdr[i]->d_descrsz))
+					{
+					ERR_PRINTF1(_L("CProcessCrashWrapper::ValidateThreadInfoSectionELFFileL sizeof(Sym32_thrdinfod) %d is different from descriptor size") );
+					SetBlockResult(EFail);
+					User::Leave(KErrGeneral);
+					}
+
+				TInt sizeofthreadinfo = sizeof(Sym32_thrdinfod);
+				INFO_PRINTF2(_L("ESYM_NOTE_THRD Header offset %d"), phdr[i].p_offset);
+				INFO_PRINTF2(_L("ESYM_NOTE_THRD Size of single descriptor element %d"),
+						idhdr[i]->d_descrsz);
+				INFO_PRINTF2(_L("ESYM_NOTE_THRD Number of elements %d"), idhdr[i]->d_elemnum);
+
+				TInt offsettothreadinfod = phdr[i].p_offset + sizeof(Sym32_dhdr);
+				TInt newoffsettothreadinfod = offsettothreadinfod;
+
+				//allocate buffer for Sym32_thrdinfod
+				TUint8* symbianThreadSection = new TUint8[sizeofthreadinfo];
+				CleanupStack::PushL(symbianThreadSection);
+
+				TPtr8 ptrSymbianThreadSection(symbianThreadSection, sizeofthreadinfo,
+						sizeofthreadinfo);
+
+				TInt ret = iSELFFile.Read(offsettothreadinfod, ptrSymbianThreadSection, sizeofthreadinfo);
+				if (ret != KErrNone)
+					{
+					ERR_PRINTF2(
+							_L("CProcessCrashWrapper::ValidateThreadInfoSectionELFFileL Error reading the SELF Header Sym32_thrdinfod %d"), ret);
+					SetBlockResult(EFail);
+					User::Leave(ret);
+					}
+				Sym32_thrdinfod *thrdinfod = (Sym32_thrdinfod*) symbianThreadSection; //Symbian Info Section Sym32_syminfod
+
+				for(int thrIdx = 0; thrIdx < idhdr[i]->d_elemnum; thrIdx++ )
+					{
+					//valid checking fo thread id
+
+					if (iCrashedThreadId == thrdinfod->td_id)
+						{
+						INFO_PRINTF2(_L("Owning process %ld"), thrdinfod->td_owning_process);
+						INFO_PRINTF2(_L("Thread Priority %d"), thrdinfod->td_priority);
+						INFO_PRINTF2(_L("Heap Adress 0x%X"), thrdinfod->td_heap_add);
+						INFO_PRINTF2(_L("Heap Size %d"), thrdinfod->td_heap_sz);
+						//storing the heap address and the Heap Siz for future verification
+						iHeapBase = thrdinfod->td_heap_add;
+						iHeapSize = thrdinfod->td_heap_sz;
+
+						ValidateStringL(EValThread, thrdinfod->td_name, aThreadCrashed, aCheck);
+
+						}
+
+					if(aValidateCpuId)
+						{
+						//If its the first, set the CPU ID to be this
+						if(cpuId < 0)
+							{
+							cpuId = thrdinfod->td_last_cpu_id;
+							}
+						else
+							{
+							//Otherwise, the current CPU ID should be the same as the previous
+							if(thrdinfod->td_last_cpu_id != cpuId)
+								{
+								ERR_PRINTF3(_L("CProcessCrashWrapper::ValidateThreadInfoSectionELFFileL CPU ID Not as expected. Current is not the same as previous. Current = [%d] Previous = [%d]"), thrdinfod->td_last_cpu_id, cpuId);
+								SetBlockResult(EFail);
+								User::Leave(KErrCorrupt);
+								}
+							cpuId = thrdinfod->td_last_cpu_id;
+							}
+						}
+
+					newoffsettothreadinfod = newoffsettothreadinfod + sizeofthreadinfo;
+
+					ret = iSELFFile.Read(newoffsettothreadinfod, ptrSymbianThreadSection, sizeofthreadinfo);
+					if (ret != KErrNone)
+						{
+						ERR_PRINTF2(
+								_L("CProcessCrashWrapper::ValidateThreadInfoSectionELFFileL Error reading the SELF Header Sym32_thrdinfod %d"), ret);
+						SetBlockResult(EFail);
+						User::Leave(ret);
+						}
+
+					thrdinfod = (Sym32_thrdinfod*) symbianThreadSection;
+
+					}
+
+				CleanupStack::PopAndDestroy();
+				}//if ESYM_NOTE_THRD
+
+			}//if PT_NOTE
+
+		}//for PHEntries
+
+	}
+
+/**
+ * Validates the Register Info Section
+ * Reads the CPSR value to determine the type of the crash (user/system)
+ */
+void CProcessCrashWrapper::ValidateRegisterInfoSectionELFFileL()
+	{
+
+	INFO_PRINTF1(_L("CProcessCrashWrapper::ValidateRegisterInfoSectionELFFileL validating the regsiter Section"));
+
+	TBool matchfound = EFalse;
+	Elf32_Phdr* phdr = (Elf32_Phdr*) iSELFPHHeader;//Elf32_Phdr Program Header
+
+	//loop through the program headers to get information about the Symbian Info section
+	for (TInt i = 0; (i < iPHEntries) && !matchfound; i++)
+		{
+		if (phdr[i].p_type == PT_NOTE)
+			{
+			if (idhdr[i]->d_type == ESYM_NOTE_REG) //SYMBIAN REGISTER INFO SEGEMENT
+				{
+
+				TInt sizeofreginfo = sizeof(Sym32_reginfod);
+				TInt offsettoreginfod = phdr[i].p_offset + sizeof(Sym32_dhdr);
+
+				//allocate buffer for Sym32_reginfod
+				TUint8* symbianRegSection = new TUint8[sizeofreginfo];
+				CleanupStack::PushL(symbianRegSection);
+
+				TPtr8 ptrSymbianRegSection(symbianRegSection, sizeofreginfo,
+						sizeofreginfo);
+
+				TInt ret = iSELFFile.Read(offsettoreginfod, ptrSymbianRegSection, sizeofreginfo);
+				if (ret != KErrNone)
+					{
+					ERR_PRINTF2(
+							_L("CProcessCrashWrapper::ValidateRegisterInfoSectionELFFileL Error reading the SELF Header Sym32_thrdinfod %d"), ret);
+					SetBlockResult(EFail);
+					User::Leave(ret);
+					}
+				Sym32_reginfod *reginfod = (Sym32_reginfod*) symbianRegSection; //Symbian Register Info Section Sym32_reginfod
+
+				if(reginfod->rid_thread_id == iCrashedThreadId)
+					{
+
+					INFO_PRINTF2(_L("Crashed Thread id %ld"), iCrashedThreadId);
+					INFO_PRINTF2(_L("Thread ID %ld"), reginfod->rid_thread_id);
+
+					TInt offsettoregdatad = offsettoreginfod + sizeofreginfo;
+
+					for( TInt i = 0; (i < reginfod->rid_num_registers) && !matchfound; i++ )
+						{
+						//Sym32_regdatad immediately following the Register Info descriptor header
+						TInt sizeofregdatad = sizeof (Sym32_regdatad);
+						offsettoregdatad = offsettoregdatad + sizeofreginfo;
+
+						TUint8* symbianRegDatad = new TUint8[sizeofregdatad];
+						CleanupStack::PushL(symbianRegDatad);
+
+						TPtr8 ptrSymbianRegDatad(symbianRegDatad, sizeofregdatad,
+								sizeofregdatad);
+
+						TInt ret = iSELFFile.Read(offsettoregdatad, ptrSymbianRegDatad, sizeofregdatad);
+						if (ret != KErrNone)
+							{
+							ERR_PRINTF2(
+									_L("CProcessCrashWrapper::ValidateRegisterInfoSectionELFFileL Error reading the SELF Header Sym32_thrdinfod %d"), ret);
+							SetBlockResult(EFail);
+							User::Leave(ret);
+							}
+
+						Sym32_regdatad *regdatad = (Sym32_regdatad*) symbianRegDatad; //Symbian Register Info Section Sym32_regdatad
+
+						if( (ESYM_REG_CORE == reginfod->rid_class) && (ESYM_REG_32 == reginfod->rid_repre) && (KCPSRReg == regdatad->rd_id) )
+							{
+							//we have found the CPSR value for the crashed thread, now read the register value
+							TInt sizeofELF32Word = sizeof(Elf32_Word);
+							TUint8* rd_data_cpsr = new TUint8[sizeofELF32Word];
+							CleanupStack::PushL(rd_data_cpsr);
+
+							TPtr8 ptrSymbianRdDataCpsr(rd_data_cpsr, sizeofELF32Word,
+									sizeofELF32Word);
+
+							TInt ret = iSELFFile.Read(regdatad->rd_data , ptrSymbianRdDataCpsr, sizeofELF32Word);
+							if (ret != KErrNone)
+								{
+								ERR_PRINTF2(
+									_L("CProcessCrashWrapper::ValidateRegisterInfoSectionELFFileL Error reading the SELF Header Sym32_thrdinfod %d"), ret);
+								SetBlockResult(EFail);
+								User::Leave(ret);
+								}
+
+							Elf32_Word * val32 = (Elf32_Word*) rd_data_cpsr;
+
+							TUint cpsrval = *val32;
+
+							if(cpsrval & KModeBitCPSR) //checking on the M[4:0] mode bits of the CPSR
+								{
+								INFO_PRINTF2(_L("System Crash CPSR  value: 0x%X\n"), cpsrval );
+								iSystemCrash = ETrue; //system crash
+								}
+							else
+								{
+								INFO_PRINTF2(_L("User Side Crash CPSR  value: 0x%X\n"), cpsrval );
+								iSystemCrash = EFalse; //user crash
+								}
+
+							matchfound = ETrue;
+
+							CleanupStack::PopAndDestroy();//rd_data_cpsr CPSR data value
+							}
+
+						CleanupStack::PopAndDestroy();//Sym32_regdatad symbianRegDatad
+						}// for loop reginfod->rid_num_registers
+
+					}//if iCrashedThreadId
+
+				CleanupStack::PopAndDestroy();
+
+				}
+			}
+		}
+
+	}
+
+/**
+ * Validates the Heap Section of the SELF file
+ */
+void CProcessCrashWrapper::ValidateHeapSectionELFFileL(TBool aHeapCheck)
+	{
+
+	INFO_PRINTF1(_L("CProcessCrashWrapper::ValidateHeapSectionELFFileL validating the Heap Section"));
+
+	Elf32_Phdr* phdr = (Elf32_Phdr*) iSELFPHHeader;//Elf32_Phdr Program Header
+
+	TBool matchfound = 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_LOAD)
+			{
+			if(phdr[i].p_vaddr == iHeapBase && phdr[i].p_filesz == iHeapSize )
+				{
+				if(phdr[i].p_filesz == 0) //if the heap size is zero just complain
+					{
+					ERR_PRINTF1(
+							_L("CProcessCrashWrapper::ValidateHeapSectionELFFileL Error Heap Size found to be zero"));
+					SetBlockResult(EFail);
+					User::Leave(KErrGeneral);
+					}
+				matchfound = ETrue;
+				INFO_PRINTF2(_L("Heap section found at PHDR offset %d"), phdr[i].p_offset);
+				break;
+				}
+
+			}
+		}
+	if(!aHeapCheck && matchfound )
+		{
+		ERR_PRINTF1(
+				_L("CProcessCrashWrapper::ValidateHeapSectionELFFileL Error found heap section when there shouldnt be one"));
+		SetBlockResult(EFail);
+		User::Leave(KErrGeneral);
+		}
+	if(aHeapCheck  && !matchfound )
+		{
+		ERR_PRINTF1(
+				_L("CProcessCrashWrapper::ValidateHeapSectionELFFileL Error did not find the heap section"));
+		SetBlockResult(EFail);
+		User::Leave(KErrGeneral);
+		}
+
+	}
+
+/**
+ * Validates the Trace Section Sym32_tracedata of the SELF file
+ */
+void CProcessCrashWrapper::ValidateTraceSectionELFFileL(TBool aTraceCheck)
+	{
+
+	INFO_PRINTF1(_L("CProcessCrashWrapper::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("CProcessCrashWrapper::ValidateTraceSectionELFFileL sizeof(Sym32_tracedata) %d is different from descriptor size") );
+					SetBlockResult(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("CProcessCrashWrapper::ValidateTraceSectionELFFileL Error reading the SELF Header Sym32_thrdinfod %d"), ret);
+					SetBlockResult(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();
+
+					tracebufferString.CreateL(traceInfo->tr_size);//READING 200 characters assuming strings to be not more than 200 characters
+
+					TInt ret = iSELFFile.Read(traceInfo->tr_data, tracebufferString, traceInfo->tr_size);
+					if (ret != KErrNone)
+						{
+						ERR_PRINTF2(
+								_L("CProcessCrashWrapper::ValidateTraceSectionELFFileL Error reading the Trace Information  %d"),
+								ret);
+						SetBlockResult(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("CProcessCrashWrapper::ValidateTraceSectionELFFileL Error found trace size to be zero"));
+					SetBlockResult(EFail);
+					User::Leave(KErrGeneral);
+
+					}
+				}
+			}
+
+		}
+
+	if(!aTraceCheck && dataPresent )
+		{
+		ERR_PRINTF1(
+				_L("CProcessCrashWrapper::ValidateTraceSectionELFFileL Error found trace section when there shouldnt be one"));
+		SetBlockResult(EFail);
+		User::Leave(KErrGeneral);
+		}
+	if(aTraceCheck  && !dataPresent )
+		{
+		ERR_PRINTF1(
+				_L("CProcessCrashWrapper::ValidateTraceSectionELFFileL Error did not find the trace section"));
+		SetBlockResult(EFail);
+		User::Leave(KErrGeneral);
+		}
+
+	}
+
+/**
+ * @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 CProcessCrashWrapper::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"));
+
+	}
+/**
+ * Utility Function to print and validate the exception type
+ * @param aException exception number
+ * @param acheckException exception to check for
+ * @param aCheck whether to validate the exception or not
+ */
+void CProcessCrashWrapper::ValidateExceptionL(TInt aException, TInt acheckException, TBool aCheck)
+	{
+	INFO_PRINTF2(_L("Hardware Exception of type: %d"), aException);
+	switch (aException)
+		{
+		case 0:
+			INFO_PRINTF1(_L(":EExcGeneral"));
+			break;
+		case 1:
+			INFO_PRINTF1(_L(":EExcIntegerDivideByZero"));
+			break;
+		case 2:
+			INFO_PRINTF1(_L(":EExcSingleStep"));
+			break;
+		case 3:
+			INFO_PRINTF1(_L(":EExcBreakPoint"));
+			break;
+		case 4:
+			INFO_PRINTF1(_L(":EExcIntegerOverflow"));
+			break;
+		case 5:
+			INFO_PRINTF1(_L(":EExcBoundsCheck"));
+			break;
+		case 6:
+			INFO_PRINTF1(_L(":EExcInvalidOpCode"));
+			break;
+		case 7:
+			INFO_PRINTF1(_L(":EExcDoubleFault"));
+			break;
+		case 8:
+			INFO_PRINTF1(_L(":EExcStackFault"));
+			break;
+		case 9:
+			INFO_PRINTF1(_L(":EExcAccessViolation"));
+			break;
+		case 10:
+			INFO_PRINTF1(_L(":EExcPrivInstruction"));
+			break;
+		case 11:
+			INFO_PRINTF1(_L(":EExcAlignment"));
+			break;
+		case 12:
+			INFO_PRINTF1(_L(":EExcPageFault"));
+			break;
+		case 13:
+			INFO_PRINTF1(_L(":EExcFloatDenormal"));
+			break;
+		case 14:
+			INFO_PRINTF1(_L(":EExcFloatDivideByZero"));
+			break;
+		case 15:
+			INFO_PRINTF1(_L(":EExcFloatInexactResult"));
+			break;
+		case 16:
+			INFO_PRINTF1(_L(":EExcFloatInvalidOperation"));
+			break;
+		case 17:
+			INFO_PRINTF1(_L(":EExcFloatOverflow"));
+			break;
+		case 18:
+			INFO_PRINTF1(_L(":EExcFloatStackCheck"));
+			break;
+		case 19:
+			INFO_PRINTF1(_L(":EExcFloatUnderflow"));
+			break;
+		case 20:
+			INFO_PRINTF1(_L(":EExcAbort"));
+			break;
+		case 21:
+			INFO_PRINTF1(_L(":EExcKill"));
+			break;
+		case 22:
+			INFO_PRINTF1(_L(":EExcUserInterrupt"));
+			break;
+		case 23:
+			INFO_PRINTF1(_L(":EExcDataAbort"));
+			break;
+		case 24:
+			INFO_PRINTF1(_L(":EExcCodeAbort"));
+			break;
+		case 25:
+			INFO_PRINTF1(_L(":EExcMaxNumber"));
+			break;
+		case 26:
+			INFO_PRINTF1(_L(":EExcInvalidVector"));
+			break;
+		default:
+			ERR_PRINTF1(_L("Unknown Exception"));
+			break;
+		}
+
+		if(aCheck)
+			{
+		    if( aException != acheckException )
+		    	{
+		    	ERR_PRINTF1(
+						_L("CProcessCrashWrapper::ValidateExceptionL is not the valid type"));
+				SetBlockResult(EFail);
+				User::Leave(KErrGeneral);
+		    	}
+
+		    INFO_PRINTF1(_L("Hardware Exception matched successful!"));
+			}
+
+	}
+/**
+ * Utility Function to print and validate a string
+ * Reads the String section and searches for a NULL character to find the right string
+ * @param aIndex index to the string section
+ * @param aStingToMatch string to be matched
+ * @param aCheck whether to validate the string or not
+ */
+void CProcessCrashWrapper::ValidateStringL(TValidateString aType, TInt aIndex, const TDesC& aStingToMatch, TBool aCheck)
+	{
+	INFO_PRINTF2(_L("CProcessCrashWrapper::ValidateStringL Index %d"), aIndex);
+
+	RBuf8 bufferString;
+	bufferString.CleanupClosePushL();
+	bufferString.CreateL(KMaxStringLength);//Reading 200 characters assuming strings to be not more than 200 characters
+
+	//going to the string in the string node
+	TInt offsetString = iOffsetStringSection + aIndex;
+	TInt ret = iSELFFile.Read(offsetString, bufferString, KMaxStringLength);
+	if (ret != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::PrintStringL Error reading the String Information  %d"),
+				ret);
+		SetBlockResult(EFail);
+		User::Leave(ret);
+		}
+
+	//trying to find a NULL terminating character
+	TInt nullPos = -1;
+	TInt loop = 0;
+	while ((nullPos = bufferString.Locate(NULL)) > KErrNotFound)
+		{
+		loop++;
+		if (loop > KMaxStringLength)
+			{
+			ERR_PRINTF1(_L("CProcessCrashWrapper::ValidateStringL Error reading NULL character from the string"));
+			SetBlockResult(EFail);
+			User::Leave(KErrGeneral);
+			}
+		else
+			{
+			//found the NULL character exit the loop
+			INFO_PRINTF2(_L("ValidateStringL postion of NULL character %d"), nullPos);
+			break;
+			}
+		}
+
+	CleanupStack::PopAndDestroy(); //bufferString
+
+	//create a new actual string to hold the value we want
+	RBuf8 printString;
+	printString.CreateL(nullPos+2);
+	printString.CleanupClosePushL();
+
+	ret = iSELFFile.Read(offsetString, printString, nullPos);
+	if (ret != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::ValidateStringL Error reading reading the String Information %d"),
+				ret);
+		SetBlockResult(EFail);
+		User::Leave(ret);
+		}
+
+	//create a NULL terminated string for printing on serial output
+	char* clPrompt = (char*) printString.PtrZ();
+	RDebug::Printf("String printed %s", clPrompt);
+
+	RBuf bigString;
+	bigString.CreateL(KMaxFileName);
+	bigString.CleanupClosePushL();
+
+	bigString.Copy(printString); //8 to 16 bit conversion
+
+	if(aType == EValExecutable)
+		{
+		INFO_PRINTF2(_L("Crashed Executable name: %S"), &bigString);
+
+		}
+
+	else if(aType == EValThread)
+		{
+		if(!aCheck) //NOT to check on the thread name
+			{
+			//just happy printing the name of the thread
+			INFO_PRINTF2(_L("Crashed Thread name: %S"), &bigString);
+			}
+		else
+			{
+			// check with the thread name passed
+			RBuf stringtoCheck;
+			stringtoCheck.Create(aStingToMatch);
+			stringtoCheck.CleanupClosePushL();
+
+			bigString.SetLength(stringtoCheck.Length()); //reducing the length
+
+			INFO_PRINTF2(_L("Crashed Thread name Verified : %S"), &bigString);
+
+			if(bigString.Compare(stringtoCheck) != 0)
+				{
+				ERR_PRINTF1(
+						_L("CProcessCrashWrapper::ValidateStringL Application name does not match "));
+				SetBlockResult(EFail);
+				User::Leave(KErrGeneral);
+				}
+
+			INFO_PRINTF1( _L("CProcessCrashWrapper::ValidateStringL Crashed Application Match Successful ! "));
+
+			CleanupStack::PopAndDestroy();//stringtoCheck
+
+			}
+
+		}
+	CleanupStack::PopAndDestroy();//bigString
+	CleanupStack::PopAndDestroy(); //printString
+
+	}
+
+/**
+ * Utility Function to do trace data verification
+ */
+void CProcessCrashWrapper::ValidateTraceBufferL(const TDesC8& aBuffer)
+{
+	INFO_PRINTF2(_L("CDataTranslator::ValidateTraceBufferL: size: %d"), aBuffer.Length());
+
+	const TUint8* tracePtr = aBuffer.Ptr();
+	TInt traceSize = aBuffer.Length();
+
+/*	TUint8 recSize = 0;
+	TUint8 flags = 0;*/
+	TUint8 category = 0;
+/*	TUint8 subCategory = 0;*/
+	TInt count = 0;
+
+	const TUint8* endPtr = tracePtr+traceSize;
+	while(tracePtr < endPtr)
+	{
+		count++;
+		category = 0;
+
+		/*recSize = flags = subCategory = 0;
+		recSize = tracePtr[BTrace::ESizeIndex];
+		flags = tracePtr[BTrace::EFlagsIndex];
+		subCategory = tracePtr[BTrace::ESubCategoryIndex];*/
+
+		//read trace header
+		category = tracePtr[BTrace::ECategoryIndex];
+
+		//check the parameter Category
+		if(category != KTraceCategory)
+			{
+			ERR_PRINTF1(
+					_L("CProcessCrashWrapper::ValidateTraceBufferL Category 200 did not match with the trace buffer"));
+			SetBlockResult(EFail);
+			User::Leave(KErrGeneral);
+			}
+
+		tracePtr = BTrace::NextRecord((TAny*)tracePtr);
+	}
+
+	INFO_PRINTF2(_L("Number of trace packets found: %d"), count);
+}
+
+/**
+ * Reports performance metrics from all the tests
+ */
+void CProcessCrashWrapper::ValidatePerformanceELFFile()
+	{
+
+	TInt ticks = HelpGetTestTicks();
+	TInt nkTicksPerSecond = HelpTicksPerSecond();
+
+	TInt actualtimeinseconds = ticks/nkTicksPerSecond;
+
+	INFO_PRINTF3(_L("SELF File Creation E:\\%S took: %d seconds\n") , &iSELFFileName, ticks/nkTicksPerSecond);
+
+	if (actualtimeinseconds > KMAXTIMEOUT)
+		{
+		ERR_PRINTF2(
+				_L("SELF File Creation had exceeded TIME OUT of %d secs "), KMAXTIMEOUT);
+		SetBlockResult(EFail);
+		User::Leave(KErrGeneral);
+		}
+
+	//clean up routine for the file created
+	TInt ret = iFsSession.Delete(iSELFFileName);
+	if (ret != KErrNone)
+		{
+		ERR_PRINTF2(
+				_L("CProcessCrashWrapper::SELF File delete returned error %d"),
+				ret);
+		SetBlockResult(EFail);
+		User::Leave(ret);
+		}
+	iStartTick = iStopTick = 0;//reset the timer ticks
+
+	}
+/**
+ * Utility Function to do SELF Configurations
+ */
+void CProcessCrashWrapper::ConfigureSELF(TBool aPresent, TInt aSegment)
+	{
+
+	INFO_PRINTF3(_L("CProcessCrashWrapper::ConfigureSELF confiugring SELF for segment %d to present %d"), aSegment, aPresent);
+
+	if(EHeap == aSegment)
+		{//heap segment is configured through the data segemnts in the SELF file
+		if(aPresent)
+			{//configure to have data segments
+			DoConfigureL(2, KUidELFFormatterV2.iUid, COptionConfig::EFormatterPlugin,
+					COptionConfig::ETBool, KDataSegmentPrompt,
+					1, KTrueFalseOpt, 1, KTrueOpt, 0);
+
+			}
+		else
+			{//configure NOT to have data segments
+			DoConfigureL(2, KUidELFFormatterV2.iUid, COptionConfig::EFormatterPlugin,
+					COptionConfig::ETBool, KDataSegmentPrompt,
+					1, KTrueFalseOpt, 0, KFalseOpt, 0);
+			}
+		}
+
+    if(ETrace == aSegment)
+    	{//trace segment configured here
+    	if(aPresent)
+			{//configure to have trace segments upto have 10KB data
+			DoConfigureL(8, KUidELFFormatterV2.iUid, COptionConfig::EFormatterPlugin,
+					COptionConfig::ETInt,  KCreateTraceData,
+					1, KNullDesC, 10, KNullDesC, 0);
+
+			}
+		else
+			{//configure NOT to have trace segments
+			DoConfigureL(8, KUidELFFormatterV2.iUid, COptionConfig::EFormatterPlugin,
+					COptionConfig::ETInt,  KCreateTraceData,
+					1, KNullDesC, 0, KNullDesC, 0);
+			}
+    	}
+
+    if(ECode == aSegment)
+    	{//code segment configured here
+    	if(aPresent)
+    		{//configure to have Code Segements
+			DoConfigureL(3, KUidELFFormatterV2.iUid, COptionConfig::EFormatterPlugin,
+					COptionConfig::ETBool, KCodeSegmentPrompt,
+					1, KTrueFalseOpt, 1, KTrueOpt, 0);
+    		}
+    	else
+    		{//configure NOT to have Code Segments
+			DoConfigureL(3, KUidELFFormatterV2.iUid, COptionConfig::EFormatterPlugin,
+					COptionConfig::ETBool, KCodeSegmentPrompt,
+					1, KTrueFalseOpt, 0, KFalseOpt, 0);
+    		}
+    	}
+
+    if(EThread == aSegment)
+    	{//thread segment configured here
+    	if(aPresent)
+    		{//configure to have Thread Segments
+			DoConfigureL(4, KUidELFFormatterV2.iUid, COptionConfig::EFormatterPlugin,
+					COptionConfig::ETBool, KThreadSegmentPrompt,
+					1, KTrueFalseOpt, 1, KTrueOpt, 0);
+    		}
+    	else
+    		{//configure NOT to have Thread Segments
+			DoConfigureL(4, KUidELFFormatterV2.iUid, COptionConfig::EFormatterPlugin,
+					COptionConfig::ETBool, KThreadSegmentPrompt,
+					1, KTrueFalseOpt, 0, KFalseOpt, 0);
+    		}
+    	}
+
+	}
+
+/**
+ * Utility Function to do cleanup activities
+ */
+void CProcessCrashWrapper::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("CProcessCrashWrapper::SELF File delete returned error %d"),
+				ret);
+		SetBlockResult(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 of the SELF File\n"));
+	}
+
+/**
+ * Returns the number of nanokernel ticks in one second
+ * @return Number of nanokernel ticks. 0 if unsuccesful
+ */
+TInt CProcessCrashWrapper::HelpTicksPerSecond(void)
+	{
+	TInt nanokernel_tick_period;
+	HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
+
+	ASSERT(nanokernel_tick_period != 0);
+
+	static const TInt KOneMillion = 1000000;
+
+	return KOneMillion/nanokernel_tick_period;
+	}
+
+/**
+ *Prints the error condition for TEF log/output
+ */
+void CProcessCrashWrapper::PrintErrorCondition(TInt aError)
+	{
+	//print out the error and put the result as failure
+	ERR_PRINTF2(_L("Oops!!! error %d"),aError);
+	SetBlockResult(EFail);
+	}
+/*
+ * class CAsyncProcessCrash Implementation
+ */
+
+/**
+ * Two phase constructor for CAsyncProcessCrash
+ * @return CAsyncProcessCrash object
+ * @leave
+ */
+CAsyncProcessCrash* CAsyncProcessCrash::NewL(CProcessCrashWrapper* aProcessCrashWrapper)
+	{
+	CAsyncProcessCrash* ret = new (ELeave) CAsyncProcessCrash(aProcessCrashWrapper);
+	CleanupStack::PushL(ret);
+	ret->ConstructL();
+	CleanupStack::Pop(ret);
+	return ret;
+	}
+
+/**
+ * Safe construction
+ * @leave
+ */
+void CAsyncProcessCrash::ConstructL()
+	{
+	}
+
+/*
+ * Constructor for the CActive derived object
+ */
+CAsyncProcessCrash::CAsyncProcessCrash(CProcessCrashWrapper* aProcessCrashWrapper)
+	: CActive(CActive::EPriorityStandard),
+	  iProcessCrashWrapper(aProcessCrashWrapper),
+	  iCrashId(0)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+/*
+ * Function that issues request to the Core Dump Server
+ * @param aCrashId is the crash id
+ * to process crash log
+ */
+void CAsyncProcessCrash::IssueProcessCrashRequest(TUint aCrashId)
+	{
+	RDebug::Printf("CAsyncProcessCrash::IssueProcessCrashRequest");
+
+	iCrashId = aCrashId;
+
+	ASSERT(!IsActive());
+
+	// Actually issue the request
+	iProcessCrashWrapper->iCoreDumpSession.ProcessCrashLog( iCrashId, iStatus);
+
+	// Tell the framework that a request is pending but
+	// do it after the async request in case it Leaves
+	SetActive();
+	}
+
+/*
+ * RunL from CActive when the asynchronous request completes
+ *
+ */
+void CAsyncProcessCrash::RunL()
+	{
+	RDebug::Printf("CAsyncProcessCrash::RunL %d", iStatus.Int());
+	// that errors are handled in RunError()
+	User::LeaveIfError(iStatus.Int());
+
+	// request-handling code
+  	iProcessCrashWrapper->ProcessSELFFileCreatedL();
+
+  	CActiveScheduler::Stop();
+	}
+
+/*
+ * RunError from CActive called when RunL leaves
+ */
+TInt CAsyncProcessCrash::RunError(TInt aError)
+	{
+	RDebug::Printf("CAsyncProcessCrash::RunError");
+
+	iProcessCrashWrapper->PrintErrorCondition(aError);
+
+	CActiveScheduler::Stop();
+
+	return KErrNone; // error handled
+	}
+
+/*
+ * Destructor for clean up purposes
+ */
+CAsyncProcessCrash::~CAsyncProcessCrash()
+	{
+	RDebug::Printf("CAsyncProcessCrash::~CAsyncProcessCrash");
+	//cancel any outstanding request
+	Cancel();
+
+	}
+
+/*
+ * Destructor for clean up purposes
+ */
+void CAsyncProcessCrash::DoCancel()
+	{
+	RDebug::Printf("CAsyncProcessCrash::DoCancel");
+	//cancel the processing the crashlog
+	iProcessCrashWrapper->iCoreDumpSession.CancelProcessCrashLog(iCrashId);
+	}
+
+//eof