brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.0 KiB · d4c5af4 Raw
301 lines · python
1# Usage:2#   art/test/run-test --host --gdb [--64] [--interpreter] 004-JniTest3#   'b Java_Main_shortMethod'4#   'r'5#   'command script import host_art_bt.py'6#   'host_art_bt'7 8import sys9import re10 11import lldb12 13 14def host_art_bt(debugger, command, result, internal_dict):15    prettified_frames = []16    lldb_frame_index = 017    art_frame_index = 018    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()25        ):26            # Compiled Java frame27 28            # Get function/filename/lineno from symbol context29            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(35                {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,39                }40            )41 42            # Skip art frames43            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"""48                )49                art_method = frame.EvaluateExpression(50                    art_stack_visitor.GetName() + """.GetMethod()"""51                )52                if art_method.GetValueAsUnsigned() != 0:53                    art_method_name = frame.EvaluateExpression(54                        """art::PrettyMethod(""" + art_method.GetName() + """, true)"""55                    )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, error65                    )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,75                        )76                    art_frame_index = art_frame_index + 177                    break78                art_frame_index = art_frame_index + 179 80            # Skip native frames81            lldb_frame_index = lldb_frame_index + 182            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()86                ):87                    # Another compile Java frame88                    # Don't skip; leave it to the next iteration89                    continue90                elif frame.GetSymbol() and (91                    frame.GetSymbol().GetName() == "art_quick_invoke_stub"92                    or frame.GetSymbol().GetName() == "art_quick_invoke_static_stub"93                ):94                    # art_quick_invoke_stub / art_quick_invoke_static_stub95                    # Skip until we get past the next ArtMethod::Invoke()96                    while True:97                        lldb_frame_index = lldb_frame_index + 198                        if lldb_frame_index >= thread.GetNumFrames():99                            print(100                                "ArtMethod::Invoke not found below art_quick_invoke_stub/art_quick_invoke_static_stub"101                            )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*)"108                        ):109                            lldb_frame_index = lldb_frame_index + 1110                            break111                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"116        ):117            # Interpreted JNI frame for x86_64118 119            # Skip art frames120            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"""125                )126                art_method = frame.EvaluateExpression(127                    art_stack_visitor.GetName() + """.GetMethod()"""128                )129                if art_method.GetValueAsUnsigned() != 0:130                    # Get function/filename/lineno from ART runtime131                    art_method_name = frame.EvaluateExpression(132                        """art::PrettyMethod(""" + art_method.GetName() + """, true)"""133                    )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, error143                    )144 145                    prettified_frames.append(146                        {"function": function, "file": None, "line": -1}147                    )148 149                    art_frame_index = art_frame_index + 1150                    break151                art_frame_index = art_frame_index + 1152 153            # Skip native frames154            lldb_frame_index = lldb_frame_index + 1155            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"160                ):161                    # art_quick_invoke_stub / art_quick_invoke_static_stub162                    # Skip until we get past the next ArtMethod::Invoke()163                    while True:164                        lldb_frame_index = lldb_frame_index + 1165                        if lldb_frame_index >= thread.GetNumFrames():166                            print(167                                "ArtMethod::Invoke not found below art_quick_invoke_stub/art_quick_invoke_static_stub"168                            )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*)"175                        ):176                            lldb_frame_index = lldb_frame_index + 1177                            break178                else:179                    print("Invalid frame below compiled Java frame: ", frame)180        elif frame.GetSymbol() and re.search(181            r"art::interpreter::", frame.GetSymbol().GetName()182        ):183            # Interpreted Java frame184 185            while True:186                lldb_frame_index = lldb_frame_index + 1187                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)"195                ):196                    break197 198            # Skip art frames199            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"""204                )205                art_method = frame.EvaluateExpression(206                    art_stack_visitor.GetName() + """.GetMethod()"""207                )208                if art_method.GetValueAsUnsigned() != 0:209                    # Get function/filename/lineno from ART runtime210                    art_method_name = frame.EvaluateExpression(211                        """art::PrettyMethod(""" + art_method.GetName() + """, true)"""212                    )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, error222                    )223 224                    line = frame.EvaluateExpression(225                        art_stack_visitor.GetName()226                        + """.GetMethod()->GetLineNumFromDexPC("""227                        + art_stack_visitor.GetName()228                        + """.GetDexPc(true))"""229                    ).GetValueAsUnsigned()230 231                    file_name = frame.EvaluateExpression(232                        art_method.GetName() + """->GetDeclaringClassSourceFile()"""233                    )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, error241                    )242                    if not error.Success():243                        print("Failed to read source file name")244                        sys.exit(1)245 246                    prettified_frames.append(247                        {"function": function, "file": file_name, "line": line}248                    )249 250                    art_frame_index = art_frame_index + 1251                    break252                art_frame_index = art_frame_index + 1253 254            # Skip native frames255            while True:256                lldb_frame_index = lldb_frame_index + 1257                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()263                ):264                    break265        else:266            # Other frames. Add them as-is.267            frame = thread.GetFrameAtIndex(lldb_frame_index)268            lldb_frame_index = lldb_frame_index + 1269            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",276                ]:277                    prettified_frames.append(278                        {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,288                        }289                    )290 291    for prettified_frame in prettified_frames:292        print(293            prettified_frame["function"],294            prettified_frame["file"],295            prettified_frame["line"],296        )297 298 299def __lldb_init_module(debugger, internal_dict):300    debugger.HandleCommand("command script add -f host_art_bt.host_art_bt host_art_bt")301