|
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.Collections.Generic; |
|
20 using CrashItemLib.Crash.Container; |
|
21 using CrashItemLib.Crash.Stacks; |
|
22 using CrashItemLib.Crash.Registers; |
|
23 using CrashItemLib.Crash.Base; |
|
24 using CrashItemLib.Crash.Messages; |
|
25 using CrashItemLib.Crash.Summarisable; |
|
26 using SymbianStructuresLib.Arm.Registers; |
|
27 using SymbianUtils.Range; |
|
28 |
|
29 namespace CrashItemLib.Engine.ProblemDetectors.Registers |
|
30 { |
|
31 internal class CIPDRegAvailability : CIProblemDetector |
|
32 { |
|
33 #region Constructors |
|
34 public CIPDRegAvailability() |
|
35 { |
|
36 } |
|
37 #endregion |
|
38 |
|
39 #region From CIProblemDetector |
|
40 public override void Check( CIContainer aContainer ) |
|
41 { |
|
42 CISummarisableEntityList list = aContainer.Summaries; |
|
43 foreach ( CISummarisableEntity entry in list ) |
|
44 { |
|
45 // Check that each stack contains some registers and at least the SP. |
|
46 bool stackAvailable = entry.IsAvailable( CISummarisableEntity.TElement.EElementStack ); |
|
47 bool regsAvailable = entry.IsAvailable( CISummarisableEntity.TElement.EElementRegisters ); |
|
48 // |
|
49 if ( stackAvailable ) |
|
50 { |
|
51 CIStack stack = entry.Stack; |
|
52 // |
|
53 if ( regsAvailable ) |
|
54 { |
|
55 CIRegisterList regs = stack.Registers; |
|
56 |
|
57 // Check that SP, LR and PC are available |
|
58 bool pointerAvailable = regs.Contains( TArmRegisterType.EArmReg_SP ); |
|
59 if ( !pointerAvailable ) |
|
60 { |
|
61 base.CreateWarning( aContainer, stack, |
|
62 LibResources.CIPDRegAvailability_MissingSP_Title, |
|
63 string.Format( LibResources.CIPDRegAvailability_MissingSP_Description, base.CreateIdentifierText( entry ) ) |
|
64 ); |
|
65 } |
|
66 // |
|
67 bool lrAvailable = regs.Contains( TArmRegisterType.EArmReg_LR ); |
|
68 if ( !lrAvailable ) |
|
69 { |
|
70 base.CreateWarning( aContainer, stack, |
|
71 LibResources.CIPDRegAvailability_MissingLR_Title, |
|
72 string.Format( LibResources.CIPDRegAvailability_MissingLR_Description, base.CreateIdentifierText( entry ) ) |
|
73 ); |
|
74 } |
|
75 // |
|
76 bool pcAvailable = regs.Contains( TArmRegisterType.EArmReg_PC ); |
|
77 if ( !pcAvailable ) |
|
78 { |
|
79 base.CreateWarning( aContainer, stack, |
|
80 LibResources.CIPDRegAvailability_MissingPC_Title, |
|
81 string.Format( LibResources.CIPDRegAvailability_MissingPC_Description, base.CreateIdentifierText( entry ) ) |
|
82 ); |
|
83 } |
|
84 |
|
85 // If R0 is available, check if it is 0 and check whether an exception occurred - if so, it was possibly |
|
86 // caused by de-referencing a NULL this pointer. |
|
87 bool threadAvailable = entry.IsAvailable( CISummarisableEntity.TElement.EElementThread ); |
|
88 if ( threadAvailable ) |
|
89 { |
|
90 if ( regs.Contains( TArmRegisterType.EArmReg_00 ) ) |
|
91 { |
|
92 CIRegister r0 = regs[ TArmRegisterType.EArmReg_00 ]; |
|
93 // |
|
94 bool r0WasNull = ( r0.Value == 0 ); |
|
95 bool wasException = entry.IsAbnormalTermination && ( entry.Thread.ExitInfo.Type == CrashItemLib.Crash.ExitInfo.CIExitInfo.TExitType.EExitTypeException ); |
|
96 bool wasKernExec3 = entry.IsAbnormalTermination && ( entry.Thread.ExitInfo.Type == CrashItemLib.Crash.ExitInfo.CIExitInfo.TExitType.EExitTypePanic && |
|
97 entry.Thread.ExitInfo.Category.ToUpper() == "KERN-EXEC" && |
|
98 entry.Thread.ExitInfo.Reason == 3 ); |
|
99 // |
|
100 if ( r0WasNull && ( wasException || wasKernExec3 ) ) |
|
101 { |
|
102 base.CreateWarning( aContainer, r0, |
|
103 LibResources.CIPDRegAvailability_NullThisPointer_Title, |
|
104 string.Format( LibResources.CIPDRegAvailability_NullThisPointer_Description, base.CreateIdentifierText( entry ) ) |
|
105 ); |
|
106 } |
|
107 } |
|
108 } |
|
109 } |
|
110 else |
|
111 { |
|
112 base.CreateWarning( aContainer, stack, |
|
113 LibResources.CIPDRegAvailability_NoRegsForStack_Title, |
|
114 string.Format( LibResources.CIPDRegAvailability_NoRegsForStack_Description, base.CreateIdentifierText( entry ) ) |
|
115 ); |
|
116 } |
|
117 } |
|
118 } |
|
119 } |
|
120 #endregion |
|
121 |
|
122 #region Properties |
|
123 #endregion |
|
124 |
|
125 #region Internal methods |
|
126 #endregion |
|
127 |
|
128 #region From System.Object |
|
129 #endregion |
|
130 |
|
131 #region Data members |
|
132 #endregion |
|
133 } |
|
134 } |