2 # art/test/run-test --host --gdb [--64] [--interpreter] 004-JniTest
3 # 'b Java_Main_shortMethod'
5 # 'command script import host_art_bt.py'
14 def host_art_bt(debugger
, command
, result
, internal_dict
):
15 prettified_frames
= []
18 target
= debugger
.GetSelectedTarget()
19 process
= target
.GetProcess()
20 thread
= process
.GetSelectedThread()
21 while lldb_frame_index
< thread
.GetNumFrames():
22 frame
= thread
.GetFrameAtIndex(lldb_frame_index
)
23 if frame
.GetModule() and re
.match(
24 r
"JIT\(.*?\)", frame
.GetModule().GetFileSpec().GetFilename()
28 # Get function/filename/lineno from symbol context
29 symbol
= frame
.GetSymbol()
31 print("No symbol info for compiled Java frame: ", frame
)
33 line_entry
= frame
.GetLineEntry()
34 prettified_frames
.append(
36 "function": symbol
.GetName(),
37 "file": str(line_entry
.GetFileSpec()) if line_entry
else None,
38 "line": line_entry
.GetLine() if line_entry
else -1,
44 art_stack_visitor
= frame
.EvaluateExpression(
45 """struct GetStackVisitor : public StackVisitor { GetStackVisitor(int depth_) : StackVisitor(Thread::Current(), NULL), depth(depth_) {} bool VisitFrame() { if (cur_depth_ == depth) { return false; } else { return true; } } int depth; }; GetStackVisitor visitor("""
46 + str(art_frame_index
)
47 + """); visitor.WalkStack(true); visitor"""
49 art_method
= frame
.EvaluateExpression(
50 art_stack_visitor
.GetName() + """.GetMethod()"""
52 if art_method
.GetValueAsUnsigned() != 0:
53 art_method_name
= frame
.EvaluateExpression(
54 """art::PrettyMethod(""" + art_method
.GetName() + """, true)"""
56 art_method_name_data
= frame
.EvaluateExpression(
57 art_method_name
.GetName() + """.c_str()"""
58 ).GetValueAsUnsigned()
59 art_method_name_size
= frame
.EvaluateExpression(
60 art_method_name
.GetName() + """.length()"""
61 ).GetValueAsUnsigned()
62 error
= lldb
.SBError()
63 art_method_name
= process
.ReadCStringFromMemory(
64 art_method_name_data
, art_method_name_size
+ 1, error
67 print("Failed to read method name")
69 if art_method_name
!= symbol
.GetName():
71 "Function names in native symbol and art runtime stack do not match: ",
76 art_frame_index
= art_frame_index
+ 1
78 art_frame_index
= art_frame_index
+ 1
81 lldb_frame_index
= lldb_frame_index
+ 1
82 if lldb_frame_index
< thread
.GetNumFrames():
83 frame
= thread
.GetFrameAtIndex(lldb_frame_index
)
84 if frame
.GetModule() and re
.match(
85 r
"JIT\(.*?\)", frame
.GetModule().GetFileSpec().GetFilename()
87 # Another compile Java frame
88 # Don't skip; leave it to the next iteration
90 elif frame
.GetSymbol() and (
91 frame
.GetSymbol().GetName() == "art_quick_invoke_stub"
92 or frame
.GetSymbol().GetName() == "art_quick_invoke_static_stub"
94 # art_quick_invoke_stub / art_quick_invoke_static_stub
95 # Skip until we get past the next ArtMethod::Invoke()
97 lldb_frame_index
= lldb_frame_index
+ 1
98 if lldb_frame_index
>= thread
.GetNumFrames():
100 "ArtMethod::Invoke not found below art_quick_invoke_stub/art_quick_invoke_static_stub"
103 frame
= thread
.GetFrameAtIndex(lldb_frame_index
)
106 and frame
.GetSymbol().GetName()
107 == "art::mirror::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)"
109 lldb_frame_index
= lldb_frame_index
+ 1
112 print("Invalid frame below compiled Java frame: ", frame
)
115 and frame
.GetSymbol().GetName() == "art_quick_generic_jni_trampoline"
117 # Interpreted JNI frame for x86_64
121 art_stack_visitor
= frame
.EvaluateExpression(
122 """struct GetStackVisitor : public StackVisitor { GetStackVisitor(int depth_) : StackVisitor(Thread::Current(), NULL), depth(depth_) {} bool VisitFrame() { if (cur_depth_ == depth) { return false; } else { return true; } } int depth; }; GetStackVisitor visitor("""
123 + str(art_frame_index
)
124 + """); visitor.WalkStack(true); visitor"""
126 art_method
= frame
.EvaluateExpression(
127 art_stack_visitor
.GetName() + """.GetMethod()"""
129 if art_method
.GetValueAsUnsigned() != 0:
130 # Get function/filename/lineno from ART runtime
131 art_method_name
= frame
.EvaluateExpression(
132 """art::PrettyMethod(""" + art_method
.GetName() + """, true)"""
134 art_method_name_data
= frame
.EvaluateExpression(
135 art_method_name
.GetName() + """.c_str()"""
136 ).GetValueAsUnsigned()
137 art_method_name_size
= frame
.EvaluateExpression(
138 art_method_name
.GetName() + """.length()"""
139 ).GetValueAsUnsigned()
140 error
= lldb
.SBError()
141 function
= process
.ReadCStringFromMemory(
142 art_method_name_data
, art_method_name_size
+ 1, error
145 prettified_frames
.append(
146 {"function": function
, "file": None, "line": -1}
149 art_frame_index
= art_frame_index
+ 1
151 art_frame_index
= art_frame_index
+ 1
154 lldb_frame_index
= lldb_frame_index
+ 1
155 if lldb_frame_index
< thread
.GetNumFrames():
156 frame
= thread
.GetFrameAtIndex(lldb_frame_index
)
157 if frame
.GetSymbol() and (
158 frame
.GetSymbol().GetName() == "art_quick_invoke_stub"
159 or frame
.GetSymbol().GetName() == "art_quick_invoke_static_stub"
161 # art_quick_invoke_stub / art_quick_invoke_static_stub
162 # Skip until we get past the next ArtMethod::Invoke()
164 lldb_frame_index
= lldb_frame_index
+ 1
165 if lldb_frame_index
>= thread
.GetNumFrames():
167 "ArtMethod::Invoke not found below art_quick_invoke_stub/art_quick_invoke_static_stub"
170 frame
= thread
.GetFrameAtIndex(lldb_frame_index
)
173 and frame
.GetSymbol().GetName()
174 == "art::mirror::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)"
176 lldb_frame_index
= lldb_frame_index
+ 1
179 print("Invalid frame below compiled Java frame: ", frame
)
180 elif frame
.GetSymbol() and re
.search(
181 r
"art::interpreter::", frame
.GetSymbol().GetName()
183 # Interpreted Java frame
186 lldb_frame_index
= lldb_frame_index
+ 1
187 if lldb_frame_index
>= thread
.GetNumFrames():
188 print("art::interpreter::Execute not found in interpreter frame")
190 frame
= thread
.GetFrameAtIndex(lldb_frame_index
)
193 and frame
.GetSymbol().GetName()
194 == "art::interpreter::Execute(art::Thread*, art::MethodHelper&, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue)"
200 art_stack_visitor
= frame
.EvaluateExpression(
201 """struct GetStackVisitor : public StackVisitor { GetStackVisitor(int depth_) : StackVisitor(Thread::Current(), NULL), depth(depth_) {} bool VisitFrame() { if (cur_depth_ == depth) { return false; } else { return true; } } int depth; }; GetStackVisitor visitor("""
202 + str(art_frame_index
)
203 + """); visitor.WalkStack(true); visitor"""
205 art_method
= frame
.EvaluateExpression(
206 art_stack_visitor
.GetName() + """.GetMethod()"""
208 if art_method
.GetValueAsUnsigned() != 0:
209 # Get function/filename/lineno from ART runtime
210 art_method_name
= frame
.EvaluateExpression(
211 """art::PrettyMethod(""" + art_method
.GetName() + """, true)"""
213 art_method_name_data
= frame
.EvaluateExpression(
214 art_method_name
.GetName() + """.c_str()"""
215 ).GetValueAsUnsigned()
216 art_method_name_size
= frame
.EvaluateExpression(
217 art_method_name
.GetName() + """.length()"""
218 ).GetValueAsUnsigned()
219 error
= lldb
.SBError()
220 function
= process
.ReadCStringFromMemory(
221 art_method_name_data
, art_method_name_size
+ 1, error
224 line
= frame
.EvaluateExpression(
225 art_stack_visitor
.GetName()
226 + """.GetMethod()->GetLineNumFromDexPC("""
227 + art_stack_visitor
.GetName()
228 + """.GetDexPc(true))"""
229 ).GetValueAsUnsigned()
231 file_name
= frame
.EvaluateExpression(
232 art_method
.GetName() + """->GetDeclaringClassSourceFile()"""
234 file_name_data
= file_name
.GetValueAsUnsigned()
235 file_name_size
= frame
.EvaluateExpression(
236 """(size_t)strlen(""" + file_name
.GetName() + """)"""
237 ).GetValueAsUnsigned()
238 error
= lldb
.SBError()
239 file_name
= process
.ReadCStringFromMemory(
240 file_name_data
, file_name_size
+ 1, error
242 if not error
.Success():
243 print("Failed to read source file name")
246 prettified_frames
.append(
247 {"function": function
, "file": file_name
, "line": line
}
250 art_frame_index
= art_frame_index
+ 1
252 art_frame_index
= art_frame_index
+ 1
256 lldb_frame_index
= lldb_frame_index
+ 1
257 if lldb_frame_index
>= thread
.GetNumFrames():
258 print("Can not get past interpreter native frames")
260 frame
= thread
.GetFrameAtIndex(lldb_frame_index
)
261 if frame
.GetSymbol() and not re
.search(
262 r
"art::interpreter::", frame
.GetSymbol().GetName()
266 # Other frames. Add them as-is.
267 frame
= thread
.GetFrameAtIndex(lldb_frame_index
)
268 lldb_frame_index
= lldb_frame_index
+ 1
269 if frame
.GetModule():
270 module_name
= frame
.GetModule().GetFileSpec().GetFilename()
271 if not module_name
in [
277 prettified_frames
.append(
279 "function": frame
.GetSymbol().GetName()
282 "file": str(frame
.GetLineEntry().GetFileSpec())
283 if frame
.GetLineEntry()
285 "line": frame
.GetLineEntry().GetLine()
286 if frame
.GetLineEntry()
291 for prettified_frame
in prettified_frames
:
293 prettified_frame
["function"],
294 prettified_frame
["file"],
295 prettified_frame
["line"],
299 def __lldb_init_module(debugger
, internal_dict
):
300 debugger
.HandleCommand("command script add -f host_art_bt.host_art_bt host_art_bt")