|
1 /* |
|
2 * Copyright (c) 2004-2008 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 |
|
18 using System; |
|
19 using System.Collections.Generic; |
|
20 using System.Text; |
|
21 using SymbianParserLib.Engine; |
|
22 using CrashDebuggerLib.Structures.KernelObjects; |
|
23 using CrashDebuggerLib.Structures.Process; |
|
24 using CrashDebuggerLib.Structures.CodeSeg; |
|
25 using CrashDebuggerLib.Structures.Register; |
|
26 using CrashDebuggerLib.Structures.Thread; |
|
27 using CrashDebuggerLib.Structures.NThread; |
|
28 using SymbianParserLib.Elements; |
|
29 using SymbianParserLib.Enums; |
|
30 using SymbianParserLib.BaseStructures; |
|
31 |
|
32 namespace CrashDebuggerLib.Parsers.State.Implementation.Helpers |
|
33 { |
|
34 internal class HelperNThread |
|
35 { |
|
36 #region Constructors |
|
37 public HelperNThread() |
|
38 { |
|
39 } |
|
40 #endregion |
|
41 |
|
42 #region API |
|
43 public void CreateMonitorNThread( ParserEngine aEngine, string aName, NThread aThread ) |
|
44 { |
|
45 CreateMonitorNThread( aEngine, aName, aThread, null ); |
|
46 } |
|
47 |
|
48 public void CreateMonitorNThread( ParserEngine aEngine, string aName, NThread aThread, ParserElementBase.ElementCompleteHandler aLastFieldHandler ) |
|
49 { |
|
50 // Create MState lines |
|
51 ParserParagraph para0 = new ParserParagraph( aName + "_NSTATE" ); |
|
52 para0.Tag = aThread; |
|
53 CreateThreadNState( para0, aThread, "READY", false ); |
|
54 CreateThreadNState( para0, aThread, "SUSPENDED", false ); |
|
55 CreateThreadNState( para0, aThread, "WAITFSEM", true ); |
|
56 CreateThreadNState( para0, aThread, "SLEEP", false ); |
|
57 CreateThreadNState( para0, aThread, "BLOCKED", false ); |
|
58 CreateThreadNState( para0, aThread, "DEAD", false ); |
|
59 CreateThreadNState( para0, aThread, "WAITDFC", false ); |
|
60 CreateThreadNState( para0, aThread, "??", true ); |
|
61 aEngine.Add( para0 ); |
|
62 |
|
63 ParserParagraph para1 = CreateThreadCommon( aName, aThread ); |
|
64 aEngine.Add( para1 ); |
|
65 |
|
66 CreateRegisterParagraphs( aEngine, aThread, aLastFieldHandler ); |
|
67 |
|
68 // TODO: add support for older memory models? |
|
69 } |
|
70 #endregion |
|
71 |
|
72 #region Call-back methods |
|
73 public void SetThreadNStateWaitObject( ParserParagraph aParagraph, ParserFieldName aParameterName, uint aWaitObjectAddress ) |
|
74 { |
|
75 System.Diagnostics.Debug.Assert( aParagraph.Tag is NThread ); |
|
76 NThread thread = (NThread) aParagraph.Tag; |
|
77 thread.WaitObj = aWaitObjectAddress; |
|
78 } |
|
79 #endregion |
|
80 |
|
81 #region Event handlers |
|
82 void NThreadState_ElementComplete( ParserElementBase aElement ) |
|
83 { |
|
84 ParserLine line = (ParserLine) aElement; |
|
85 System.Diagnostics.Debug.Assert( line.Tag is NThread.TNThreadState ); |
|
86 NThread.TNThreadState state = (NThread.TNThreadState) line.Tag; |
|
87 ParserParagraph paragraph = line.Paragraph; |
|
88 System.Diagnostics.Debug.Assert( paragraph.Tag is NThread ); |
|
89 NThread thread = (NThread) paragraph.Tag; |
|
90 thread.NState = state; |
|
91 } |
|
92 #endregion |
|
93 |
|
94 #region Internal methods |
|
95 private void CreateThreadNState( ParserParagraph aParagraph, NThread aThread, string aNStateName, bool aCapturesWaitObject ) |
|
96 { |
|
97 StringBuilder format = new StringBuilder( "NThread @ %8x Pri %d NState " + aNStateName ); |
|
98 // |
|
99 if ( aCapturesWaitObject ) |
|
100 { |
|
101 format.Append( " %8x" ); |
|
102 } |
|
103 format.Append( "\r\n" ); |
|
104 // |
|
105 // |
|
106 string finalFormat = format.ToString(); |
|
107 NThread.TNThreadState state = NThread.NStateFromString( aNStateName ); |
|
108 ParserLine l1 = ParserLine.NewSymFormat( finalFormat ); |
|
109 l1.Tag = state; |
|
110 // |
|
111 l1[ 0 ].SetTargetProperty( aThread, "Address" ); |
|
112 l1[ 1 ].SetTargetProperty( aThread, "Priority" ); |
|
113 // |
|
114 if ( aCapturesWaitObject ) |
|
115 { |
|
116 l1[ 2 ].SetTargetMethod( this, "SetThreadNStateWaitObject" ); |
|
117 } |
|
118 // |
|
119 l1.ElementComplete += new ParserElementBase.ElementCompleteHandler( NThreadState_ElementComplete ); |
|
120 aParagraph.Add( l1 ); |
|
121 } |
|
122 |
|
123 private ParserParagraph CreateThreadCommon( string aName, NThread aThread ) |
|
124 { |
|
125 ParserParagraph para = new ParserParagraph( aName ); |
|
126 // |
|
127 ParserLine l1 = ParserLine.NewSymFormat( "Next=%08x Prev=%08x Att=%02x\r\n" ); |
|
128 l1.SetTargetProperties( new object[] { aThread.LinkedListInfo, aThread.LinkedListInfo, aThread }, "Next", "Previous", "Attributes" ); |
|
129 // |
|
130 ParserLine l2 = ParserLine.NewSymFormat( "HeldFM=%08x WaitFM=%08x AddrSp=%08x\r\n" ); |
|
131 l2.SetTargetProperties( new object[] { aThread.MutexInfo, aThread.MutexInfo, aThread }, "HeldAddress", "WaitAddress", "AddressSpace" ); |
|
132 // |
|
133 ParserLine l3 = ParserLine.NewSymFormat( "Time=%d Timeslice=%d ReqCount=%d\r\n" ); |
|
134 l3.SetTargetProperties( new object[] { aThread.TimeInfo, aThread.TimeInfo, aThread.CountInfo }, "Time", "Timeslice", "RequestSemaphoreCount" ); |
|
135 // |
|
136 ParserLine l4 = ParserLine.NewSymFormat( "LastStartTime=%08x TotalCpuTime=%lx Tag=%08x\r\n" ); |
|
137 l4.SetTargetProperties( aThread.TimeInfo, "LastStartTime", "TotalCpuTime", "Tag" ); |
|
138 // |
|
139 ParserLine l5 = ParserLine.NewSymFormat( "ReturnValue=%d, UCT=%d\r\n" ); |
|
140 l5.SetTargetProperties( aThread, "ReturnValue", "UserContextType" ); |
|
141 // |
|
142 ParserLine l6 = ParserLine.NewSymFormat( "SuspendCount=%d CsCount=%d CsFunction=%08x\r\n" ); |
|
143 l6.SetTargetProperties( aThread.CountInfo, "SuspendCount", "CsCount", "CsFunctionRaw" ); |
|
144 // |
|
145 ParserLine l7 = ParserLine.NewSymFormat( "SavedSP=%08x ExtraContext=%08x ExtraContextSize=%08x\r\n" ); |
|
146 l7.SetTargetProperties( new object[] { aThread, aThread.ExtraContextInfo, aThread.ExtraContextInfo }, "SavedSP", "ExtraContext", "ExtraContextSizeRaw" ); |
|
147 // |
|
148 para.Add( l1, l2, l3, l4, l5, l6, l7 ); |
|
149 return para; |
|
150 } |
|
151 |
|
152 private void CreateRegisterParagraphs( ParserEngine aEngine, NThread aThread, ParserElementBase.ElementCompleteHandler aLastFieldHandler ) |
|
153 { |
|
154 { |
|
155 ParserParagraph para = new ParserParagraph( "NTHREAD_REGS1" ); |
|
156 para.SetTargetMethod( aThread.Registers, "Add" ); |
|
157 ParserLine l1 = ParserLine.NewSymFormat( "FPEXC %08x\r\n" ); |
|
158 ParserLine l2 = ParserLine.NewSymFormat( "CAR %08x\r\n" ); |
|
159 ParserLine l3 = ParserLine.NewSymFormat( "DACR %08x\r\n" ); |
|
160 para.Add( l1, l2, l3 ); |
|
161 aEngine.Add( para ); |
|
162 } |
|
163 |
|
164 { |
|
165 ParserParagraph para = new ParserParagraph( "NTHREAD_REGS2" ); |
|
166 para.SetTargetMethod( aThread.Registers, "Add" ); |
|
167 ParserLine l1 = ParserLine.NewSymFormat( "R13_USR %08x R14_USR %08x SPSR_SVC %08x\r\n" ); |
|
168 ParserLine l2 = ParserLine.NewSymFormat( " R4 %08x R5 %08x R6 %08x R7 %08x\r\n" ); |
|
169 ParserLine l3 = ParserLine.NewSymFormat( " R8 %08x R9 %08x R10 %08x R11 %08x\r\n" ); |
|
170 ParserLine l4 = ParserLine.NewSymFormat( " PC %08x\r\n" ); |
|
171 // |
|
172 if ( aLastFieldHandler != null ) |
|
173 { |
|
174 l4[ 0 ].ElementComplete += new ParserElementBase.ElementCompleteHandler( aLastFieldHandler ); |
|
175 } |
|
176 // |
|
177 para.Add( l1, l2, l3, l4 ); |
|
178 aEngine.Add( para ); |
|
179 } |
|
180 } |
|
181 #endregion |
|
182 } |
|
183 } |