|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 using System; |
|
18 using System.Text; |
|
19 using System.Text.RegularExpressions; |
|
20 using System.Collections.Generic; |
|
21 using SymbianUtils.Range; |
|
22 using SymbianStructuresLib.Uids; |
|
23 using SymbianStructuresLib.Arm.Registers; |
|
24 using CrashItemLib.Crash; |
|
25 using CrashItemLib.Crash.Base; |
|
26 using CrashItemLib.Crash.Base.DataBinding; |
|
27 using CrashItemLib.Crash.Stacks; |
|
28 using CrashItemLib.Crash.ExitInfo; |
|
29 using CrashItemLib.Crash.Processes; |
|
30 using CrashItemLib.Crash.Registers; |
|
31 using CrashItemLib.Crash.Container; |
|
32 using CrashItemLib.Crash.Summarisable; |
|
33 |
|
34 namespace CrashItemLib.Crash.Threads |
|
35 { |
|
36 #region Attributes |
|
37 [CIDBAttributeColumn( "Name", 0 )] |
|
38 [CIDBAttributeColumn( "Value", 1, true )] |
|
39 #endregion |
|
40 public class CIThread : CIElement |
|
41 { |
|
42 #region Constructors |
|
43 public CIThread( CIProcess aProcess ) |
|
44 : base( aProcess.Container, aProcess ) |
|
45 { |
|
46 AddChild( new CIExitInfo( this ) ); |
|
47 AddChild( new CIThreadRegisterListCollection( this ) ); |
|
48 } |
|
49 #endregion |
|
50 |
|
51 #region API |
|
52 public CIStack CreateStack( CIRegisterList aRegisters, byte[] aData, uint aAddressOfFirstByte, AddressRange aRange ) |
|
53 { |
|
54 // The registers given must be a child of this thread (in some way) |
|
55 System.Diagnostics.Debug.Assert( aRegisters.OwningThread == this ); |
|
56 |
|
57 // Add it to the overall item too |
|
58 CIStack stack = CIStack.NewThreadStack( this, aRegisters, aData, aAddressOfFirstByte, aRange ); |
|
59 AddChild( stack ); |
|
60 |
|
61 return stack; |
|
62 } |
|
63 |
|
64 internal bool Contains( CIStack aStack ) |
|
65 { |
|
66 return iStacks.ContainsKey( aStack.Type ); |
|
67 } |
|
68 #endregion |
|
69 |
|
70 #region Properties |
|
71 [CIDBAttributeCell( "Id", 2 )] |
|
72 public override CIElementId Id |
|
73 { |
|
74 get { return base.Id; } |
|
75 set { base.Id = value; } |
|
76 } |
|
77 |
|
78 [CIDBAttributeCell( "Priority", 3, 0 )] |
|
79 public int Priority |
|
80 { |
|
81 get { return iPriority; } |
|
82 set { iPriority = value; } |
|
83 } |
|
84 |
|
85 [CIDBAttributeCell("Full Name", 1 )] |
|
86 public string FullName |
|
87 { |
|
88 get |
|
89 { |
|
90 StringBuilder ret = new StringBuilder(); |
|
91 // |
|
92 if ( OwningProcess.Name.Length > 0 ) |
|
93 { |
|
94 ret.AppendFormat( "{0}[{1:x8}]{2:d4}::{3}", |
|
95 OwningProcess.Name, |
|
96 OwningProcess.SID, |
|
97 OwningProcess.Generation, |
|
98 Name |
|
99 ); |
|
100 } |
|
101 else |
|
102 { |
|
103 ret.Append( Name ); |
|
104 } |
|
105 // |
|
106 return ret.ToString(); |
|
107 } |
|
108 } |
|
109 |
|
110 public override string Name |
|
111 { |
|
112 get |
|
113 { |
|
114 return iName; |
|
115 } |
|
116 set |
|
117 { |
|
118 iName = value; |
|
119 } |
|
120 } |
|
121 |
|
122 public CIProcess OwningProcess |
|
123 { |
|
124 get |
|
125 { |
|
126 CIProcess ret = (CIProcess) base.Parent; |
|
127 return ret; |
|
128 } |
|
129 } |
|
130 |
|
131 [CIDBAttributeCell( "Exit Info", 4 )] |
|
132 public CIExitInfo ExitInfo |
|
133 { |
|
134 get |
|
135 { |
|
136 // We ensure there is only ever one, so this is okay |
|
137 return (CIExitInfo) base.ChildByType( typeof( CIExitInfo ) ); |
|
138 } |
|
139 } |
|
140 |
|
141 public CIStack[] Stacks |
|
142 { |
|
143 get |
|
144 { |
|
145 CIElementList<CIStack> stacks = base.ChildrenByType<CIStack>(); |
|
146 return stacks.ToArray(); |
|
147 } |
|
148 } |
|
149 |
|
150 public CISummarisableEntity Summary |
|
151 { |
|
152 get |
|
153 { |
|
154 CISummarisableEntityList list = Container.Summaries; |
|
155 CISummarisableEntity ret = list[ this ]; |
|
156 return ret; |
|
157 } |
|
158 } |
|
159 |
|
160 public bool IsAbnormalTermination |
|
161 { |
|
162 get |
|
163 { |
|
164 bool ret = ExitInfo.IsAbnormalTermination; |
|
165 return ret; |
|
166 } |
|
167 } |
|
168 |
|
169 public CIRegisterList CurrentProcessorModeRegisters |
|
170 { |
|
171 get { return Registers.CurrentProcessorModeRegisters; } |
|
172 } |
|
173 |
|
174 public CIThreadRegisterListCollection Registers |
|
175 { |
|
176 get |
|
177 { |
|
178 // We ensure there is only ever one, so this is okay |
|
179 return (CIThreadRegisterListCollection) base.ChildByType( typeof( CIThreadRegisterListCollection ) ); |
|
180 } |
|
181 } |
|
182 #endregion |
|
183 |
|
184 #region From CIElement |
|
185 public override void AddChild( CIElement aChild ) |
|
186 { |
|
187 // We support 4 types of children at the moment. |
|
188 // Registers, stacks and exit info, messages. |
|
189 if ( aChild.GetType() == typeof( CIExitInfo ) ) |
|
190 { |
|
191 if ( base.ChildrenByType<CIExitInfo>().Count != 0 ) |
|
192 { |
|
193 throw new ArgumentException( "Exit Info already associated with the thread" ); |
|
194 } |
|
195 } |
|
196 else if ( aChild.GetType() == typeof( CIThreadRegisterListCollection ) ) |
|
197 { |
|
198 if ( base.ChildrenByType<CIThreadRegisterListCollection>().Count != 0 ) |
|
199 { |
|
200 throw new ArgumentException( "Registers already associated with the thread" ); |
|
201 } |
|
202 } |
|
203 else if ( aChild.GetType() == typeof( CIStack ) ) |
|
204 { |
|
205 CIStack stack = (CIStack) aChild; |
|
206 |
|
207 // We must ensure we don't already have a stack of the specified mode |
|
208 // associated with the thread. |
|
209 bool exists = iStacks.ContainsKey( stack.Type ); |
|
210 if ( exists ) |
|
211 { |
|
212 throw new ArgumentException( ArmRegisterBankUtils.BankAsStringLong( stack.Type ) + " mode stack already registered with thread" ); |
|
213 } |
|
214 else |
|
215 { |
|
216 iStacks.Add( stack.Type, stack ); |
|
217 } |
|
218 } |
|
219 // |
|
220 base.AddChild( aChild ); |
|
221 } |
|
222 #endregion |
|
223 |
|
224 #region Internal methods |
|
225 #endregion |
|
226 |
|
227 #region Internal constants |
|
228 private const string KUnknownThreadName = "UnknownThread"; |
|
229 #endregion |
|
230 |
|
231 #region Data members |
|
232 private int iPriority = 0; |
|
233 private string iName = KUnknownThreadName; |
|
234 private Dictionary<TArmRegisterBank, CIStack> iStacks = new Dictionary<TArmRegisterBank, CIStack>(); |
|
235 #endregion |
|
236 } |
|
237 } |