crashanalysercmd/Libraries/Engine/CrashItemLib/Crash/Summarisable/CISummarisableEntity.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/Libraries/Engine/CrashItemLib/Crash/Summarisable/CISummarisableEntity.cs Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,307 @@
+/*
+* 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.Processes;
+using CrashItemLib.Crash.Registers;
+using CrashItemLib.Crash.Stacks;
+using CrashItemLib.Crash.CodeSegs;
+using CrashItemLib.Crash.Threads;
+using CrashItemLib.Crash.Messages;
+using SymbianStructuresLib.Arm.Registers;
+
+namespace CrashItemLib.Crash.Summarisable
+{
+ public class CISummarisableEntity : CIElement
+ {
+ #region Enumerations
+ public enum TContext
+ {
+ /// <summary>
+ /// A thread-specific entity, the normal case when the crash occurs within a Symbian
+ /// OS kernel or user side thread context.
+ /// </summary>
+ EContextTypeThread = 0,
+
+ /// <summary>
+ /// An exception mode entity. For example, an object that represents the associated
+ /// stack et al for an IRQ handler or FIQ handler crash.
+ /// </summary>
+ EContextTypeException
+ }
+
+ public enum TElement
+ {
+ EElementThread = 0,
+ EElementProcess,
+ EElementCodeSegments,
+ EElementStack,
+ EElementRegisters
+ }
+ #endregion
+
+ #region Constructors
+ /// <summary>
+ /// Preferred constructor that is called by CISummarisableEntityList during finalization.
+ /// This constructor is used to create a summary wrapper for any stack-level objects that
+ /// were created during container preparation. Those stack objects may be stand-alone exception
+ /// mode stacks (IRQ, FIQ, ABT, UND et al) or then they may be associated with a specific
+ /// Symbian OS thread (user or supervisor).
+ /// </summary>
+ /// <param name="aStack"></param>
+ internal CISummarisableEntity( CIStack aStack )
+ : base( aStack.Container )
+ {
+ // NB: If the stack has an associated register list,
+ // and the register list's owner is a thread, then we
+ // automatically know we're dealing with a thread-based stack.
+ AddChild( aStack );
+ }
+
+ /// <summary>
+ /// Fall back constructor which is called when the thread in question has no associated
+ /// stack. This means that stack data is unavailable and therefore stack reconstruction is
+ /// obviously impossible. However, the thread (and by implication the process) may well still
+ /// contain useful information.
+ /// </summary>
+ /// <param name="aThread"></param>
+ internal CISummarisableEntity( CIThread aThread )
+ : base( aThread.Container )
+ {
+ AddChild( aThread );
+ }
+ #endregion
+
+ #region API
+ public bool IsAvailable( TElement aElement )
+ {
+ bool ret = false;
+ //
+ switch ( aElement )
+ {
+ case TElement.EElementThread:
+ ret = ( Thread != null );
+ break;
+ case TElement.EElementProcess:
+ ret = ( Process != null );
+ break;
+ case TElement.EElementCodeSegments:
+ ret = ( CodeSegments != null );
+ break;
+ case TElement.EElementStack:
+ ret = ( Stack != null );
+ break;
+ case TElement.EElementRegisters:
+ ret = ( Registers != null );
+ break;
+ }
+ //
+ return ret;
+ }
+
+ public CIMessageDictionary GetMessages()
+ {
+ CIElementList<CIMessage> list = base.ChildrenByType<CIMessage>( TChildSearchType.EEntireHierarchy );
+ CIMessageDictionary ret = new CIMessageDictionary( list );
+ return ret;
+ }
+ #endregion
+
+ #region Properties
+ public TContext Context
+ {
+ get
+ {
+ TContext ret = TContext.EContextTypeException;
+ //
+ if ( IsAvailable( TElement.EElementThread ) )
+ {
+ ret = TContext.EContextTypeThread;
+ }
+ //
+ return ret;
+ }
+ }
+
+ public bool IsAbnormalTermination
+ {
+ get
+ {
+ // A crash can be an exception stack (i.e. without a thread)
+ // or then a thread that has panics/crashed in some way.
+ bool ret = false;
+ //
+ if ( IsAvailable( TElement.EElementThread ) )
+ {
+ ret = Thread.IsAbnormalTermination;
+ }
+ else if ( IsAvailable( TElement.EElementStack ) )
+ {
+ // All stand-alone stacks are treated as crashes.
+ ret = true;
+ }
+ //
+ return ret;
+ }
+ }
+
+ public CIThread Thread
+ {
+ get
+ {
+ CIThread ret = null;
+
+ // Use the stack object to find associated thread.
+ CIStack stack = this.Stack;
+ if ( stack != null )
+ {
+ ret = stack.OwningThread;
+ }
+
+ // Did we find a thread? If not, fall back to trying our children.
+ if ( ret == null )
+ {
+ // Register set unavailable - check child nodes for
+ // presence of thread object. Implies no stack data for
+ // this summary wrapper object.
+ ret = base.ChildByType( typeof( CIThread ) ) as CIThread;
+ }
+ //
+ return ret;
+ }
+ }
+
+ public CIProcess Process
+ {
+ get
+ {
+ CIProcess ret = null;
+ //
+ if ( Thread != null )
+ {
+ ret = Thread.OwningProcess;
+ }
+ //
+ return ret;
+ }
+ }
+
+ public CICodeSegList CodeSegments
+ {
+ get
+ {
+ CICodeSegList ret = null;
+ //
+ CIProcess process = this.Process;
+ if ( process != null )
+ {
+ ret = process.CodeSegments;
+ }
+ //
+ return ret;
+ }
+ }
+
+ public CIRegisterList Registers
+ {
+ get
+ {
+ CIRegisterList ret = null;
+ //
+ CIStack stack = this.Stack;
+ if ( stack != null )
+ {
+ // Use registers associated with stack
+ ret = stack.Registers;
+ }
+ else
+ {
+ // No stack, if we have a thread then try to
+ // find the thread register list that is current.
+ CIThread thread = this.Thread;
+ if ( thread != null )
+ {
+ ret = thread.CurrentProcessorModeRegisters;
+ }
+ }
+ //
+ return ret;
+ }
+ }
+
+ public CIStack Stack
+ {
+ get
+ {
+ // Might return null
+ CIStack ret = base.ChildByType( typeof( CIStack ) ) as CIStack;
+ return ret;
+ }
+ }
+
+ public TArmRegisterBank Bank
+ {
+ get
+ {
+ TArmRegisterBank ret = TArmRegisterBank.ETypeUnknown;
+ //
+ if ( IsAvailable( TElement.EElementStack ) )
+ {
+ ret = Stack.Type;
+ }
+ //
+ return ret;
+ }
+ }
+
+ public override string Name
+ {
+ get
+ {
+ StringBuilder ret = new StringBuilder();
+ //
+ if ( IsAvailable( TElement.EElementThread ) )
+ {
+ // Just use thread name
+ ret.Append( Thread.FullName );
+ }
+ else if ( IsAvailable( TElement.EElementStack ) )
+ {
+ // Get associated bank type
+ TArmRegisterBank bank = Stack.Registers.Bank;
+ string type = ArmRegisterBankUtils.BankAsStringLong( bank );
+ ret.AppendFormat( "{0} mode", type );
+ }
+ //
+ return ret.ToString();
+ }
+ set
+ {
+ }
+ }
+ #endregion
+
+ #region Internal methods
+ #endregion
+
+ #region Data members
+ #endregion
+ }
+}