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(r'JIT\(.*?\)',
24 frame.GetModule().GetFileSpec().GetFilename()):
27 # Get function/filename/lineno from symbol context
28 symbol = frame.GetSymbol()
30 print 'No symbol info for compiled Java frame: ', frame
32 line_entry = frame.GetLineEntry()
33 prettified_frames.append({
34 'function': symbol.GetName(),
35 'file': str(line_entry.GetFileSpec()) if line_entry else None,
36 'line': line_entry.GetLine() if line_entry else -1
41 art_stack_visitor = frame.EvaluateExpression(
42 """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(""" +
43 str(art_frame_index) +
44 """); visitor.WalkStack(true); visitor""")
45 art_method = frame.EvaluateExpression(
46 art_stack_visitor.GetName() + """.GetMethod()""")
47 if art_method.GetValueAsUnsigned() != 0:
48 art_method_name = frame.EvaluateExpression(
49 """art::PrettyMethod(""" + art_method.GetName() + """, true)""")
50 art_method_name_data = frame.EvaluateExpression(
51 art_method_name.GetName() + """.c_str()""").GetValueAsUnsigned()
52 art_method_name_size = frame.EvaluateExpression(
53 art_method_name.GetName() + """.length()""").GetValueAsUnsigned()
54 error = lldb.SBError()
55 art_method_name = process.ReadCStringFromMemory(
56 art_method_name_data, art_method_name_size + 1, error)
58 print 'Failed to read method name'
60 if art_method_name != symbol.GetName():
61 print 'Function names in native symbol and art runtime stack do not match: ', symbol.GetName(), ' != ', art_method_name
62 art_frame_index = art_frame_index + 1
64 art_frame_index = art_frame_index + 1
67 lldb_frame_index = lldb_frame_index + 1
68 if lldb_frame_index < thread.GetNumFrames():
69 frame = thread.GetFrameAtIndex(lldb_frame_index)
70 if frame.GetModule() and re.match(
71 r'JIT\(.*?\)', frame.GetModule().GetFileSpec().GetFilename()):
72 # Another compile Java frame
73 # Don't skip; leave it to the next iteration
75 elif frame.GetSymbol() and (frame.GetSymbol().GetName() == 'art_quick_invoke_stub' or frame.GetSymbol().GetName() == 'art_quick_invoke_static_stub'):
76 # art_quick_invoke_stub / art_quick_invoke_static_stub
77 # Skip until we get past the next ArtMethod::Invoke()
79 lldb_frame_index = lldb_frame_index + 1
80 if lldb_frame_index >= thread.GetNumFrames():
81 print 'ArtMethod::Invoke not found below art_quick_invoke_stub/art_quick_invoke_static_stub'
83 frame = thread.GetFrameAtIndex(lldb_frame_index)
84 if frame.GetSymbol() and frame.GetSymbol().GetName(
85 ) == 'art::mirror::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)':
86 lldb_frame_index = lldb_frame_index + 1
89 print 'Invalid frame below compiled Java frame: ', frame
90 elif frame.GetSymbol() and frame.GetSymbol().GetName() == 'art_quick_generic_jni_trampoline':
91 # Interpreted JNI frame for x86_64
95 art_stack_visitor = frame.EvaluateExpression(
96 """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(""" +
97 str(art_frame_index) +
98 """); visitor.WalkStack(true); visitor""")
99 art_method = frame.EvaluateExpression(
100 art_stack_visitor.GetName() + """.GetMethod()""")
101 if art_method.GetValueAsUnsigned() != 0:
102 # Get function/filename/lineno from ART runtime
103 art_method_name = frame.EvaluateExpression(
104 """art::PrettyMethod(""" + art_method.GetName() + """, true)""")
105 art_method_name_data = frame.EvaluateExpression(
106 art_method_name.GetName() + """.c_str()""").GetValueAsUnsigned()
107 art_method_name_size = frame.EvaluateExpression(
108 art_method_name.GetName() + """.length()""").GetValueAsUnsigned()
109 error = lldb.SBError()
110 function = process.ReadCStringFromMemory(
111 art_method_name_data, art_method_name_size + 1, error)
113 prettified_frames.append({
114 'function': function,
119 art_frame_index = art_frame_index + 1
121 art_frame_index = art_frame_index + 1
124 lldb_frame_index = lldb_frame_index + 1
125 if lldb_frame_index < thread.GetNumFrames():
126 frame = thread.GetFrameAtIndex(lldb_frame_index)
127 if frame.GetSymbol() and (frame.GetSymbol().GetName() ==
128 'art_quick_invoke_stub' or frame.GetSymbol().GetName() == 'art_quick_invoke_static_stub'):
129 # art_quick_invoke_stub / art_quick_invoke_static_stub
130 # Skip until we get past the next ArtMethod::Invoke()
132 lldb_frame_index = lldb_frame_index + 1
133 if lldb_frame_index >= thread.GetNumFrames():
134 print 'ArtMethod::Invoke not found below art_quick_invoke_stub/art_quick_invoke_static_stub'
136 frame = thread.GetFrameAtIndex(lldb_frame_index)
137 if frame.GetSymbol() and frame.GetSymbol().GetName(
138 ) == 'art::mirror::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)':
139 lldb_frame_index = lldb_frame_index + 1
142 print 'Invalid frame below compiled Java frame: ', frame
143 elif frame.GetSymbol() and re.search(r'art::interpreter::', frame.GetSymbol().GetName()):
144 # Interpreted Java frame
147 lldb_frame_index = lldb_frame_index + 1
148 if lldb_frame_index >= thread.GetNumFrames():
149 print 'art::interpreter::Execute not found in interpreter frame'
151 frame = thread.GetFrameAtIndex(lldb_frame_index)
152 if frame.GetSymbol() and frame.GetSymbol().GetName(
153 ) == 'art::interpreter::Execute(art::Thread*, art::MethodHelper&, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue)':
158 art_stack_visitor = frame.EvaluateExpression(
159 """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(""" +
160 str(art_frame_index) +
161 """); visitor.WalkStack(true); visitor""")
162 art_method = frame.EvaluateExpression(
163 art_stack_visitor.GetName() + """.GetMethod()""")
164 if art_method.GetValueAsUnsigned() != 0:
165 # Get function/filename/lineno from ART runtime
166 art_method_name = frame.EvaluateExpression(
167 """art::PrettyMethod(""" + art_method.GetName() + """, true)""")
168 art_method_name_data = frame.EvaluateExpression(
169 art_method_name.GetName() + """.c_str()""").GetValueAsUnsigned()
170 art_method_name_size = frame.EvaluateExpression(
171 art_method_name.GetName() + """.length()""").GetValueAsUnsigned()
172 error = lldb.SBError()
173 function = process.ReadCStringFromMemory(
174 art_method_name_data, art_method_name_size + 1, error)
176 line = frame.EvaluateExpression(
177 art_stack_visitor.GetName() +
178 """.GetMethod()->GetLineNumFromDexPC(""" +
179 art_stack_visitor.GetName() +
180 """.GetDexPc(true))""").GetValueAsUnsigned()
182 file_name = frame.EvaluateExpression(
183 art_method.GetName() + """->GetDeclaringClassSourceFile()""")
184 file_name_data = file_name.GetValueAsUnsigned()
185 file_name_size = frame.EvaluateExpression(
186 """(size_t)strlen(""" + file_name.GetName() + """)""").GetValueAsUnsigned()
187 error = lldb.SBError()
188 file_name = process.ReadCStringFromMemory(
189 file_name_data, file_name_size + 1, error)
190 if not error.Success():
191 print 'Failed to read source file name'
194 prettified_frames.append({
195 'function': function,
200 art_frame_index = art_frame_index + 1
202 art_frame_index = art_frame_index + 1
206 lldb_frame_index = lldb_frame_index + 1
207 if lldb_frame_index >= thread.GetNumFrames():
208 print 'Can not get past interpreter native frames'
210 frame = thread.GetFrameAtIndex(lldb_frame_index)
211 if frame.GetSymbol() and not re.search(
212 r'art::interpreter::', frame.GetSymbol().GetName()):
215 # Other frames. Add them as-is.
216 frame = thread.GetFrameAtIndex(lldb_frame_index)
217 lldb_frame_index = lldb_frame_index + 1
218 if frame.GetModule():
219 module_name = frame.GetModule().GetFileSpec().GetFilename()
220 if not module_name in [
225 prettified_frames.append({
226 'function': frame.GetSymbol().GetName() if frame.GetSymbol() else None,
227 'file': str(frame.GetLineEntry().GetFileSpec()) if frame.GetLineEntry() else None,
228 'line': frame.GetLineEntry().GetLine() if frame.GetLineEntry() else -1
231 for prettified_frame in prettified_frames:
232 print prettified_frame['function'], prettified_frame['file'], prettified_frame['line']
235 def __lldb_init_module(debugger, internal_dict):
236 debugger.HandleCommand(
237 'command script add -f host_art_bt.host_art_bt host_art_bt')