@@ -38,29 +38,37 @@ public static LinuxAMD64CFrame getTopFrame(LinuxDebugger dbg, Address rip, Threa
38
38
DwarfParser dwarf = null ;
39
39
40
40
if (libptr != null ) { // Native frame
41
+ dwarf = new DwarfParser (libptr );
41
42
try {
42
- dwarf = new DwarfParser (libptr );
43
43
dwarf .processDwarf (rip );
44
- cfa = ((dwarf .getCFARegister () == AMD64ThreadContext .RBP ) &&
45
- !dwarf .isBPOffsetAvailable ())
46
- ? context .getRegisterAsAddress (AMD64ThreadContext .RBP )
47
- : context .getRegisterAsAddress (dwarf .getCFARegister ())
48
- .addOffsetTo (dwarf .getCFAOffset ());
49
44
} catch (DebuggerException e ) {
50
- // Bail out to Java frame case
45
+ // DWARF processing should succeed when the frame is native
46
+ // but it might fail if Common Information Entry (CIE) has language
47
+ // personality routine and/or Language Specific Data Area (LSDA).
48
+ return new LinuxAMD64CFrame (dbg , cfa , rip , dwarf , true );
51
49
}
50
+ cfa = ((dwarf .getCFARegister () == AMD64ThreadContext .RBP ) &&
51
+ !dwarf .isBPOffsetAvailable ())
52
+ ? context .getRegisterAsAddress (AMD64ThreadContext .RBP )
53
+ : context .getRegisterAsAddress (dwarf .getCFARegister ())
54
+ .addOffsetTo (dwarf .getCFAOffset ());
52
55
}
53
56
54
57
return (cfa == null ) ? null
55
58
: new LinuxAMD64CFrame (dbg , cfa , rip , dwarf );
56
59
}
57
60
58
61
private LinuxAMD64CFrame (LinuxDebugger dbg , Address cfa , Address rip , DwarfParser dwarf ) {
62
+ this (dbg , cfa , rip , dwarf , false );
63
+ }
64
+
65
+ private LinuxAMD64CFrame (LinuxDebugger dbg , Address cfa , Address rip , DwarfParser dwarf , boolean finalFrame ) {
59
66
super (dbg .getCDebugger ());
60
67
this .cfa = cfa ;
61
68
this .rip = rip ;
62
69
this .dbg = dbg ;
63
70
this .dwarf = dwarf ;
71
+ this .finalFrame = finalFrame ;
64
72
}
65
73
66
74
// override base class impl to avoid ELF parsing
@@ -123,7 +131,19 @@ private Address getNextCFA(DwarfParser nextDwarf, ThreadContext context) {
123
131
return isValidFrame (nextCFA , context ) ? nextCFA : null ;
124
132
}
125
133
126
- private DwarfParser getNextDwarf (Address nextPC ) {
134
+ @ Override
135
+ public CFrame sender (ThreadProxy thread ) {
136
+ if (finalFrame ) {
137
+ return null ;
138
+ }
139
+
140
+ ThreadContext context = thread .getContext ();
141
+
142
+ Address nextPC = getNextPC (dwarf != null );
143
+ if (nextPC == null ) {
144
+ return null ;
145
+ }
146
+
127
147
DwarfParser nextDwarf = null ;
128
148
129
149
if ((dwarf != null ) && dwarf .isIn (nextPC )) {
@@ -140,22 +160,16 @@ private DwarfParser getNextDwarf(Address nextPC) {
140
160
}
141
161
142
162
if (nextDwarf != null ) {
143
- nextDwarf .processDwarf (nextPC );
144
- }
145
-
146
- return nextDwarf ;
147
- }
148
-
149
- @ Override
150
- public CFrame sender (ThreadProxy thread ) {
151
- ThreadContext context = thread .getContext ();
152
-
153
- Address nextPC = getNextPC (dwarf != null );
154
- if (nextPC == null ) {
155
- return null ;
163
+ try {
164
+ nextDwarf .processDwarf (nextPC );
165
+ } catch (DebuggerException e ) {
166
+ // DWARF processing should succeed when the frame is native
167
+ // but it might fail if Common Information Entry (CIE) has language
168
+ // personality routine and/or Language Specific Data Area (LSDA).
169
+ return new LinuxAMD64CFrame (dbg , null , nextPC , nextDwarf , true );
170
+ }
156
171
}
157
172
158
- DwarfParser nextDwarf = getNextDwarf (nextPC );
159
173
Address nextCFA = getNextCFA (nextDwarf , context );
160
174
return isValidFrame (nextCFA , context ) ? new LinuxAMD64CFrame (dbg , nextCFA , nextPC , nextDwarf )
161
175
: null ;
@@ -167,4 +181,5 @@ public CFrame sender(ThreadProxy thread) {
167
181
private Address cfa ;
168
182
private LinuxDebugger dbg ;
169
183
private DwarfParser dwarf ;
184
+ private boolean finalFrame ;
170
185
}
0 commit comments