kernel/eka/debug/crashMonitor/src/crashlogwalker.cpp
changeset 296 94f2adf59133
parent 293 0659d0e1a03c
child 297 b2826f67641f
--- a/kernel/eka/debug/crashMonitor/src/crashlogwalker.cpp	Wed Oct 20 13:58:28 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,535 +0,0 @@
-// 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 the License "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:
-// e32\debug\crashMonitor\src\crashlogwalker.cpp
-// Class to allow us to traverse the crash log generated by System Crash Monitor
-// 
-//
-
-/**
- @file
- @internalTechnology
-*/
-
-#ifndef __KERNEL_MODE__
-#include <e32std.h>
-#include <e32std_private.h> 
-#include <e32base.h>
-#include <e32base_private.h> 
-#endif
-
-#include "scmtrace.h"
-#include "crashlogwalker.h"
-
-namespace Debug
-	{	
-	/**
-	 * Constructor for log walker
-	 * @param aBuffer The buffer containing the crash data
-	 */
-	TCrashLogWalker::TCrashLogWalker(TDesC8& aBuffer) : 
-		iBuffer(aBuffer),
-		iReader(const_cast<TUint8*>(iBuffer.Ptr()))
-		{
-		}
-	
-	/**
-	 * This reads in the crash header from the buffer from the given start point
-	 * @param aStartPoint Point to begin reading in buffer
-	 * @return One of the OS wide codes
-	 */
-	TInt TCrashLogWalker::ReadLogHeader(const TInt aStartPoint)
-		{		
-		iReader.SetPosition(aStartPoint);
-		
-		TInt err = iCrashHeader.Deserialize(iReader);
-		if(err != KErrNone)
-			{
-			CLTRACE("(TCrashLogWalker::ReadLogHeader) - failed to read crash header");
-			return KErrCorrupt;
-			}
-		
-		err = iOffsets.Deserialize(iReader);
-		if(err != KErrNone)
-			{
-			CLTRACE("(TCrashLogWalker::ReadLogHeader) - failed to read offsets");
-			return KErrCorrupt;
-			}
-		
-		TRegisterSet set;
-		err = set.Deserialize(iReader);
-		if(err != KErrNone)
-			{
-			CLTRACE("(TCrashLogWalker::ReadLogHeader) - failed to read register set");
-			return KErrCorrupt;
-			}
-		
-		for(TInt cnt = 0; cnt < set.iNumRegisters; cnt++)
-			{
-			TRegisterValue val;
-			err = val.Deserialize(iReader);
-			if(err != KErrNone)
-				{
-				CLTRACE1("(TCrashLogWalker::ReadLogHeader) - failed to read TRegisterValue cnt = %d", cnt);
-				return KErrCorrupt;
-				}
-						
-			HelpAssignRegisterToContext(val);
-			}
-		
-		return VerifyHeader();
-		}
-	
-	/**
-	 * Getter for the crash context - This is the CPU register set at the time of crash
-	 * @return Crash Context
-	 */
-	const TRmdArmExcInfo& TCrashLogWalker::GetCrashContext() const
-		{
-		return iContext;
-		}
-	
-	/**
-	 * Returns the crash size for the crash that has just been read, provided the
-	 * reading of the header was succesful. 
-	 * @see ReadLogHeader
-	 * @return Crash Log size
-	 */
-	TInt TCrashLogWalker::GetCrashSize() const
-		{
-		return iCrashHeader.iLogSize;
-		}
-	
-	/**
-	 * Returns the crash ID for the crash that has just been read, provided the
-	 * reading of the header was succesful. 
-	 * @see ReadLogHeader
-	 * @return Crash Log ID
-	 */
-	TInt TCrashLogWalker::GetCrashId() const
-		{
-		return iCrashHeader.iCrashId;
-		}
-	
-	/**
-	 * Looks at the member crash log header and checks that it is valid.
-	 * @see ReadLogHeader 
-	 * @return one of the OS wide codes
-	 */
-	TInt TCrashLogWalker::VerifyHeader()
-		{
-		if(iCrashHeader.iId == ESCMTCrashInfo)
-			{			
-			CLTRACE("TCrashLogWalker::VerifyHeader() OK");
-			return KErrNone;
-			}
-		else
-			{
-			CLTRACE("TCrashLogWalker::VerifyHeader() FAILED");
-			return KErrCorrupt;
-			}
-		}
-	
-	/**
-	 * Updates the buffer being used by the crash walker and resets reader to use 
-	 * the beginning of this
-	 * @param aBuffer New buffer
-	 */
-	void TCrashLogWalker::UpdateBuffer(TDesC8& aBuffer)
-		{
-		iBuffer = aBuffer;		
-		
-		//Read from start of this buffer		
-		iReader = TByteStreamReader(const_cast<TUint8*>(aBuffer.Ptr()));
-		}
-	
-#ifndef __KERNEL_MODE__
-	/**
-	 * Gets the next data type from the buffer. If this is NULL it means the buffer was too small.
-	 * Call again with a larger buffer. It assumes the buffer contains valid data and leaves with KErrCorrupt 
-	 * if it isnt. Note for raw data types, the data will be empty. This should be read with GetRawDataTypeL after reseting the reader to the 
-	 * correct position. If you just want to skip a raw data type, move the buffer along the size of (contained in the returned struct)
-	 * 
-	 * @see GetRawDataTypeL
-	 * @see UpdateBuffer
-	 * @param aPos Next position that will be read. If we return NULL, this is the position the next buffer should
-	 * 			begin from
-	 * @param aId ID of the MByteStreamSerializable returned	 
-	 * @param buffer size to be used the next time. Unchanged if the current buffer is ok
-	 * @return MByteStreamSerializable pointer. Ownership is passed to caller. NULL if failed
-	 * @leave KErrCorrupt if the buffer cant be read
-	 */
-	MByteStreamSerializable* TCrashLogWalker::GetNextDataTypeL(TInt& aPos, SCMStructId& aId, TInt& aBufferSize)
-		{
-		MByteStreamSerializable* data = NULL;
-		
-		TInt roomInBuffer = iBuffer.Length() - iReader.CurrentPosition();
-		//make sure we have at LEAST 4 bytes in the buffer
-		if(roomInBuffer < (TInt)(sizeof(TInt)))
-			{
-			aBufferSize = sizeof(TInt);
-			return NULL;
-			}
-		
-		//this stores the required size in which to deserialize a structure - to make sure 
-		//there is room in the buffer
-		TInt maxSize = 0;
-		aPos = iReader.CurrentPosition();
-		aBufferSize = iBuffer.Length();		
-		
-		//all these data types are defined by their first byte
-		aId = (SCMStructId)iBuffer.Ptr()[iReader.CurrentPosition()];		
-		
-		//ensure we have a valid structure found
-		if(aId <= 0 || aId >= ESCMLast)
-			{
-			//oddness is afoot and the mist of corruption reigns thick
-			User::Leave(KErrCorrupt);
-			}					
-		
-		switch(aId)
-			{
-			case ESCMOffsetsHeader:
-				{
-				data = new TCrashOffsetsHeader();	
-				maxSize = TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize;
-				break;
-				}
-			case ESCMTCrashInfo:
-				{
-				data = new TCrashInfoHeader();
-				maxSize = TCrashInfoHeader::KSCMCrashInfoMaxSize;
-				break;
-				}
-			case ESCMProcessData:
-				{
-				data = new TProcessData();
-				maxSize = TProcessData::KSCMProcessDataMaxSize;
-				break;
-				}
-			case ESCMThreadData:
-				{
-				data = new TThreadData();
-				maxSize = TThreadData::KSCMThreadDataMaxSize;
-				break;
-				}
-			case ESCMThreadStack:
-				{
-				data = new TThreadStack();
-				maxSize = TThreadStack::KSCMThreadStackMaxSize;
-				break;
-				}
-			case ESCMRegisterValue:
-				{
-				data = new TRegisterValue();
-				maxSize = TRegisterValue::KSCMRegisterValueMaxSize;
-				break;
-				}
-			case ESCMRegisterSet:
-				{
-				data = new TRegisterSet();
-				maxSize = TRegisterSet::KSCMRegisterSetMaxSize;
-				break;
-				}
-			case ESCMMemory:
-				{
-				data = new TMemoryDump();
-				maxSize = TMemoryDump::KSCMMemDumpMaxSize;
-				break;
-				}
-			case ESCMCodeSegSet:
-				{
-				data = new TCodeSegmentSet();
-				maxSize = TCodeSegmentSet::KSCMCodeSegSetMaxSize;
-				break;
-				}
-			case ESCMCodeSeg:
-				{
-				data = new TCodeSegment();
-				maxSize = TCodeSegment::KMaxSegmentNameSize;
-				break;
-				}	
-			case ESCMLocks:
-				{
-				data = new TSCMLockData();
-				maxSize = TSCMLockData::KSCMLockDataMaxSize;	
-				break;
-				}
-			case ESCMVariantData:
-				{
-				data = new TVariantSpecificData();
-				maxSize = TVariantSpecificData::KSCMVarSpecMaxSize;	
-				break;
-				}				
-			case ESCMRomHeader:
-				{
-				data = new TRomHeaderData();
-				maxSize = TRomHeaderData::KSCMRomHdrMaxSize;	
-				break;
-				}				
-			case ESCMRawData:
-				{
-				data = new TRawData();
-				
-				//This is a special case. The data in here can be any length, so we need to deserialise it
-				//to find this length out. The MAX_SIZE of this class is the max size minus data
-				//which is fine if we dont assign the TPtr8.				
-				if(TRawData::KSCMRawDataMaxSize > roomInBuffer )
-					{					
-					aBufferSize = (maxSize > aBufferSize) ? maxSize : aBufferSize;
-					
-					if(data)
-						delete data;
-					
-					return NULL;
-					}
-				else
-					{
-					data->Deserialize(iReader);
-					maxSize = data->GetSize();
-					
-					aPos = iReader.CurrentPosition();
-					return data;
-					}
-				}
-			case ESCMTraceData:
-				{
-				data = new TTraceDump();
-				maxSize = TTraceDump::KSCMTraceDumpMaxSize;
-				break;
-				}
-			default :
-				{
-				User::Panic(_L("Unexpected Null. Unrecognised Data type from crash log."), KErrGeneral); //Programming error				
-				}							
-			}
-		
-		__ASSERT_ALWAYS((data != NULL), User::Panic(_L("Unexpected Null"), KErrGeneral));
-		
-		if(maxSize > roomInBuffer )
-			{
-			//Not enough room in buffer to read this. Tell caller where in the current buffer
-			//we were via aPos, and what minimum size buffer should be used next time to allow reading
-			aBufferSize = maxSize;
-			if(data)
-				{
-				delete data;
-				}
-			
-			return NULL;
-			}
-		
-		if(!data)
-			{
-			CLTRACE("Unable to create data structure");
-			User::Leave(KErrAbort);
-			}
-		
-		data->Deserialize(iReader);			
-		aPos = iReader.CurrentPosition();
-		
-		return data;
-		}
-	
-	/**
-	 * Assuming the next type in the buffer is a TRawData type, this will return the TRawData
-	 * types data pointer pointing to the buffer passed via aRawBuf.
-	 *  
-	 * The difference between this call and GetNextDataTypeL is that GetNextDataTypeL only lets you move along the buffer
-	 * it doesnt allow you to specify a buffer in which to store the raw data.
-	 * 
-	 * @see GetNextDataTypeL
-	 * @return TRawData* This is the TRawData object that holds the data via the buffer passed in. Ownership is passed to the caller
-	 * @param aPos position in buffer its been found. If we return NULL, this is the position the next buffer should
-	 * 			begin from
-	 * @param aBufferSize Should we return NULL, that means the descriptor passed in was not big enough and should be of at least aBufferSize bytes
-	 * @param aRawBuf The buffer to store the data refered to by the TRawData returned
-	 * @param aStartRawPosition The point in the raw data at which we will start to put it into the buffer
-	 * @leave One of the OS wide codes
-	 */
-	TRawData* TCrashLogWalker::GetRawDataTypeL(TInt& aPos, TInt& aBufferSize, TDes8& aRawBuf, TInt aStartRawPosition)
-		{								
-		//make sure we have at LEAST the size of the struct in the buffer
-		if(iBuffer.Length() < TRawData::KSCMRawDataMaxSize)
-			{
-			aBufferSize = TRawData::KSCMRawDataMaxSize;
-			return NULL;
-			}
-		
-		//this stores the required size in which to deserialize a structure - to make sure 
-		//there is room in the buffer
-		aPos = iReader.CurrentPosition();
-		aBufferSize = iBuffer.Length();
-		
-		//all these data types are defined by their first byte
-		TInt id = (SCMStructId)iBuffer.Ptr()[iReader.CurrentPosition()];
-		if(id != ESCMRawData)
-			{
-			User::Leave(KErrCorrupt);
-			}		
-		
-		//Deserialise once to get the length (this will ignore the data in the absence of a Tptr)
-		TRawData* data = new TRawData();
-		data->Deserialize(iReader);
-		
-		//reset reader to where the raw data starts again
-		iReader.SetPosition(aPos);
-		
-		//now we know we have room, deserialize into this descriptor	
-		aRawBuf.SetMax();	
-		data->iData.Set(aRawBuf.MidTPtr(0));
-		User::LeaveIfError(data->Deserialize(aStartRawPosition, iReader));
-		
-		return data;
-		}
-	
-#endif
-	
-	/**
-	 * This is a helper function to convert between the two formats of register
-	 * @param aRegVal Resulting register values
-	 */
-	void TCrashLogWalker::HelpAssignRegisterToContext(const TRegisterValue& aRegVal)
-		{
-		//only interested in core registers at the moment
-		if(aRegVal.iClass != 0 || aRegVal.iSize != 2)
-			{
-			return;
-			}
-		
-		//Is there a cleverer way to do this with bitmasks and FOFF ?
-		switch(aRegVal.iType)
-			{
-			case 0x0 :
-				{
-				iContext.iR0 = aRegVal.iValue32;
-				break;
-				}
-			case 0x100 :
-				{
-				iContext.iR1 = aRegVal.iValue32;
-				break;
-				}
-			case 0x200 :
-				{
-				iContext.iR2 = aRegVal.iValue32;
-				break;
-				}
-			case 0x300 :
-				{
-				iContext.iR3 = aRegVal.iValue32;
-				break;
-				}
-			case 0x400 :
-				{
-				iContext.iR4 = aRegVal.iValue32;
-				break;
-				}
-			case 0x500 :
-				{
-				iContext.iR5 = aRegVal.iValue32;
-				break;
-				}
-			case 0x600 :
-				{
-				iContext.iR6 = aRegVal.iValue32;
-				break;
-				}
-			case 0x700 :
-				{
-				iContext.iR7 = aRegVal.iValue32;
-				break;
-				}
-			case 0x800 :
-				{
-				iContext.iR8 = aRegVal.iValue32;
-				break;
-				}
-			case 0x900 :
-				{
-				iContext.iR9 = aRegVal.iValue32;
-				break;
-				}
-			case 0xa00 :
-				{
-				iContext.iR10 = aRegVal.iValue32;
-				break;
-				}
-			case 0xb00 :
-				{
-				iContext.iR11 = aRegVal.iValue32;
-				break;
-				}
-			case 0xc00 :
-				{
-				iContext.iR12 = aRegVal.iValue32;
-				break;
-				}
-			case 0xd00 :
-				{
-				iContext.iR13 = aRegVal.iValue32;				
-				break;
-				}
-			case 0xe00 :
-				{
-				iContext.iR14 = aRegVal.iValue32;
-				break;
-				}
-			case 0xf00 :
-				{
-				iContext.iR15 = aRegVal.iValue32;
-				break;
-				}
-			case 0x1000 :
-				{
-				iContext.iCpsr = aRegVal.iValue32;
-				break;
-				}
-			case 0x1100 :
-				{
-				iContext.iR13Svc = aRegVal.iValue32;
-				break;
-				}
-			case 0x1200 :
-				{
-				iContext.iR14Svc = aRegVal.iValue32;
-				break;
-				}
-			default :
-				{
-				return;
-				}				
-			}
-		}
-	
-	/**
-	 * Getter for crash header
-	 * @return header
-	 */
-	const TCrashInfoHeader& TCrashLogWalker::GetCrashHeader() const
-		{
-		return iCrashHeader;
-		}
-	
-	/**
-	 * Getter for crash offsets header
-	 * @return header
-	 */
-	const TCrashOffsetsHeader& TCrashLogWalker::GetOffsetsHeader() const
-		{
-		return iOffsets;
-		}			
-		
-	}
-//eof
-