[NFC][Coroutines] Use structured binding with llvm::enumerate in CoroSplit (#116879)
[llvm-project.git] / lldb / scripts / android / host_art_bt.py
blobd4c5af46d9e2f8e37bf8bfe71d485da8e9e0687e
1 # Usage:
2 # art/test/run-test --host --gdb [--64] [--interpreter] 004-JniTest
3 # 'b Java_Main_shortMethod'
4 # 'r'
5 # 'command script import host_art_bt.py'
6 # 'host_art_bt'
8 import sys
9 import re
11 import lldb
14 def host_art_bt(debugger, command, result, internal_dict):
15 prettified_frames = []
16 lldb_frame_index = 0
17 art_frame_index = 0
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()
26 # Compiled Java frame
28 # Get function/filename/lineno from symbol context
29 symbol = frame.GetSymbol()
30 if not symbol:
31 print("No symbol info for compiled Java frame: ", frame)
32 sys.exit(1)
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,
42 # Skip art frames
43 while True:
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
66 if not error.Success:
67 print("Failed to read method name")
68 sys.exit(1)
69 if art_method_name != symbol.GetName():
70 print(
71 "Function names in native symbol and art runtime stack do not match: ",
72 symbol.GetName(),
73 " != ",
74 art_method_name,
76 art_frame_index = art_frame_index + 1
77 break
78 art_frame_index = art_frame_index + 1
80 # Skip native frames
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
89 continue
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()
96 while True:
97 lldb_frame_index = lldb_frame_index + 1
98 if lldb_frame_index >= thread.GetNumFrames():
99 print(
100 "ArtMethod::Invoke not found below art_quick_invoke_stub/art_quick_invoke_static_stub"
102 sys.exit(1)
103 frame = thread.GetFrameAtIndex(lldb_frame_index)
104 if (
105 frame.GetSymbol()
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
110 break
111 else:
112 print("Invalid frame below compiled Java frame: ", frame)
113 elif (
114 frame.GetSymbol()
115 and frame.GetSymbol().GetName() == "art_quick_generic_jni_trampoline"
117 # Interpreted JNI frame for x86_64
119 # Skip art frames
120 while True:
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
150 break
151 art_frame_index = art_frame_index + 1
153 # Skip native frames
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()
163 while True:
164 lldb_frame_index = lldb_frame_index + 1
165 if lldb_frame_index >= thread.GetNumFrames():
166 print(
167 "ArtMethod::Invoke not found below art_quick_invoke_stub/art_quick_invoke_static_stub"
169 sys.exit(1)
170 frame = thread.GetFrameAtIndex(lldb_frame_index)
171 if (
172 frame.GetSymbol()
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
177 break
178 else:
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
185 while True:
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")
189 sys.exit(1)
190 frame = thread.GetFrameAtIndex(lldb_frame_index)
191 if (
192 frame.GetSymbol()
193 and frame.GetSymbol().GetName()
194 == "art::interpreter::Execute(art::Thread*, art::MethodHelper&, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue)"
196 break
198 # Skip art frames
199 while True:
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")
244 sys.exit(1)
246 prettified_frames.append(
247 {"function": function, "file": file_name, "line": line}
250 art_frame_index = art_frame_index + 1
251 break
252 art_frame_index = art_frame_index + 1
254 # Skip native frames
255 while True:
256 lldb_frame_index = lldb_frame_index + 1
257 if lldb_frame_index >= thread.GetNumFrames():
258 print("Can not get past interpreter native frames")
259 sys.exit(1)
260 frame = thread.GetFrameAtIndex(lldb_frame_index)
261 if frame.GetSymbol() and not re.search(
262 r"art::interpreter::", frame.GetSymbol().GetName()
264 break
265 else:
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 [
272 "libartd.so",
273 "dalvikvm32",
274 "dalvikvm64",
275 "libc.so.6",
277 prettified_frames.append(
279 "function": frame.GetSymbol().GetName()
280 if frame.GetSymbol()
281 else None,
282 "file": str(frame.GetLineEntry().GetFileSpec())
283 if frame.GetLineEntry()
284 else None,
285 "line": frame.GetLineEntry().GetLine()
286 if frame.GetLineEntry()
287 else -1,
291 for prettified_frame in prettified_frames:
292 print(
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")