--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/Libraries/Engine/CrashItemLib/Crash/ExitInfo/CIExitInfo.cs Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,396 @@
+/*
+* Copyright (c) 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:
+*
+*/
+using System;
+using System.Text;
+using System.Collections.Generic;
+using CrashItemLib.Crash;
+using CrashItemLib.Crash.Base;
+using CrashItemLib.Crash.Base.DataBinding;
+using CrashItemLib.Crash.Container;
+using CrashItemLib.Crash.Threads;
+using CrashItemLib.Crash.Processes;
+using CrashItemLib.Crash.Registers;
+using CrashItemLib.Crash.Registers.Special;
+using SymbianUtils.Range;
+using SymbianUtils.Enum;
+using SymbianStructuresLib.Uids;
+using SymbianUtils.DataBuffer;
+using SymbianStructuresLib.Arm.Registers;
+
+namespace CrashItemLib.Crash.ExitInfo
+{
+ [CIDBAttributeColumn( "Name", 0 )]
+ [CIDBAttributeColumn( "Value", 1, true )]
+ public class CIExitInfo : CIElement
+ {
+ #region Enumerations
+ public enum TExitType
+ {
+ EExitTypePending = 0,
+ EExitTypeKill,
+ EExitTypePanic,
+ EExitTypeTerminate,
+ EExitTypeException
+ }
+ #endregion
+
+ #region Constructors
+ public CIExitInfo( CIElement aParent )
+ : base( aParent.Container, aParent )
+ {
+ }
+ #endregion
+
+ #region API
+ #endregion
+
+ #region Properties
+ public TExitType Type
+ {
+ get
+ {
+ TExitType ret = iType;
+ //
+ if ( !iTypeWasExplicitlySet && OwningThread != null )
+ {
+ // A client did not specify an explict exit reason, so in this case
+ // we'll try to work out if we're dealing with an exception based upon
+ // register values.
+ //
+ // We can only do this if the owning object is available.
+ CIThread thread = OwningThread;
+ CIThreadRegisterListCollection regs = thread.Registers;
+ if ( thread.Registers.Contains( TArmRegisterBank.ETypeException ) )
+ {
+ // Best guess
+ ret = TExitType.EExitTypeException;
+ }
+ }
+ //
+ return iType;
+ }
+ set
+ {
+ iTypeWasExplicitlySet = true;
+ iType = value;
+ }
+ }
+
+ public string TypeDescription
+ {
+ get
+ {
+ switch( Type )
+ {
+ case TExitType.EExitTypeException:
+ return "Exception";
+ case TExitType.EExitTypePending:
+ return "Pending";
+ case TExitType.EExitTypePanic:
+ return "Panic";
+ case TExitType.EExitTypeTerminate:
+ return "Terminate";
+ case TExitType.EExitTypeKill:
+ return "Kill";
+ default:
+ return "Unknown";
+ }
+ }
+ }
+
+ public bool IsAbnormalTermination
+ {
+ get
+ {
+ bool ret = false;
+ //
+ switch ( Type )
+ {
+ case TExitType.EExitTypeException:
+ case TExitType.EExitTypePanic:
+ case TExitType.EExitTypeTerminate:
+ ret = true;
+ break;
+ default:
+ case TExitType.EExitTypeKill:
+ case TExitType.EExitTypePending:
+ break;
+ }
+ //
+ return ret;
+ }
+ }
+
+ public string Category
+ {
+ get
+ {
+ string ret = iCategory;
+ //
+ if ( Type == TExitType.EExitTypeException )
+ {
+ CIRegisterExcCode code = RegisterExcCode;
+ if ( code != null )
+ {
+ ret = EnumUtils.ToString( ExceptionCode );
+ }
+ }
+ //
+ return ret;
+ }
+ set { iCategory = value; }
+ }
+
+ public int Reason
+ {
+ get
+ {
+ int ret = iReason;
+ //
+ if ( Type == TExitType.EExitTypeException )
+ {
+ ret = (int) ExceptionCode;
+ }
+ //
+ return ret;
+ }
+ set { iReason = value; }
+ }
+
+ public CIRegisterFSR RegisterFSR
+ {
+ get
+ {
+ CIRegisterFSR ret = null;
+ //
+ CIRegisterList list = RegListCoProcessor;
+ if ( list != null && list.Contains( TArmRegisterType.EArmReg_FSR ) )
+ {
+ CIRegister reg = list[ TArmRegisterType.EArmReg_FSR ];
+ ret = reg as CIRegisterFSR;
+ }
+ //
+ return ret;
+ }
+ }
+
+ public CIRegisterExcCode RegisterExcCode
+ {
+ get
+ {
+ CIRegisterExcCode ret = null;
+ //
+ CIRegisterList list = RegListException;
+ if ( list != null && list.Contains( TArmRegisterType.EArmReg_EXCCODE ) )
+ {
+ CIRegister reg = list[ TArmRegisterType.EArmReg_EXCCODE ];
+ ret = reg as CIRegisterExcCode;
+ }
+ //
+ return ret;
+ }
+ }
+
+ public CIRegisterExcCode.TExceptionCode ExceptionCode
+ {
+ get
+ {
+ if ( Type != TExitType.EExitTypeException )
+ {
+ throw new InvalidOperationException();
+ }
+
+ CIRegisterExcCode.TExceptionCode code = CIRegisterExcCode.TExceptionCode.EExceptionCodeUnknown;
+ CIRegisterExcCode excCode = RegisterExcCode;
+ //
+ if ( excCode != null )
+ {
+ code = excCode;
+ }
+ //
+ return code;
+ }
+ }
+
+ public string ExceptionDescription
+ {
+ get
+ {
+ string ret = string.Empty;
+ //
+ if ( Type == TExitType.EExitTypeException )
+ {
+ CIRegisterExcCode reg = RegisterExcCode;
+ if ( reg != null )
+ {
+ ret = reg.ExceptionCodeDescription;
+ }
+ }
+ //
+ return ret;
+ }
+ }
+
+ public CIThread OwningThread
+ {
+ get { return base.Parent as CIThread; }
+ }
+
+ public CIProcess OwningProcess
+ {
+ get
+ {
+ CIProcess ret = base.Parent as CIProcess;
+ //
+ if ( ret == null && OwningThread != null )
+ {
+ ret = OwningThread.OwningProcess;
+ }
+ //
+ return ret;
+ }
+ }
+ #endregion
+
+ #region Internal methods
+ private CIRegisterList RegListException
+ {
+ get
+ {
+ System.Diagnostics.Debug.Assert( OwningThread != null );
+ //
+ CIThread thread = (CIThread) OwningThread;
+ CIThreadRegisterListCollection registers = thread.Registers;
+ //
+ if ( registers.Contains( TArmRegisterBank.ETypeException ) )
+ {
+ CIRegisterList list = registers[ TArmRegisterBank.ETypeException ];
+ return list;
+ }
+ //
+ return null;
+ }
+ }
+
+ private CIRegisterList RegListCoProcessor
+ {
+ get
+ {
+ System.Diagnostics.Debug.Assert( OwningThread != null );
+ //
+ CIThread thread = (CIThread) OwningThread;
+ CIThreadRegisterListCollection registers = thread.Registers;
+ //
+ if ( registers.Contains( TArmRegisterBank.ETypeCoProcessor ) )
+ {
+ CIRegisterList list = registers[ TArmRegisterBank.ETypeCoProcessor ];
+ return list;
+ }
+ //
+ return null;
+ }
+ }
+ #endregion
+
+ #region From CIElement
+ public override void PrepareRows()
+ {
+ DataBindingModel.ClearRows();
+
+ // Type is common
+ CIDBRow rowType= new CIDBRow();
+ rowType.Add( new CIDBCell( "Type" ) );
+ rowType.Add( new CIDBCell( TypeDescription ) );
+ DataBindingModel.Add( rowType );
+
+ // We must prepare them by hand because we show
+ // different content depending on the type of exit.
+ if ( Type == TExitType.EExitTypePending )
+ {
+ // Nothing to add
+ }
+ else if ( Type == TExitType.EExitTypeException )
+ {
+ string code = ExceptionDescription;
+ if ( code != string.Empty )
+ {
+ CIDBRow rowExcCode = new CIDBRow();
+ rowExcCode.Add( new CIDBCell( "Exception Code" ) );
+ rowExcCode.Add( new CIDBCell( code ) );
+ DataBindingModel.Add( rowExcCode );
+ }
+
+ CIRegisterFSR fsr = RegisterFSR;
+ if ( fsr != null )
+ {
+ CIDBRow rowFSR = new CIDBRow();
+ rowFSR.Add( new CIDBCell( "Fault Type" ) );
+ rowFSR.Add( new CIDBCell( fsr.FaultDescription ) );
+ DataBindingModel.Add( rowFSR );
+ }
+ }
+ else
+ {
+ // Panic, terminate
+ CIDBRow rowCategory = new CIDBRow();
+ rowCategory.Add( new CIDBCell( "Category" ) );
+ rowCategory.Add( new CIDBCell( Category ) );
+ DataBindingModel.Add( rowCategory );
+
+ CIDBRow rowReason = new CIDBRow();
+ rowReason.Add( new CIDBCell( "Reason" ) );
+ rowReason.Add( new CIDBCell( Reason.ToString() ) );
+ DataBindingModel.Add( rowReason );
+
+ CIDBRow rowFullPanic = new CIDBRow();
+ rowFullPanic.Add( new CIDBCell( "In Full" ) );
+ rowFullPanic.Add( new CIDBCell( string.Format( "{0}-{1}", Category, Reason ) ) );
+ DataBindingModel.Add( rowFullPanic );
+ }
+ }
+ #endregion
+
+ #region From System.Object
+ public override string ToString()
+ {
+ StringBuilder ret = new StringBuilder();
+ //
+ if ( Type == TExitType.EExitTypePending )
+ {
+ ret.Append( "Pending" );
+ }
+ else if ( Type == TExitType.EExitTypeException )
+ {
+ ret.Append( "Exception" );
+ }
+ else
+ {
+ ret.AppendFormat( "{0}-{1}", Category, Reason );
+ }
+ //
+ return ret.ToString();
+ }
+ #endregion
+
+ #region Data members
+ private int iReason = 0;
+ private string iCategory = string.Empty;
+ private bool iTypeWasExplicitlySet = false;
+ private TExitType iType = TExitType.EExitTypePending;
+ #endregion
+ }
+}