diff options
| author | Jonas Devlieghere <jonas@devlieghere.com> | 2020-01-10 13:54:31 -0800 |
|---|---|---|
| committer | Jonas Devlieghere <jonas@devlieghere.com> | 2020-01-10 13:54:33 -0800 |
| commit | 7c47a3719a9e587fdf993637dc09d97b5397483b (patch) | |
| tree | d7c0e829d1dc98599c8b2b3a1d977f243a3030f2 /lldb/scripts/android | |
| parent | e6d219122d5a94fa8642c67c391aeb47fc032c89 (diff) | |
| download | bcm5719-llvm-7c47a3719a9e587fdf993637dc09d97b5397483b.tar.gz bcm5719-llvm-7c47a3719a9e587fdf993637dc09d97b5397483b.zip | |
[lldb/Scripts] Move android script from underneath Python dir
The scripts root directory already contains python scripts. No need to
keep this one nested under a dedicated Python directory.
Diffstat (limited to 'lldb/scripts/android')
| -rw-r--r-- | lldb/scripts/android/host_art_bt.py | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/lldb/scripts/android/host_art_bt.py b/lldb/scripts/android/host_art_bt.py new file mode 100644 index 00000000000..b4e9d7e3027 --- /dev/null +++ b/lldb/scripts/android/host_art_bt.py @@ -0,0 +1,239 @@ +# Usage: +# art/test/run-test --host --gdb [--64] [--interpreter] 004-JniTest +# 'b Java_Main_shortMethod' +# 'r' +# 'command script import host_art_bt.py' +# 'host_art_bt' + +from __future__ import print_function + +import sys +import re + +import lldb + + +def host_art_bt(debugger, command, result, internal_dict): + prettified_frames = [] + lldb_frame_index = 0 + art_frame_index = 0 + target = debugger.GetSelectedTarget() + process = target.GetProcess() + thread = process.GetSelectedThread() + while lldb_frame_index < thread.GetNumFrames(): + frame = thread.GetFrameAtIndex(lldb_frame_index) + if frame.GetModule() and re.match(r'JIT\(.*?\)', + frame.GetModule().GetFileSpec().GetFilename()): + # Compiled Java frame + + # Get function/filename/lineno from symbol context + symbol = frame.GetSymbol() + if not symbol: + print('No symbol info for compiled Java frame: ', frame) + sys.exit(1) + line_entry = frame.GetLineEntry() + prettified_frames.append({ + 'function': symbol.GetName(), + 'file': str(line_entry.GetFileSpec()) if line_entry else None, + 'line': line_entry.GetLine() if line_entry else -1 + }) + + # Skip art frames + while True: + art_stack_visitor = frame.EvaluateExpression( + """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(""" + + str(art_frame_index) + + """); visitor.WalkStack(true); visitor""") + art_method = frame.EvaluateExpression( + art_stack_visitor.GetName() + """.GetMethod()""") + if art_method.GetValueAsUnsigned() != 0: + art_method_name = frame.EvaluateExpression( + """art::PrettyMethod(""" + art_method.GetName() + """, true)""") + art_method_name_data = frame.EvaluateExpression( + art_method_name.GetName() + """.c_str()""").GetValueAsUnsigned() + art_method_name_size = frame.EvaluateExpression( + art_method_name.GetName() + """.length()""").GetValueAsUnsigned() + error = lldb.SBError() + art_method_name = process.ReadCStringFromMemory( + art_method_name_data, art_method_name_size + 1, error) + if not error.Success: + print('Failed to read method name') + sys.exit(1) + if art_method_name != symbol.GetName(): + print('Function names in native symbol and art runtime stack do not match: ', symbol.GetName(), ' != ', art_method_name) + art_frame_index = art_frame_index + 1 + break + art_frame_index = art_frame_index + 1 + + # Skip native frames + lldb_frame_index = lldb_frame_index + 1 + if lldb_frame_index < thread.GetNumFrames(): + frame = thread.GetFrameAtIndex(lldb_frame_index) + if frame.GetModule() and re.match( + r'JIT\(.*?\)', frame.GetModule().GetFileSpec().GetFilename()): + # Another compile Java frame + # Don't skip; leave it to the next iteration + continue + elif frame.GetSymbol() and (frame.GetSymbol().GetName() == 'art_quick_invoke_stub' or frame.GetSymbol().GetName() == 'art_quick_invoke_static_stub'): + # art_quick_invoke_stub / art_quick_invoke_static_stub + # Skip until we get past the next ArtMethod::Invoke() + while True: + lldb_frame_index = lldb_frame_index + 1 + if lldb_frame_index >= thread.GetNumFrames(): + print('ArtMethod::Invoke not found below art_quick_invoke_stub/art_quick_invoke_static_stub') + sys.exit(1) + frame = thread.GetFrameAtIndex(lldb_frame_index) + if frame.GetSymbol() and frame.GetSymbol().GetName( + ) == 'art::mirror::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)': + lldb_frame_index = lldb_frame_index + 1 + break + else: + print('Invalid frame below compiled Java frame: ', frame) + elif frame.GetSymbol() and frame.GetSymbol().GetName() == 'art_quick_generic_jni_trampoline': + # Interpreted JNI frame for x86_64 + + # Skip art frames + while True: + art_stack_visitor = frame.EvaluateExpression( + """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(""" + + str(art_frame_index) + + """); visitor.WalkStack(true); visitor""") + art_method = frame.EvaluateExpression( + art_stack_visitor.GetName() + """.GetMethod()""") + if art_method.GetValueAsUnsigned() != 0: + # Get function/filename/lineno from ART runtime + art_method_name = frame.EvaluateExpression( + """art::PrettyMethod(""" + art_method.GetName() + """, true)""") + art_method_name_data = frame.EvaluateExpression( + art_method_name.GetName() + """.c_str()""").GetValueAsUnsigned() + art_method_name_size = frame.EvaluateExpression( + art_method_name.GetName() + """.length()""").GetValueAsUnsigned() + error = lldb.SBError() + function = process.ReadCStringFromMemory( + art_method_name_data, art_method_name_size + 1, error) + + prettified_frames.append({ + 'function': function, + 'file': None, + 'line': -1 + }) + + art_frame_index = art_frame_index + 1 + break + art_frame_index = art_frame_index + 1 + + # Skip native frames + lldb_frame_index = lldb_frame_index + 1 + if lldb_frame_index < thread.GetNumFrames(): + frame = thread.GetFrameAtIndex(lldb_frame_index) + if frame.GetSymbol() and (frame.GetSymbol().GetName() == + 'art_quick_invoke_stub' or frame.GetSymbol().GetName() == 'art_quick_invoke_static_stub'): + # art_quick_invoke_stub / art_quick_invoke_static_stub + # Skip until we get past the next ArtMethod::Invoke() + while True: + lldb_frame_index = lldb_frame_index + 1 + if lldb_frame_index >= thread.GetNumFrames(): + print('ArtMethod::Invoke not found below art_quick_invoke_stub/art_quick_invoke_static_stub') + sys.exit(1) + frame = thread.GetFrameAtIndex(lldb_frame_index) + if frame.GetSymbol() and frame.GetSymbol().GetName( + ) == 'art::mirror::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)': + lldb_frame_index = lldb_frame_index + 1 + break + else: + print('Invalid frame below compiled Java frame: ', frame) + elif frame.GetSymbol() and re.search(r'art::interpreter::', frame.GetSymbol().GetName()): + # Interpreted Java frame + + while True: + lldb_frame_index = lldb_frame_index + 1 + if lldb_frame_index >= thread.GetNumFrames(): + print('art::interpreter::Execute not found in interpreter frame') + sys.exit(1) + frame = thread.GetFrameAtIndex(lldb_frame_index) + if frame.GetSymbol() and frame.GetSymbol().GetName( + ) == 'art::interpreter::Execute(art::Thread*, art::MethodHelper&, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue)': + break + + # Skip art frames + while True: + art_stack_visitor = frame.EvaluateExpression( + """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(""" + + str(art_frame_index) + + """); visitor.WalkStack(true); visitor""") + art_method = frame.EvaluateExpression( + art_stack_visitor.GetName() + """.GetMethod()""") + if art_method.GetValueAsUnsigned() != 0: + # Get function/filename/lineno from ART runtime + art_method_name = frame.EvaluateExpression( + """art::PrettyMethod(""" + art_method.GetName() + """, true)""") + art_method_name_data = frame.EvaluateExpression( + art_method_name.GetName() + """.c_str()""").GetValueAsUnsigned() + art_method_name_size = frame.EvaluateExpression( + art_method_name.GetName() + """.length()""").GetValueAsUnsigned() + error = lldb.SBError() + function = process.ReadCStringFromMemory( + art_method_name_data, art_method_name_size + 1, error) + + line = frame.EvaluateExpression( + art_stack_visitor.GetName() + + """.GetMethod()->GetLineNumFromDexPC(""" + + art_stack_visitor.GetName() + + """.GetDexPc(true))""").GetValueAsUnsigned() + + file_name = frame.EvaluateExpression( + art_method.GetName() + """->GetDeclaringClassSourceFile()""") + file_name_data = file_name.GetValueAsUnsigned() + file_name_size = frame.EvaluateExpression( + """(size_t)strlen(""" + file_name.GetName() + """)""").GetValueAsUnsigned() + error = lldb.SBError() + file_name = process.ReadCStringFromMemory( + file_name_data, file_name_size + 1, error) + if not error.Success(): + print('Failed to read source file name') + sys.exit(1) + + prettified_frames.append({ + 'function': function, + 'file': file_name, + 'line': line + }) + + art_frame_index = art_frame_index + 1 + break + art_frame_index = art_frame_index + 1 + + # Skip native frames + while True: + lldb_frame_index = lldb_frame_index + 1 + if lldb_frame_index >= thread.GetNumFrames(): + print('Can not get past interpreter native frames') + sys.exit(1) + frame = thread.GetFrameAtIndex(lldb_frame_index) + if frame.GetSymbol() and not re.search( + r'art::interpreter::', frame.GetSymbol().GetName()): + break + else: + # Other frames. Add them as-is. + frame = thread.GetFrameAtIndex(lldb_frame_index) + lldb_frame_index = lldb_frame_index + 1 + if frame.GetModule(): + module_name = frame.GetModule().GetFileSpec().GetFilename() + if not module_name in [ + 'libartd.so', + 'dalvikvm32', + 'dalvikvm64', + 'libc.so.6']: + prettified_frames.append({ + 'function': frame.GetSymbol().GetName() if frame.GetSymbol() else None, + 'file': str(frame.GetLineEntry().GetFileSpec()) if frame.GetLineEntry() else None, + 'line': frame.GetLineEntry().GetLine() if frame.GetLineEntry() else -1 + }) + + for prettified_frame in prettified_frames: + print(prettified_frame['function'], prettified_frame['file'], prettified_frame['line']) + + +def __lldb_init_module(debugger, internal_dict): + debugger.HandleCommand( + 'command script add -f host_art_bt.host_art_bt host_art_bt') |

