--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/Libraries/Engine/CrashDebuggerLib/Structures/Thread/DThread.cs Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,353 @@
+/*
+* Copyright (c) 2004-2008 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.Collections.Generic;
+using System.Text;
+using CrashDebuggerLib.Structures.Common;
+using CrashDebuggerLib.Structures.KernelObjects;
+using CrashDebuggerLib.Structures.Process;
+using CrashDebuggerLib.Structures.NThread;
+using SymbianStructuresLib.Debug.Symbols;
+
+namespace CrashDebuggerLib.Structures.Thread
+{
+ public class DThread : DObject
+ {
+ #region Enumerations
+ [System.ComponentModel.TypeConverter( typeof( SymbianParserLib.TypeConverters.SymbianEnumConverter ) )]
+ public enum TThreadState
+ {
+ EUnknown = -1,
+ ECreated = 0,
+ EDead,
+ EReady,
+ EWaitSemaphore,
+ EWaitSemaphoreSuspended,
+ EWaitMutex,
+ EWaitMutexSuspended,
+ EHoldMutexPending,
+ EWaitCondVar,
+ EWaitCondVarSuspended,
+ }
+
+ [Flags, System.ComponentModel.TypeConverter( typeof( SymbianParserLib.TypeConverters.SymbianEnumConverter ) )]
+ public enum TThreadFlags
+ {
+ EThreadFlagNone = 0x00000000,
+ EThreadFlagProcessCritical = 0x00000001, // thread panic panics process
+ EThreadFlagProcessPermanent = 0x00000002, // thread exit of any kind causes process to exit (=main)
+ EThreadFlagSystemCritical = 0x00000004, // thread panic reboots entire system
+ EThreadFlagSystemPermanent = 0x00000008, // thread exit of any kind reboots entire system
+ EThreadFlagOriginal = 0x00000010,
+ EThreadFlagLastChance = 0x00000020,
+ EThreadFlagRealtime = 0x00000040, // thread will be panicked when using some non-realtime functions
+ EThreadFlagRealtimeTest = 0x00000080 // non-realtime functions only warn rather than panic
+ }
+
+ public enum TThreadWaitType
+ {
+ EThreadWaitingUnknown = 0,
+ EThreadWaitingReady,
+ EThreadWaitingOnSemaphore,
+ EThreadWaitingOnMutex,
+ EThreadWaitingOnDfc,
+ EThreadWaitingOnResumption,
+ EThreadWaitingOnRequestSemaphore,
+ EThreadWaitingOnRequestSemaphoreInsideSchedulerWaitLoop
+ }
+ #endregion
+
+ #region Constructors
+ public DThread( CrashDebuggerInfo aCrashDebugger )
+ : base( aCrashDebugger, TObjectType.EThread )
+ {
+ iNThread = new CrashDebuggerLib.Structures.NThread.NThread( aCrashDebugger, this );
+ iStackInfoSupervisor = new ThreadStackInfo( aCrashDebugger, this, ThreadStackInfo.TType.ETypeSupervisor );
+ iStackInfoUser = new ThreadStackInfo( aCrashDebugger, this, ThreadStackInfo.TType.ETypeUser );
+ }
+ #endregion
+
+ #region API
+ #endregion
+
+ #region Properties
+ public TThreadState MState
+ {
+ get { return iState; }
+ set { iState = value; }
+ }
+
+ public uint WaitObj
+ {
+ get { return iStateWaitObjectAddress; }
+ set { iStateWaitObjectAddress = value; }
+ }
+
+ public TThreadFlags Flags
+ {
+ get { return iFlags; }
+ set { iFlags = value; }
+ }
+
+ public uint Handles
+ {
+ get { return iHandles; }
+ set { iHandles = value; }
+ }
+
+ public long Id
+ {
+ get { return iId; }
+ set { iId = value; }
+ }
+
+ public ThreadAllocatorInfo AllocatorInfo
+ {
+ get { return iAllocatorInfo; }
+ }
+
+ public uint Frame
+ {
+ get { return iFrame; }
+ set { iFrame = value; }
+ }
+
+ public ThreadPriorities Priorities
+ {
+ get { return iPriorities; }
+ }
+
+ public ExitInfo ExitInfo
+ {
+ get { return iExitInfo; }
+ }
+
+ public ThreadStackInfo StackInfoUser
+ {
+ get { return iStackInfoUser; }
+ }
+
+ public ThreadStackInfo StackInfoSupervisor
+ {
+ get { return iStackInfoSupervisor; }
+ }
+
+ public ThreadHandlers Handlers
+ {
+ get { return iHandlers; }
+ }
+
+ public ThreadTemporaries Temporaries
+ {
+ get { return iTemporaries; }
+ }
+
+ public uint IpcCount
+ {
+ get { return iIpcCount; }
+ set { iIpcCount = value; }
+ }
+
+ public DProcess OwningProcess
+ {
+ get
+ {
+ DProcess ret = null;
+ //
+ DObject owner = Owner;
+ if ( owner != null && owner is DProcess )
+ {
+ ret = (DProcess) owner;
+ }
+ //
+ return ret;
+ }
+ }
+
+ public NThread.NThread NThread
+ {
+ get { return iNThread; }
+ }
+
+ public bool HasActiveScheduler
+ {
+ get
+ {
+ return ( iHandlers.ActiveScheduler != 0 );
+ }
+ }
+
+ public TThreadWaitType WaitType
+ {
+ get
+ {
+ TThreadWaitType waitType = TThreadWaitType.EThreadWaitingUnknown;
+ //
+ if ( NThread.NState == CrashDebuggerLib.Structures.NThread.NThread.TNThreadState.EWaitDfc )
+ {
+ waitType = TThreadWaitType.EThreadWaitingOnDfc;
+ }
+ else if ( NThread.NState == CrashDebuggerLib.Structures.NThread.NThread.TNThreadState.EReady )
+ {
+ waitType = TThreadWaitType.EThreadWaitingReady;
+ }
+ else if ( NThread.NState == CrashDebuggerLib.Structures.NThread.NThread.TNThreadState.ESuspended )
+ {
+ waitType = TThreadWaitType.EThreadWaitingOnResumption;
+ }
+ else if ( NThread.NState == CrashDebuggerLib.Structures.NThread.NThread.TNThreadState.EBlocked )
+ {
+ bool blockdOnSemaphore = IsBlockedOnSemaphore;
+ if ( blockdOnSemaphore )
+ {
+ waitType = TThreadWaitType.EThreadWaitingOnSemaphore;
+ }
+ }
+ else if ( NThread.NState == CrashDebuggerLib.Structures.NThread.NThread.TNThreadState.EWaitFastSemaphore )
+ {
+ // Check that the fast semaphore is definitely the NThread's request semaphore.
+ uint nThreadRequestSemaphoreAddress = NThread.RequestSemaphoreAddress;
+ if ( NThread.WaitObj != 0 && NThread.WaitObj == nThreadRequestSemaphoreAddress )
+ {
+ CrashDebuggerLib.Structures.NThread.NThread.TWaitType nThreadWaitType = NThread.WaitType;
+ //
+ if ( nThreadWaitType == CrashDebuggerLib.Structures.NThread.NThread.TWaitType.EWaitTypeUserWaitForAnyRequest )
+ {
+ if ( HasActiveScheduler )
+ {
+ waitType = TThreadWaitType.EThreadWaitingOnRequestSemaphoreInsideSchedulerWaitLoop;
+ }
+ else
+ {
+ waitType = TThreadWaitType.EThreadWaitingOnRequestSemaphore;
+ }
+ }
+ else if ( nThreadWaitType == CrashDebuggerLib.Structures.NThread.NThread.TWaitType.EWaitTypeUserWaitForRequest )
+ {
+ waitType = TThreadWaitType.EThreadWaitingOnRequestSemaphore;
+ }
+ }
+ }
+ //
+ return waitType;
+ }
+ }
+
+ public bool IsUserThread
+ {
+ get
+ {
+ bool ret = false;
+ //
+ DProcess parent = OwningProcess;
+ if ( parent != null )
+ {
+ string name = parent.Name.ToLower();
+ ret = ( name != Platform.ProcessNames.KKernel.ToLower() );
+ }
+ //
+ return ret;
+ }
+ }
+
+ public bool IsCurrent
+ {
+ get
+ {
+ bool ret = CrashDebugger.IsCurrentThread( this );
+ return ret;
+ }
+ }
+ #endregion
+
+ #region Internal methods
+ private bool IsBlockedOnSemaphore
+ {
+ get
+ {
+ bool ret = false;
+ //
+ if ( NThread.NState == CrashDebuggerLib.Structures.NThread.NThread.TNThreadState.EBlocked )
+ {
+ Register.RegisterEntry linkReg = NThread.Registers[ "R14_USR" ];
+ if ( linkReg.Symbol != null )
+ {
+ string symbolText = linkReg.Symbol.Name;
+ if ( symbolText.Contains( "RSemaphore::Wait" ) || symbolText.Contains( "RCriticalSection::Wait" ) )
+ {
+ ret = true;
+ }
+ else if ( symbolText.Contains( "Exec::SemaphoreWait" ) )
+ {
+ ret = true;
+ }
+ }
+ }
+ //
+ return ret;
+ }
+ }
+ #endregion
+
+ #region Internal constants
+ #endregion
+
+ #region From DBase
+ public override string ToClipboard()
+ {
+ StringBuilder ret = new StringBuilder();
+ //
+ ret.AppendLine( base.ToClipboard() );
+ ret.AppendFormat( "MState: {0}, Id: {1}, ExitInfo: {2}" + System.Environment.NewLine, MState, Id, ExitInfo );
+ ret.AppendLine( iNThread.ToClipboard() );
+ ret.AppendLine( iStackInfoUser.ToClipboard() );
+ ret.AppendLine( iStackInfoSupervisor.ToClipboard() );
+ //
+ return ret.ToString();
+ }
+ #endregion
+
+ #region From System.Object
+ public override string ToString()
+ {
+ return base.ToString();
+ }
+ #endregion
+
+ #region Data members
+ private readonly NThread.NThread iNThread;
+ private readonly ThreadStackInfo iStackInfoSupervisor;
+ private readonly ThreadStackInfo iStackInfoUser;
+
+ private TThreadState iState = TThreadState.EUnknown;
+ private TThreadFlags iFlags = TThreadFlags.EThreadFlagNone;
+
+ private uint iStateWaitObjectAddress = 0;
+ private uint iHandles = 0;
+ private long iId = 0;
+ private uint iFrame = 0;
+ private uint iIpcCount = 0;
+
+ private ThreadAllocatorInfo iAllocatorInfo = new ThreadAllocatorInfo();
+ private ThreadPriorities iPriorities = new ThreadPriorities();
+ private ExitInfo iExitInfo = new ExitInfo();
+ private ThreadHandlers iHandlers = new ThreadHandlers();
+ private ThreadTemporaries iTemporaries = new ThreadTemporaries();
+ #endregion
+ }
+}
\ No newline at end of file