1061da546Spatrick""" 2061da546SpatrickThis LLDB module contains miscellaneous utilities. 3061da546SpatrickSome of the test suite takes advantage of the utility functions defined here. 4061da546SpatrickThey can also be useful for general purpose lldb scripting. 5061da546Spatrick""" 6061da546Spatrick 7061da546Spatrickfrom __future__ import print_function 8061da546Spatrickfrom __future__ import absolute_import 9061da546Spatrick 10061da546Spatrick# System modules 11061da546Spatrickimport errno 12061da546Spatrickimport os 13061da546Spatrickimport re 14061da546Spatrickimport sys 15*be691f3bSpatrickimport subprocess 16061da546Spatrick 17061da546Spatrick# Third-party modules 18061da546Spatrickfrom six import StringIO as SixStringIO 19061da546Spatrickimport six 20061da546Spatrick 21061da546Spatrick# LLDB modules 22061da546Spatrickimport lldb 23061da546Spatrickfrom . import lldbtest_config 24*be691f3bSpatrickfrom . import configuration 25061da546Spatrick 26*be691f3bSpatrick# How often failed simulator process launches are retried. 27*be691f3bSpatrickSIMULATOR_RETRY = 3 28061da546Spatrick 29061da546Spatrick# =================================================== 30061da546Spatrick# Utilities for locating/checking executable programs 31061da546Spatrick# =================================================== 32061da546Spatrick 33061da546Spatrickdef is_exe(fpath): 34061da546Spatrick """Returns True if fpath is an executable.""" 35061da546Spatrick return os.path.isfile(fpath) and os.access(fpath, os.X_OK) 36061da546Spatrick 37061da546Spatrick 38061da546Spatrickdef which(program): 39061da546Spatrick """Returns the full path to a program; None otherwise.""" 40061da546Spatrick fpath, fname = os.path.split(program) 41061da546Spatrick if fpath: 42061da546Spatrick if is_exe(program): 43061da546Spatrick return program 44061da546Spatrick else: 45061da546Spatrick for path in os.environ["PATH"].split(os.pathsep): 46061da546Spatrick exe_file = os.path.join(path, program) 47061da546Spatrick if is_exe(exe_file): 48061da546Spatrick return exe_file 49061da546Spatrick return None 50061da546Spatrick 51061da546Spatrickdef mkdir_p(path): 52061da546Spatrick try: 53061da546Spatrick os.makedirs(path) 54061da546Spatrick except OSError as e: 55061da546Spatrick if e.errno != errno.EEXIST: 56061da546Spatrick raise 57061da546Spatrick if not os.path.isdir(path): 58061da546Spatrick raise OSError(errno.ENOTDIR, "%s is not a directory"%path) 59*be691f3bSpatrick 60*be691f3bSpatrick 61*be691f3bSpatrick# ============================ 62*be691f3bSpatrick# Dealing with SDK and triples 63*be691f3bSpatrick# ============================ 64*be691f3bSpatrick 65*be691f3bSpatrickdef get_xcode_sdk(os, env): 66*be691f3bSpatrick # Respect --apple-sdk <path> if it's specified. If the SDK is simply 67*be691f3bSpatrick # mounted from some disk image, and not actually installed, this is the 68*be691f3bSpatrick # only way to use it. 69*be691f3bSpatrick if configuration.apple_sdk: 70*be691f3bSpatrick return configuration.apple_sdk 71*be691f3bSpatrick if os == "ios": 72*be691f3bSpatrick if env == "simulator": 73*be691f3bSpatrick return "iphonesimulator" 74*be691f3bSpatrick if env == "macabi": 75*be691f3bSpatrick return "macosx" 76*be691f3bSpatrick return "iphoneos" 77*be691f3bSpatrick elif os == "tvos": 78*be691f3bSpatrick if env == "simulator": 79*be691f3bSpatrick return "appletvsimulator" 80*be691f3bSpatrick return "appletvos" 81*be691f3bSpatrick elif os == "watchos": 82*be691f3bSpatrick if env == "simulator": 83*be691f3bSpatrick return "watchsimulator" 84*be691f3bSpatrick return "watchos" 85*be691f3bSpatrick return os 86*be691f3bSpatrick 87*be691f3bSpatrick 88*be691f3bSpatrickdef get_xcode_sdk_version(sdk): 89*be691f3bSpatrick return subprocess.check_output( 90*be691f3bSpatrick ['xcrun', '--sdk', sdk, '--show-sdk-version']).rstrip().decode('utf-8') 91*be691f3bSpatrick 92*be691f3bSpatrick 93*be691f3bSpatrickdef get_xcode_sdk_root(sdk): 94*be691f3bSpatrick return subprocess.check_output(['xcrun', '--sdk', sdk, '--show-sdk-path' 95*be691f3bSpatrick ]).rstrip().decode('utf-8') 96*be691f3bSpatrick 97*be691f3bSpatrick 98*be691f3bSpatrickdef get_xcode_clang(sdk): 99*be691f3bSpatrick return subprocess.check_output(['xcrun', '-sdk', sdk, '-f', 'clang' 100*be691f3bSpatrick ]).rstrip().decode("utf-8") 101*be691f3bSpatrick 102*be691f3bSpatrick 103061da546Spatrick# =================================================== 104061da546Spatrick# Disassembly for an SBFunction or an SBSymbol object 105061da546Spatrick# =================================================== 106061da546Spatrick 107061da546Spatrick 108061da546Spatrickdef disassemble(target, function_or_symbol): 109061da546Spatrick """Disassemble the function or symbol given a target. 110061da546Spatrick 111061da546Spatrick It returns the disassembly content in a string object. 112061da546Spatrick """ 113061da546Spatrick buf = SixStringIO() 114061da546Spatrick insts = function_or_symbol.GetInstructions(target) 115061da546Spatrick for i in insts: 116061da546Spatrick print(i, file=buf) 117061da546Spatrick return buf.getvalue() 118061da546Spatrick 119061da546Spatrick# ========================================================== 120061da546Spatrick# Integer (byte size 1, 2, 4, and 8) to bytearray conversion 121061da546Spatrick# ========================================================== 122061da546Spatrick 123061da546Spatrick 124061da546Spatrickdef int_to_bytearray(val, bytesize): 125061da546Spatrick """Utility function to convert an integer into a bytearray. 126061da546Spatrick 127061da546Spatrick It returns the bytearray in the little endian format. It is easy to get the 128061da546Spatrick big endian format, just do ba.reverse() on the returned object. 129061da546Spatrick """ 130061da546Spatrick import struct 131061da546Spatrick 132061da546Spatrick if bytesize == 1: 133061da546Spatrick return bytearray([val]) 134061da546Spatrick 135061da546Spatrick # Little endian followed by a format character. 136061da546Spatrick template = "<%c" 137061da546Spatrick if bytesize == 2: 138061da546Spatrick fmt = template % 'h' 139061da546Spatrick elif bytesize == 4: 140061da546Spatrick fmt = template % 'i' 141061da546Spatrick elif bytesize == 4: 142061da546Spatrick fmt = template % 'q' 143061da546Spatrick else: 144061da546Spatrick return None 145061da546Spatrick 146061da546Spatrick packed = struct.pack(fmt, val) 147061da546Spatrick return bytearray(packed) 148061da546Spatrick 149061da546Spatrick 150061da546Spatrickdef bytearray_to_int(bytes, bytesize): 151061da546Spatrick """Utility function to convert a bytearray into an integer. 152061da546Spatrick 153061da546Spatrick It interprets the bytearray in the little endian format. For a big endian 154061da546Spatrick bytearray, just do ba.reverse() on the object before passing it in. 155061da546Spatrick """ 156061da546Spatrick import struct 157061da546Spatrick 158061da546Spatrick if bytesize == 1: 159061da546Spatrick return bytes[0] 160061da546Spatrick 161061da546Spatrick # Little endian followed by a format character. 162061da546Spatrick template = "<%c" 163061da546Spatrick if bytesize == 2: 164061da546Spatrick fmt = template % 'h' 165061da546Spatrick elif bytesize == 4: 166061da546Spatrick fmt = template % 'i' 167061da546Spatrick elif bytesize == 4: 168061da546Spatrick fmt = template % 'q' 169061da546Spatrick else: 170061da546Spatrick return None 171061da546Spatrick 172061da546Spatrick unpacked = struct.unpack_from(fmt, bytes) 173061da546Spatrick return unpacked[0] 174061da546Spatrick 175061da546Spatrick 176061da546Spatrick# ============================================================== 177061da546Spatrick# Get the description of an lldb object or None if not available 178061da546Spatrick# ============================================================== 179061da546Spatrickdef get_description(obj, option=None): 180061da546Spatrick """Calls lldb_obj.GetDescription() and returns a string, or None. 181061da546Spatrick 182061da546Spatrick For SBTarget, SBBreakpointLocation, and SBWatchpoint lldb objects, an extra 183061da546Spatrick option can be passed in to describe the detailed level of description 184061da546Spatrick desired: 185061da546Spatrick o lldb.eDescriptionLevelBrief 186061da546Spatrick o lldb.eDescriptionLevelFull 187061da546Spatrick o lldb.eDescriptionLevelVerbose 188061da546Spatrick """ 189061da546Spatrick method = getattr(obj, 'GetDescription') 190061da546Spatrick if not method: 191061da546Spatrick return None 192061da546Spatrick tuple = (lldb.SBTarget, lldb.SBBreakpointLocation, lldb.SBWatchpoint) 193061da546Spatrick if isinstance(obj, tuple): 194061da546Spatrick if option is None: 195061da546Spatrick option = lldb.eDescriptionLevelBrief 196061da546Spatrick 197061da546Spatrick stream = lldb.SBStream() 198061da546Spatrick if option is None: 199061da546Spatrick success = method(stream) 200061da546Spatrick else: 201061da546Spatrick success = method(stream, option) 202061da546Spatrick if not success: 203061da546Spatrick return None 204061da546Spatrick return stream.GetData() 205061da546Spatrick 206061da546Spatrick 207061da546Spatrick# ================================================= 208061da546Spatrick# Convert some enum value to its string counterpart 209061da546Spatrick# ================================================= 210061da546Spatrick 211061da546Spatrickdef state_type_to_str(enum): 212061da546Spatrick """Returns the stateType string given an enum.""" 213061da546Spatrick if enum == lldb.eStateInvalid: 214061da546Spatrick return "invalid" 215061da546Spatrick elif enum == lldb.eStateUnloaded: 216061da546Spatrick return "unloaded" 217061da546Spatrick elif enum == lldb.eStateConnected: 218061da546Spatrick return "connected" 219061da546Spatrick elif enum == lldb.eStateAttaching: 220061da546Spatrick return "attaching" 221061da546Spatrick elif enum == lldb.eStateLaunching: 222061da546Spatrick return "launching" 223061da546Spatrick elif enum == lldb.eStateStopped: 224061da546Spatrick return "stopped" 225061da546Spatrick elif enum == lldb.eStateRunning: 226061da546Spatrick return "running" 227061da546Spatrick elif enum == lldb.eStateStepping: 228061da546Spatrick return "stepping" 229061da546Spatrick elif enum == lldb.eStateCrashed: 230061da546Spatrick return "crashed" 231061da546Spatrick elif enum == lldb.eStateDetached: 232061da546Spatrick return "detached" 233061da546Spatrick elif enum == lldb.eStateExited: 234061da546Spatrick return "exited" 235061da546Spatrick elif enum == lldb.eStateSuspended: 236061da546Spatrick return "suspended" 237061da546Spatrick else: 238061da546Spatrick raise Exception("Unknown StateType enum") 239061da546Spatrick 240061da546Spatrick 241061da546Spatrickdef stop_reason_to_str(enum): 242061da546Spatrick """Returns the stopReason string given an enum.""" 243061da546Spatrick if enum == lldb.eStopReasonInvalid: 244061da546Spatrick return "invalid" 245061da546Spatrick elif enum == lldb.eStopReasonNone: 246061da546Spatrick return "none" 247061da546Spatrick elif enum == lldb.eStopReasonTrace: 248061da546Spatrick return "trace" 249061da546Spatrick elif enum == lldb.eStopReasonBreakpoint: 250061da546Spatrick return "breakpoint" 251061da546Spatrick elif enum == lldb.eStopReasonWatchpoint: 252061da546Spatrick return "watchpoint" 253061da546Spatrick elif enum == lldb.eStopReasonExec: 254061da546Spatrick return "exec" 255*be691f3bSpatrick elif enum == lldb.eStopReasonFork: 256*be691f3bSpatrick return "fork" 257*be691f3bSpatrick elif enum == lldb.eStopReasonVFork: 258*be691f3bSpatrick return "vfork" 259*be691f3bSpatrick elif enum == lldb.eStopReasonVForkDone: 260*be691f3bSpatrick return "vforkdone" 261061da546Spatrick elif enum == lldb.eStopReasonSignal: 262061da546Spatrick return "signal" 263061da546Spatrick elif enum == lldb.eStopReasonException: 264061da546Spatrick return "exception" 265061da546Spatrick elif enum == lldb.eStopReasonPlanComplete: 266061da546Spatrick return "plancomplete" 267061da546Spatrick elif enum == lldb.eStopReasonThreadExiting: 268061da546Spatrick return "threadexiting" 269061da546Spatrick else: 270061da546Spatrick raise Exception("Unknown StopReason enum") 271061da546Spatrick 272061da546Spatrick 273061da546Spatrickdef symbol_type_to_str(enum): 274061da546Spatrick """Returns the symbolType string given an enum.""" 275061da546Spatrick if enum == lldb.eSymbolTypeInvalid: 276061da546Spatrick return "invalid" 277061da546Spatrick elif enum == lldb.eSymbolTypeAbsolute: 278061da546Spatrick return "absolute" 279061da546Spatrick elif enum == lldb.eSymbolTypeCode: 280061da546Spatrick return "code" 281061da546Spatrick elif enum == lldb.eSymbolTypeData: 282061da546Spatrick return "data" 283061da546Spatrick elif enum == lldb.eSymbolTypeTrampoline: 284061da546Spatrick return "trampoline" 285061da546Spatrick elif enum == lldb.eSymbolTypeRuntime: 286061da546Spatrick return "runtime" 287061da546Spatrick elif enum == lldb.eSymbolTypeException: 288061da546Spatrick return "exception" 289061da546Spatrick elif enum == lldb.eSymbolTypeSourceFile: 290061da546Spatrick return "sourcefile" 291061da546Spatrick elif enum == lldb.eSymbolTypeHeaderFile: 292061da546Spatrick return "headerfile" 293061da546Spatrick elif enum == lldb.eSymbolTypeObjectFile: 294061da546Spatrick return "objectfile" 295061da546Spatrick elif enum == lldb.eSymbolTypeCommonBlock: 296061da546Spatrick return "commonblock" 297061da546Spatrick elif enum == lldb.eSymbolTypeBlock: 298061da546Spatrick return "block" 299061da546Spatrick elif enum == lldb.eSymbolTypeLocal: 300061da546Spatrick return "local" 301061da546Spatrick elif enum == lldb.eSymbolTypeParam: 302061da546Spatrick return "param" 303061da546Spatrick elif enum == lldb.eSymbolTypeVariable: 304061da546Spatrick return "variable" 305061da546Spatrick elif enum == lldb.eSymbolTypeVariableType: 306061da546Spatrick return "variabletype" 307061da546Spatrick elif enum == lldb.eSymbolTypeLineEntry: 308061da546Spatrick return "lineentry" 309061da546Spatrick elif enum == lldb.eSymbolTypeLineHeader: 310061da546Spatrick return "lineheader" 311061da546Spatrick elif enum == lldb.eSymbolTypeScopeBegin: 312061da546Spatrick return "scopebegin" 313061da546Spatrick elif enum == lldb.eSymbolTypeScopeEnd: 314061da546Spatrick return "scopeend" 315061da546Spatrick elif enum == lldb.eSymbolTypeAdditional: 316061da546Spatrick return "additional" 317061da546Spatrick elif enum == lldb.eSymbolTypeCompiler: 318061da546Spatrick return "compiler" 319061da546Spatrick elif enum == lldb.eSymbolTypeInstrumentation: 320061da546Spatrick return "instrumentation" 321061da546Spatrick elif enum == lldb.eSymbolTypeUndefined: 322061da546Spatrick return "undefined" 323061da546Spatrick 324061da546Spatrick 325061da546Spatrickdef value_type_to_str(enum): 326061da546Spatrick """Returns the valueType string given an enum.""" 327061da546Spatrick if enum == lldb.eValueTypeInvalid: 328061da546Spatrick return "invalid" 329061da546Spatrick elif enum == lldb.eValueTypeVariableGlobal: 330061da546Spatrick return "global_variable" 331061da546Spatrick elif enum == lldb.eValueTypeVariableStatic: 332061da546Spatrick return "static_variable" 333061da546Spatrick elif enum == lldb.eValueTypeVariableArgument: 334061da546Spatrick return "argument_variable" 335061da546Spatrick elif enum == lldb.eValueTypeVariableLocal: 336061da546Spatrick return "local_variable" 337061da546Spatrick elif enum == lldb.eValueTypeRegister: 338061da546Spatrick return "register" 339061da546Spatrick elif enum == lldb.eValueTypeRegisterSet: 340061da546Spatrick return "register_set" 341061da546Spatrick elif enum == lldb.eValueTypeConstResult: 342061da546Spatrick return "constant_result" 343061da546Spatrick else: 344061da546Spatrick raise Exception("Unknown ValueType enum") 345061da546Spatrick 346061da546Spatrick 347061da546Spatrick# ================================================== 348061da546Spatrick# Get stopped threads due to each stop reason. 349061da546Spatrick# ================================================== 350061da546Spatrick 351061da546Spatrickdef sort_stopped_threads(process, 352061da546Spatrick breakpoint_threads=None, 353061da546Spatrick crashed_threads=None, 354061da546Spatrick watchpoint_threads=None, 355061da546Spatrick signal_threads=None, 356061da546Spatrick exiting_threads=None, 357061da546Spatrick other_threads=None): 358061da546Spatrick """ Fills array *_threads with threads stopped for the corresponding stop 359061da546Spatrick reason. 360061da546Spatrick """ 361061da546Spatrick for lst in [breakpoint_threads, 362061da546Spatrick watchpoint_threads, 363061da546Spatrick signal_threads, 364061da546Spatrick exiting_threads, 365061da546Spatrick other_threads]: 366061da546Spatrick if lst is not None: 367061da546Spatrick lst[:] = [] 368061da546Spatrick 369061da546Spatrick for thread in process: 370061da546Spatrick dispatched = False 371061da546Spatrick for (reason, list) in [(lldb.eStopReasonBreakpoint, breakpoint_threads), 372061da546Spatrick (lldb.eStopReasonException, crashed_threads), 373061da546Spatrick (lldb.eStopReasonWatchpoint, watchpoint_threads), 374061da546Spatrick (lldb.eStopReasonSignal, signal_threads), 375061da546Spatrick (lldb.eStopReasonThreadExiting, exiting_threads), 376061da546Spatrick (None, other_threads)]: 377061da546Spatrick if not dispatched and list is not None: 378061da546Spatrick if thread.GetStopReason() == reason or reason is None: 379061da546Spatrick list.append(thread) 380061da546Spatrick dispatched = True 381061da546Spatrick 382061da546Spatrick# ================================================== 383061da546Spatrick# Utility functions for setting breakpoints 384061da546Spatrick# ================================================== 385061da546Spatrick 386061da546Spatrickdef run_break_set_by_script( 387061da546Spatrick test, 388061da546Spatrick class_name, 389061da546Spatrick extra_options=None, 390061da546Spatrick num_expected_locations=1): 391061da546Spatrick """Set a scripted breakpoint. Check that it got the right number of locations.""" 392061da546Spatrick test.assertTrue(class_name is not None, "Must pass in a class name.") 393061da546Spatrick command = "breakpoint set -P " + class_name 394061da546Spatrick if extra_options is not None: 395061da546Spatrick command += " " + extra_options 396061da546Spatrick 397061da546Spatrick break_results = run_break_set_command(test, command) 398061da546Spatrick check_breakpoint_result(test, break_results, num_locations=num_expected_locations) 399061da546Spatrick return get_bpno_from_match(break_results) 400061da546Spatrick 401061da546Spatrickdef run_break_set_by_file_and_line( 402061da546Spatrick test, 403061da546Spatrick file_name, 404061da546Spatrick line_number, 405061da546Spatrick extra_options=None, 406061da546Spatrick num_expected_locations=1, 407061da546Spatrick loc_exact=False, 408061da546Spatrick module_name=None): 409061da546Spatrick """Set a breakpoint by file and line, returning the breakpoint number. 410061da546Spatrick 411061da546Spatrick If extra_options is not None, then we append it to the breakpoint set command. 412061da546Spatrick 413061da546Spatrick If num_expected_locations is -1, we check that we got AT LEAST one location. If num_expected_locations is -2, we don't 414061da546Spatrick check the actual number at all. Otherwise, we check that num_expected_locations equals the number of locations. 415061da546Spatrick 416061da546Spatrick If loc_exact is true, we check that there is one location, and that location must be at the input file and line number.""" 417061da546Spatrick 418061da546Spatrick if file_name is None: 419061da546Spatrick command = 'breakpoint set -l %d' % (line_number) 420061da546Spatrick else: 421061da546Spatrick command = 'breakpoint set -f "%s" -l %d' % (file_name, line_number) 422061da546Spatrick 423061da546Spatrick if module_name: 424061da546Spatrick command += " --shlib '%s'" % (module_name) 425061da546Spatrick 426061da546Spatrick if extra_options: 427061da546Spatrick command += " " + extra_options 428061da546Spatrick 429061da546Spatrick break_results = run_break_set_command(test, command) 430061da546Spatrick 431061da546Spatrick if num_expected_locations == 1 and loc_exact: 432061da546Spatrick check_breakpoint_result( 433061da546Spatrick test, 434061da546Spatrick break_results, 435061da546Spatrick num_locations=num_expected_locations, 436061da546Spatrick file_name=file_name, 437061da546Spatrick line_number=line_number, 438061da546Spatrick module_name=module_name) 439061da546Spatrick else: 440061da546Spatrick check_breakpoint_result( 441061da546Spatrick test, 442061da546Spatrick break_results, 443061da546Spatrick num_locations=num_expected_locations) 444061da546Spatrick 445061da546Spatrick return get_bpno_from_match(break_results) 446061da546Spatrick 447061da546Spatrick 448061da546Spatrickdef run_break_set_by_symbol( 449061da546Spatrick test, 450061da546Spatrick symbol, 451061da546Spatrick extra_options=None, 452061da546Spatrick num_expected_locations=-1, 453061da546Spatrick sym_exact=False, 454061da546Spatrick module_name=None): 455061da546Spatrick """Set a breakpoint by symbol name. Common options are the same as run_break_set_by_file_and_line. 456061da546Spatrick 457061da546Spatrick If sym_exact is true, then the output symbol must match the input exactly, otherwise we do a substring match.""" 458061da546Spatrick command = 'breakpoint set -n "%s"' % (symbol) 459061da546Spatrick 460061da546Spatrick if module_name: 461061da546Spatrick command += " --shlib '%s'" % (module_name) 462061da546Spatrick 463061da546Spatrick if extra_options: 464061da546Spatrick command += " " + extra_options 465061da546Spatrick 466061da546Spatrick break_results = run_break_set_command(test, command) 467061da546Spatrick 468061da546Spatrick if num_expected_locations == 1 and sym_exact: 469061da546Spatrick check_breakpoint_result( 470061da546Spatrick test, 471061da546Spatrick break_results, 472061da546Spatrick num_locations=num_expected_locations, 473061da546Spatrick symbol_name=symbol, 474061da546Spatrick module_name=module_name) 475061da546Spatrick else: 476061da546Spatrick check_breakpoint_result( 477061da546Spatrick test, 478061da546Spatrick break_results, 479061da546Spatrick num_locations=num_expected_locations) 480061da546Spatrick 481061da546Spatrick return get_bpno_from_match(break_results) 482061da546Spatrick 483061da546Spatrick 484061da546Spatrickdef run_break_set_by_selector( 485061da546Spatrick test, 486061da546Spatrick selector, 487061da546Spatrick extra_options=None, 488061da546Spatrick num_expected_locations=-1, 489061da546Spatrick module_name=None): 490061da546Spatrick """Set a breakpoint by selector. Common options are the same as run_break_set_by_file_and_line.""" 491061da546Spatrick 492061da546Spatrick command = 'breakpoint set -S "%s"' % (selector) 493061da546Spatrick 494061da546Spatrick if module_name: 495061da546Spatrick command += ' --shlib "%s"' % (module_name) 496061da546Spatrick 497061da546Spatrick if extra_options: 498061da546Spatrick command += " " + extra_options 499061da546Spatrick 500061da546Spatrick break_results = run_break_set_command(test, command) 501061da546Spatrick 502061da546Spatrick if num_expected_locations == 1: 503061da546Spatrick check_breakpoint_result( 504061da546Spatrick test, 505061da546Spatrick break_results, 506061da546Spatrick num_locations=num_expected_locations, 507061da546Spatrick symbol_name=selector, 508061da546Spatrick symbol_match_exact=False, 509061da546Spatrick module_name=module_name) 510061da546Spatrick else: 511061da546Spatrick check_breakpoint_result( 512061da546Spatrick test, 513061da546Spatrick break_results, 514061da546Spatrick num_locations=num_expected_locations) 515061da546Spatrick 516061da546Spatrick return get_bpno_from_match(break_results) 517061da546Spatrick 518061da546Spatrick 519061da546Spatrickdef run_break_set_by_regexp( 520061da546Spatrick test, 521061da546Spatrick regexp, 522061da546Spatrick extra_options=None, 523061da546Spatrick num_expected_locations=-1): 524061da546Spatrick """Set a breakpoint by regular expression match on symbol name. Common options are the same as run_break_set_by_file_and_line.""" 525061da546Spatrick 526061da546Spatrick command = 'breakpoint set -r "%s"' % (regexp) 527061da546Spatrick if extra_options: 528061da546Spatrick command += " " + extra_options 529061da546Spatrick 530061da546Spatrick break_results = run_break_set_command(test, command) 531061da546Spatrick 532061da546Spatrick check_breakpoint_result( 533061da546Spatrick test, 534061da546Spatrick break_results, 535061da546Spatrick num_locations=num_expected_locations) 536061da546Spatrick 537061da546Spatrick return get_bpno_from_match(break_results) 538061da546Spatrick 539061da546Spatrick 540061da546Spatrickdef run_break_set_by_source_regexp( 541061da546Spatrick test, 542061da546Spatrick regexp, 543061da546Spatrick extra_options=None, 544061da546Spatrick num_expected_locations=-1): 545061da546Spatrick """Set a breakpoint by source regular expression. Common options are the same as run_break_set_by_file_and_line.""" 546061da546Spatrick command = 'breakpoint set -p "%s"' % (regexp) 547061da546Spatrick if extra_options: 548061da546Spatrick command += " " + extra_options 549061da546Spatrick 550061da546Spatrick break_results = run_break_set_command(test, command) 551061da546Spatrick 552061da546Spatrick check_breakpoint_result( 553061da546Spatrick test, 554061da546Spatrick break_results, 555061da546Spatrick num_locations=num_expected_locations) 556061da546Spatrick 557061da546Spatrick return get_bpno_from_match(break_results) 558061da546Spatrick 559*be691f3bSpatrickdef run_break_set_by_file_colon_line( 560*be691f3bSpatrick test, 561*be691f3bSpatrick specifier, 562*be691f3bSpatrick path, 563*be691f3bSpatrick line_number, 564*be691f3bSpatrick column_number = 0, 565*be691f3bSpatrick extra_options=None, 566*be691f3bSpatrick num_expected_locations=-1): 567*be691f3bSpatrick command = 'breakpoint set -y "%s"'%(specifier) 568*be691f3bSpatrick if extra_options: 569*be691f3bSpatrick command += " " + extra_options 570*be691f3bSpatrick 571*be691f3bSpatrick print("About to run: '%s'", command) 572*be691f3bSpatrick break_results = run_break_set_command(test, command) 573*be691f3bSpatrick check_breakpoint_result( 574*be691f3bSpatrick test, 575*be691f3bSpatrick break_results, 576*be691f3bSpatrick num_locations = num_expected_locations, 577*be691f3bSpatrick file_name = path, 578*be691f3bSpatrick line_number = line_number, 579*be691f3bSpatrick column_number = column_number) 580*be691f3bSpatrick 581*be691f3bSpatrick return get_bpno_from_match(break_results) 582061da546Spatrick 583061da546Spatrickdef run_break_set_command(test, command): 584061da546Spatrick """Run the command passed in - it must be some break set variant - and analyze the result. 585061da546Spatrick Returns a dictionary of information gleaned from the command-line results. 586061da546Spatrick Will assert if the breakpoint setting fails altogether. 587061da546Spatrick 588061da546Spatrick Dictionary will contain: 589061da546Spatrick bpno - breakpoint of the newly created breakpoint, -1 on error. 590061da546Spatrick num_locations - number of locations set for the breakpoint. 591061da546Spatrick 592061da546Spatrick If there is only one location, the dictionary MAY contain: 593061da546Spatrick file - source file name 594061da546Spatrick line_no - source line number 595*be691f3bSpatrick column - source column number 596061da546Spatrick symbol - symbol name 597061da546Spatrick inline_symbol - inlined symbol name 598061da546Spatrick offset - offset from the original symbol 599061da546Spatrick module - module 600061da546Spatrick address - address at which the breakpoint was set.""" 601061da546Spatrick 602061da546Spatrick patterns = [ 603061da546Spatrick r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>[0-9]+) locations\.$", 604061da546Spatrick r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>no) locations \(pending\)\.", 605061da546Spatrick r"^Breakpoint (?P<bpno>[0-9]+): where = (?P<module>.*)`(?P<symbol>[+\-]{0,1}[^+]+)( \+ (?P<offset>[0-9]+)){0,1}( \[inlined\] (?P<inline_symbol>.*)){0,1} at (?P<file>[^:]+):(?P<line_no>[0-9]+)(?P<column>(:[0-9]+)?), address = (?P<address>0x[0-9a-fA-F]+)$", 606061da546Spatrick r"^Breakpoint (?P<bpno>[0-9]+): where = (?P<module>.*)`(?P<symbol>.*)( \+ (?P<offset>[0-9]+)){0,1}, address = (?P<address>0x[0-9a-fA-F]+)$"] 607061da546Spatrick match_object = test.match(command, patterns) 608061da546Spatrick break_results = match_object.groupdict() 609061da546Spatrick 610061da546Spatrick # We always insert the breakpoint number, setting it to -1 if we couldn't find it 611061da546Spatrick # Also, make sure it gets stored as an integer. 612061da546Spatrick if not 'bpno' in break_results: 613061da546Spatrick break_results['bpno'] = -1 614061da546Spatrick else: 615061da546Spatrick break_results['bpno'] = int(break_results['bpno']) 616061da546Spatrick 617061da546Spatrick # We always insert the number of locations 618061da546Spatrick # If ONE location is set for the breakpoint, then the output doesn't mention locations, but it has to be 1... 619061da546Spatrick # We also make sure it is an integer. 620061da546Spatrick 621061da546Spatrick if not 'num_locations' in break_results: 622061da546Spatrick num_locations = 1 623061da546Spatrick else: 624061da546Spatrick num_locations = break_results['num_locations'] 625061da546Spatrick if num_locations == 'no': 626061da546Spatrick num_locations = 0 627061da546Spatrick else: 628061da546Spatrick num_locations = int(break_results['num_locations']) 629061da546Spatrick 630061da546Spatrick break_results['num_locations'] = num_locations 631061da546Spatrick 632061da546Spatrick if 'line_no' in break_results: 633061da546Spatrick break_results['line_no'] = int(break_results['line_no']) 634061da546Spatrick 635061da546Spatrick return break_results 636061da546Spatrick 637061da546Spatrick 638061da546Spatrickdef get_bpno_from_match(break_results): 639061da546Spatrick return int(break_results['bpno']) 640061da546Spatrick 641061da546Spatrick 642061da546Spatrickdef check_breakpoint_result( 643061da546Spatrick test, 644061da546Spatrick break_results, 645061da546Spatrick file_name=None, 646061da546Spatrick line_number=-1, 647*be691f3bSpatrick column_number=0, 648061da546Spatrick symbol_name=None, 649061da546Spatrick symbol_match_exact=True, 650061da546Spatrick module_name=None, 651061da546Spatrick offset=-1, 652061da546Spatrick num_locations=-1): 653061da546Spatrick 654061da546Spatrick out_num_locations = break_results['num_locations'] 655061da546Spatrick 656061da546Spatrick if num_locations == -1: 657061da546Spatrick test.assertTrue(out_num_locations > 0, 658061da546Spatrick "Expecting one or more locations, got none.") 659061da546Spatrick elif num_locations != -2: 660061da546Spatrick test.assertTrue( 661061da546Spatrick num_locations == out_num_locations, 662061da546Spatrick "Expecting %d locations, got %d." % 663061da546Spatrick (num_locations, 664061da546Spatrick out_num_locations)) 665061da546Spatrick 666061da546Spatrick if file_name: 667061da546Spatrick out_file_name = "" 668061da546Spatrick if 'file' in break_results: 669061da546Spatrick out_file_name = break_results['file'] 670061da546Spatrick test.assertTrue( 671061da546Spatrick file_name.endswith(out_file_name), 672061da546Spatrick "Breakpoint file name '%s' doesn't match resultant name '%s'." % 673061da546Spatrick (file_name, 674061da546Spatrick out_file_name)) 675061da546Spatrick 676061da546Spatrick if line_number != -1: 677061da546Spatrick out_line_number = -1 678061da546Spatrick if 'line_no' in break_results: 679061da546Spatrick out_line_number = break_results['line_no'] 680061da546Spatrick 681061da546Spatrick test.assertTrue( 682061da546Spatrick line_number == out_line_number, 683061da546Spatrick "Breakpoint line number %s doesn't match resultant line %s." % 684061da546Spatrick (line_number, 685061da546Spatrick out_line_number)) 686061da546Spatrick 687*be691f3bSpatrick if column_number != 0: 688*be691f3bSpatrick out_column_number = 0 689*be691f3bSpatrick if 'column' in break_results: 690*be691f3bSpatrick out_column_number = break_results['column'] 691*be691f3bSpatrick 692*be691f3bSpatrick test.assertTrue( 693*be691f3bSpatrick column_number == out_column_number, 694*be691f3bSpatrick "Breakpoint column number %s doesn't match resultant column %s." % 695*be691f3bSpatrick (column_number, 696*be691f3bSpatrick out_column_number)) 697*be691f3bSpatrick 698061da546Spatrick if symbol_name: 699061da546Spatrick out_symbol_name = "" 700061da546Spatrick # Look first for the inlined symbol name, otherwise use the symbol 701061da546Spatrick # name: 702061da546Spatrick if 'inline_symbol' in break_results and break_results['inline_symbol']: 703061da546Spatrick out_symbol_name = break_results['inline_symbol'] 704061da546Spatrick elif 'symbol' in break_results: 705061da546Spatrick out_symbol_name = break_results['symbol'] 706061da546Spatrick 707061da546Spatrick if symbol_match_exact: 708061da546Spatrick test.assertTrue( 709061da546Spatrick symbol_name == out_symbol_name, 710061da546Spatrick "Symbol name '%s' doesn't match resultant symbol '%s'." % 711061da546Spatrick (symbol_name, 712061da546Spatrick out_symbol_name)) 713061da546Spatrick else: 714061da546Spatrick test.assertTrue( 715061da546Spatrick out_symbol_name.find(symbol_name) != - 716061da546Spatrick 1, 717061da546Spatrick "Symbol name '%s' isn't in resultant symbol '%s'." % 718061da546Spatrick (symbol_name, 719061da546Spatrick out_symbol_name)) 720061da546Spatrick 721061da546Spatrick if module_name: 722061da546Spatrick out_module_name = None 723061da546Spatrick if 'module' in break_results: 724061da546Spatrick out_module_name = break_results['module'] 725061da546Spatrick 726061da546Spatrick test.assertTrue( 727061da546Spatrick module_name.find(out_module_name) != - 728061da546Spatrick 1, 729061da546Spatrick "Symbol module name '%s' isn't in expected module name '%s'." % 730061da546Spatrick (out_module_name, 731061da546Spatrick module_name)) 732061da546Spatrick 733061da546Spatrick# ================================================== 734061da546Spatrick# Utility functions related to Threads and Processes 735061da546Spatrick# ================================================== 736061da546Spatrick 737061da546Spatrick 738061da546Spatrickdef get_stopped_threads(process, reason): 739061da546Spatrick """Returns the thread(s) with the specified stop reason in a list. 740061da546Spatrick 741061da546Spatrick The list can be empty if no such thread exists. 742061da546Spatrick """ 743061da546Spatrick threads = [] 744061da546Spatrick for t in process: 745061da546Spatrick if t.GetStopReason() == reason: 746061da546Spatrick threads.append(t) 747061da546Spatrick return threads 748061da546Spatrick 749061da546Spatrick 750061da546Spatrickdef get_stopped_thread(process, reason): 751061da546Spatrick """A convenience function which returns the first thread with the given stop 752061da546Spatrick reason or None. 753061da546Spatrick 754061da546Spatrick Example usages: 755061da546Spatrick 756061da546Spatrick 1. Get the stopped thread due to a breakpoint condition 757061da546Spatrick 758061da546Spatrick ... 759061da546Spatrick from lldbutil import get_stopped_thread 760061da546Spatrick thread = get_stopped_thread(process, lldb.eStopReasonPlanComplete) 761061da546Spatrick self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition") 762061da546Spatrick ... 763061da546Spatrick 764061da546Spatrick 2. Get the thread stopped due to a breakpoint 765061da546Spatrick 766061da546Spatrick ... 767061da546Spatrick from lldbutil import get_stopped_thread 768061da546Spatrick thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) 769061da546Spatrick self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint") 770061da546Spatrick ... 771061da546Spatrick 772061da546Spatrick """ 773061da546Spatrick threads = get_stopped_threads(process, reason) 774061da546Spatrick if len(threads) == 0: 775061da546Spatrick return None 776061da546Spatrick return threads[0] 777061da546Spatrick 778061da546Spatrick 779061da546Spatrickdef get_threads_stopped_at_breakpoint_id(process, bpid): 780061da546Spatrick """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt""" 781061da546Spatrick stopped_threads = [] 782061da546Spatrick threads = [] 783061da546Spatrick 784061da546Spatrick stopped_threads = get_stopped_threads(process, lldb.eStopReasonBreakpoint) 785061da546Spatrick 786061da546Spatrick if len(stopped_threads) == 0: 787061da546Spatrick return threads 788061da546Spatrick 789061da546Spatrick for thread in stopped_threads: 790061da546Spatrick # Make sure we've hit our breakpoint... 791061da546Spatrick break_id = thread.GetStopReasonDataAtIndex(0) 792061da546Spatrick if break_id == bpid: 793061da546Spatrick threads.append(thread) 794061da546Spatrick 795061da546Spatrick return threads 796061da546Spatrick 797061da546Spatrick 798061da546Spatrickdef get_threads_stopped_at_breakpoint(process, bkpt): 799061da546Spatrick return get_threads_stopped_at_breakpoint_id(process, bkpt.GetID()) 800061da546Spatrick 801061da546Spatrick 802061da546Spatrickdef get_one_thread_stopped_at_breakpoint_id( 803061da546Spatrick process, bpid, require_exactly_one=True): 804061da546Spatrick threads = get_threads_stopped_at_breakpoint_id(process, bpid) 805061da546Spatrick if len(threads) == 0: 806061da546Spatrick return None 807061da546Spatrick if require_exactly_one and len(threads) != 1: 808061da546Spatrick return None 809061da546Spatrick 810061da546Spatrick return threads[0] 811061da546Spatrick 812061da546Spatrick 813061da546Spatrickdef get_one_thread_stopped_at_breakpoint( 814061da546Spatrick process, bkpt, require_exactly_one=True): 815061da546Spatrick return get_one_thread_stopped_at_breakpoint_id( 816061da546Spatrick process, bkpt.GetID(), require_exactly_one) 817061da546Spatrick 818061da546Spatrick 819061da546Spatrickdef is_thread_crashed(test, thread): 820061da546Spatrick """In the test suite we dereference a null pointer to simulate a crash. The way this is 821061da546Spatrick reported depends on the platform.""" 822061da546Spatrick if test.platformIsDarwin(): 823061da546Spatrick return thread.GetStopReason( 824061da546Spatrick ) == lldb.eStopReasonException and "EXC_BAD_ACCESS" in thread.GetStopDescription(100) 825061da546Spatrick elif test.getPlatform() == "linux": 826061da546Spatrick return thread.GetStopReason() == lldb.eStopReasonSignal and thread.GetStopReasonDataAtIndex( 827061da546Spatrick 0) == thread.GetProcess().GetUnixSignals().GetSignalNumberFromName("SIGSEGV") 828061da546Spatrick elif test.getPlatform() == "windows": 829061da546Spatrick return "Exception 0xc0000005" in thread.GetStopDescription(200) 830061da546Spatrick else: 831061da546Spatrick return "invalid address" in thread.GetStopDescription(100) 832061da546Spatrick 833061da546Spatrick 834061da546Spatrickdef get_crashed_threads(test, process): 835061da546Spatrick threads = [] 836061da546Spatrick if process.GetState() != lldb.eStateStopped: 837061da546Spatrick return threads 838061da546Spatrick for thread in process: 839061da546Spatrick if is_thread_crashed(test, thread): 840061da546Spatrick threads.append(thread) 841061da546Spatrick return threads 842061da546Spatrick 843061da546Spatrick# Helper functions for run_to_{source,name}_breakpoint: 844061da546Spatrick 845061da546Spatrickdef run_to_breakpoint_make_target(test, exe_name = "a.out", in_cwd = True): 846061da546Spatrick if in_cwd: 847061da546Spatrick exe = test.getBuildArtifact(exe_name) 848061da546Spatrick 849061da546Spatrick # Create the target 850061da546Spatrick target = test.dbg.CreateTarget(exe) 851061da546Spatrick test.assertTrue(target, "Target: %s is not valid."%(exe_name)) 852061da546Spatrick 853061da546Spatrick # Set environment variables for the inferior. 854061da546Spatrick if lldbtest_config.inferior_env: 855061da546Spatrick test.runCmd('settings set target.env-vars {}'.format( 856061da546Spatrick lldbtest_config.inferior_env)) 857061da546Spatrick 858061da546Spatrick return target 859061da546Spatrick 860061da546Spatrickdef run_to_breakpoint_do_run(test, target, bkpt, launch_info = None, 861061da546Spatrick only_one_thread = True, extra_images = None): 862061da546Spatrick 863061da546Spatrick # Launch the process, and do not stop at the entry point. 864061da546Spatrick if not launch_info: 865061da546Spatrick launch_info = target.GetLaunchInfo() 866061da546Spatrick launch_info.SetWorkingDirectory(test.get_process_working_directory()) 867061da546Spatrick 868dda28197Spatrick if extra_images: 869061da546Spatrick environ = test.registerSharedLibrariesWithTarget(target, extra_images) 870061da546Spatrick launch_info.SetEnvironmentEntries(environ, True) 871061da546Spatrick 872061da546Spatrick error = lldb.SBError() 873061da546Spatrick process = target.Launch(launch_info, error) 874061da546Spatrick 875*be691f3bSpatrick # Unfortunate workaround for the iPhone simulator. 876*be691f3bSpatrick retry = SIMULATOR_RETRY 877*be691f3bSpatrick while (retry and error.Fail() and error.GetCString() and 878*be691f3bSpatrick "Unable to boot the Simulator" in error.GetCString()): 879*be691f3bSpatrick retry -= 1 880*be691f3bSpatrick print("** Simulator is unresponsive. Retrying %d more time(s)"%retry) 881*be691f3bSpatrick import time 882*be691f3bSpatrick time.sleep(60) 883*be691f3bSpatrick error = lldb.SBError() 884*be691f3bSpatrick process = target.Launch(launch_info, error) 885*be691f3bSpatrick 886061da546Spatrick test.assertTrue(process, 887*be691f3bSpatrick "Could not create a valid process for %s: %s" % 888*be691f3bSpatrick (target.GetExecutable().GetFilename(), error.GetCString())) 889061da546Spatrick test.assertFalse(error.Fail(), 890061da546Spatrick "Process launch failed: %s" % (error.GetCString())) 891061da546Spatrick 892dda28197Spatrick test.assertEqual(process.GetState(), lldb.eStateStopped) 893dda28197Spatrick 894061da546Spatrick # Frame #0 should be at our breakpoint. 895061da546Spatrick threads = get_threads_stopped_at_breakpoint( 896061da546Spatrick process, bkpt) 897061da546Spatrick 898061da546Spatrick num_threads = len(threads) 899061da546Spatrick if only_one_thread: 900061da546Spatrick test.assertEqual(num_threads, 1, "Expected 1 thread to stop at breakpoint, %d did."%(num_threads)) 901061da546Spatrick else: 902061da546Spatrick test.assertGreater(num_threads, 0, "No threads stopped at breakpoint") 903061da546Spatrick 904061da546Spatrick thread = threads[0] 905061da546Spatrick return (target, process, thread, bkpt) 906061da546Spatrick 907061da546Spatrickdef run_to_name_breakpoint (test, bkpt_name, launch_info = None, 908061da546Spatrick exe_name = "a.out", 909061da546Spatrick bkpt_module = None, 910061da546Spatrick in_cwd = True, 911061da546Spatrick only_one_thread = True, 912061da546Spatrick extra_images = None): 913061da546Spatrick """Start up a target, using exe_name as the executable, and run it to 914061da546Spatrick a breakpoint set by name on bkpt_name restricted to bkpt_module. 915061da546Spatrick 916061da546Spatrick If you want to pass in launch arguments or environment 917061da546Spatrick variables, you can optionally pass in an SBLaunchInfo. If you 918061da546Spatrick do that, remember to set the working directory as well. 919061da546Spatrick 920061da546Spatrick If your executable isn't called a.out, you can pass that in. 921061da546Spatrick And if your executable isn't in the CWD, pass in the absolute 922061da546Spatrick path to the executable in exe_name, and set in_cwd to False. 923061da546Spatrick 924061da546Spatrick If you need to restrict the breakpoint to a particular module, 925061da546Spatrick pass the module name (a string not a FileSpec) in bkpt_module. If 926061da546Spatrick nothing is passed in setting will be unrestricted. 927061da546Spatrick 928061da546Spatrick If the target isn't valid, the breakpoint isn't found, or hit, the 929061da546Spatrick function will cause a testsuite failure. 930061da546Spatrick 931061da546Spatrick If successful it returns a tuple with the target process and 932061da546Spatrick thread that hit the breakpoint, and the breakpoint that we set 933061da546Spatrick for you. 934061da546Spatrick 935061da546Spatrick If only_one_thread is true, we require that there be only one 936061da546Spatrick thread stopped at the breakpoint. Otherwise we only require one 937061da546Spatrick or more threads stop there. If there are more than one, we return 938061da546Spatrick the first thread that stopped. 939061da546Spatrick """ 940061da546Spatrick 941061da546Spatrick target = run_to_breakpoint_make_target(test, exe_name, in_cwd) 942061da546Spatrick 943061da546Spatrick breakpoint = target.BreakpointCreateByName(bkpt_name, bkpt_module) 944061da546Spatrick 945061da546Spatrick 946061da546Spatrick test.assertTrue(breakpoint.GetNumLocations() > 0, 947061da546Spatrick "No locations found for name breakpoint: '%s'."%(bkpt_name)) 948061da546Spatrick return run_to_breakpoint_do_run(test, target, breakpoint, launch_info, 949061da546Spatrick only_one_thread, extra_images) 950061da546Spatrick 951061da546Spatrickdef run_to_source_breakpoint(test, bkpt_pattern, source_spec, 952061da546Spatrick launch_info = None, exe_name = "a.out", 953061da546Spatrick bkpt_module = None, 954061da546Spatrick in_cwd = True, 955061da546Spatrick only_one_thread = True, 956061da546Spatrick extra_images = None): 957061da546Spatrick """Start up a target, using exe_name as the executable, and run it to 958061da546Spatrick a breakpoint set by source regex bkpt_pattern. 959061da546Spatrick 960061da546Spatrick The rest of the behavior is the same as run_to_name_breakpoint. 961061da546Spatrick """ 962061da546Spatrick 963061da546Spatrick target = run_to_breakpoint_make_target(test, exe_name, in_cwd) 964061da546Spatrick # Set the breakpoints 965061da546Spatrick breakpoint = target.BreakpointCreateBySourceRegex( 966061da546Spatrick bkpt_pattern, source_spec, bkpt_module) 967061da546Spatrick test.assertTrue(breakpoint.GetNumLocations() > 0, 968061da546Spatrick 'No locations found for source breakpoint: "%s", file: "%s", dir: "%s"' 969061da546Spatrick %(bkpt_pattern, source_spec.GetFilename(), source_spec.GetDirectory())) 970061da546Spatrick return run_to_breakpoint_do_run(test, target, breakpoint, launch_info, 971061da546Spatrick only_one_thread, extra_images) 972061da546Spatrick 973061da546Spatrickdef run_to_line_breakpoint(test, source_spec, line_number, column = 0, 974061da546Spatrick launch_info = None, exe_name = "a.out", 975061da546Spatrick bkpt_module = None, 976061da546Spatrick in_cwd = True, 977061da546Spatrick only_one_thread = True, 978061da546Spatrick extra_images = None): 979061da546Spatrick """Start up a target, using exe_name as the executable, and run it to 980061da546Spatrick a breakpoint set by (source_spec, line_number(, column)). 981061da546Spatrick 982061da546Spatrick The rest of the behavior is the same as run_to_name_breakpoint. 983061da546Spatrick """ 984061da546Spatrick 985061da546Spatrick target = run_to_breakpoint_make_target(test, exe_name, in_cwd) 986061da546Spatrick # Set the breakpoints 987061da546Spatrick breakpoint = target.BreakpointCreateByLocation( 988061da546Spatrick source_spec, line_number, column, 0, lldb.SBFileSpecList()) 989061da546Spatrick test.assertTrue(breakpoint.GetNumLocations() > 0, 990061da546Spatrick 'No locations found for line breakpoint: "%s:%d(:%d)", dir: "%s"' 991061da546Spatrick %(source_spec.GetFilename(), line_number, column, 992061da546Spatrick source_spec.GetDirectory())) 993061da546Spatrick return run_to_breakpoint_do_run(test, target, breakpoint, launch_info, 994061da546Spatrick only_one_thread, extra_images) 995061da546Spatrick 996061da546Spatrick 997061da546Spatrickdef continue_to_breakpoint(process, bkpt): 998061da546Spatrick """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None""" 999061da546Spatrick process.Continue() 1000061da546Spatrick if process.GetState() != lldb.eStateStopped: 1001061da546Spatrick return None 1002061da546Spatrick else: 1003061da546Spatrick return get_threads_stopped_at_breakpoint(process, bkpt) 1004061da546Spatrick 1005061da546Spatrick 1006061da546Spatrickdef get_caller_symbol(thread): 1007061da546Spatrick """ 1008061da546Spatrick Returns the symbol name for the call site of the leaf function. 1009061da546Spatrick """ 1010061da546Spatrick depth = thread.GetNumFrames() 1011061da546Spatrick if depth <= 1: 1012061da546Spatrick return None 1013061da546Spatrick caller = thread.GetFrameAtIndex(1).GetSymbol() 1014061da546Spatrick if caller: 1015061da546Spatrick return caller.GetName() 1016061da546Spatrick else: 1017061da546Spatrick return None 1018061da546Spatrick 1019061da546Spatrick 1020061da546Spatrickdef get_function_names(thread): 1021061da546Spatrick """ 1022061da546Spatrick Returns a sequence of function names from the stack frames of this thread. 1023061da546Spatrick """ 1024061da546Spatrick def GetFuncName(i): 1025061da546Spatrick return thread.GetFrameAtIndex(i).GetFunctionName() 1026061da546Spatrick 1027061da546Spatrick return list(map(GetFuncName, list(range(thread.GetNumFrames())))) 1028061da546Spatrick 1029061da546Spatrick 1030061da546Spatrickdef get_symbol_names(thread): 1031061da546Spatrick """ 1032061da546Spatrick Returns a sequence of symbols for this thread. 1033061da546Spatrick """ 1034061da546Spatrick def GetSymbol(i): 1035061da546Spatrick return thread.GetFrameAtIndex(i).GetSymbol().GetName() 1036061da546Spatrick 1037061da546Spatrick return list(map(GetSymbol, list(range(thread.GetNumFrames())))) 1038061da546Spatrick 1039061da546Spatrick 1040061da546Spatrickdef get_pc_addresses(thread): 1041061da546Spatrick """ 1042061da546Spatrick Returns a sequence of pc addresses for this thread. 1043061da546Spatrick """ 1044061da546Spatrick def GetPCAddress(i): 1045061da546Spatrick return thread.GetFrameAtIndex(i).GetPCAddress() 1046061da546Spatrick 1047061da546Spatrick return list(map(GetPCAddress, list(range(thread.GetNumFrames())))) 1048061da546Spatrick 1049061da546Spatrick 1050061da546Spatrickdef get_filenames(thread): 1051061da546Spatrick """ 1052061da546Spatrick Returns a sequence of file names from the stack frames of this thread. 1053061da546Spatrick """ 1054061da546Spatrick def GetFilename(i): 1055061da546Spatrick return thread.GetFrameAtIndex( 1056061da546Spatrick i).GetLineEntry().GetFileSpec().GetFilename() 1057061da546Spatrick 1058061da546Spatrick return list(map(GetFilename, list(range(thread.GetNumFrames())))) 1059061da546Spatrick 1060061da546Spatrick 1061061da546Spatrickdef get_line_numbers(thread): 1062061da546Spatrick """ 1063061da546Spatrick Returns a sequence of line numbers from the stack frames of this thread. 1064061da546Spatrick """ 1065061da546Spatrick def GetLineNumber(i): 1066061da546Spatrick return thread.GetFrameAtIndex(i).GetLineEntry().GetLine() 1067061da546Spatrick 1068061da546Spatrick return list(map(GetLineNumber, list(range(thread.GetNumFrames())))) 1069061da546Spatrick 1070061da546Spatrick 1071061da546Spatrickdef get_module_names(thread): 1072061da546Spatrick """ 1073061da546Spatrick Returns a sequence of module names from the stack frames of this thread. 1074061da546Spatrick """ 1075061da546Spatrick def GetModuleName(i): 1076061da546Spatrick return thread.GetFrameAtIndex( 1077061da546Spatrick i).GetModule().GetFileSpec().GetFilename() 1078061da546Spatrick 1079061da546Spatrick return list(map(GetModuleName, list(range(thread.GetNumFrames())))) 1080061da546Spatrick 1081061da546Spatrick 1082061da546Spatrickdef get_stack_frames(thread): 1083061da546Spatrick """ 1084061da546Spatrick Returns a sequence of stack frames for this thread. 1085061da546Spatrick """ 1086061da546Spatrick def GetStackFrame(i): 1087061da546Spatrick return thread.GetFrameAtIndex(i) 1088061da546Spatrick 1089061da546Spatrick return list(map(GetStackFrame, list(range(thread.GetNumFrames())))) 1090061da546Spatrick 1091061da546Spatrick 1092061da546Spatrickdef print_stacktrace(thread, string_buffer=False): 1093061da546Spatrick """Prints a simple stack trace of this thread.""" 1094061da546Spatrick 1095061da546Spatrick output = SixStringIO() if string_buffer else sys.stdout 1096061da546Spatrick target = thread.GetProcess().GetTarget() 1097061da546Spatrick 1098061da546Spatrick depth = thread.GetNumFrames() 1099061da546Spatrick 1100061da546Spatrick mods = get_module_names(thread) 1101061da546Spatrick funcs = get_function_names(thread) 1102061da546Spatrick symbols = get_symbol_names(thread) 1103061da546Spatrick files = get_filenames(thread) 1104061da546Spatrick lines = get_line_numbers(thread) 1105061da546Spatrick addrs = get_pc_addresses(thread) 1106061da546Spatrick 1107061da546Spatrick if thread.GetStopReason() != lldb.eStopReasonInvalid: 1108061da546Spatrick desc = "stop reason=" + stop_reason_to_str(thread.GetStopReason()) 1109061da546Spatrick else: 1110061da546Spatrick desc = "" 1111061da546Spatrick print( 1112061da546Spatrick "Stack trace for thread id={0:#x} name={1} queue={2} ".format( 1113061da546Spatrick thread.GetThreadID(), 1114061da546Spatrick thread.GetName(), 1115061da546Spatrick thread.GetQueueName()) + desc, 1116061da546Spatrick file=output) 1117061da546Spatrick 1118061da546Spatrick for i in range(depth): 1119061da546Spatrick frame = thread.GetFrameAtIndex(i) 1120061da546Spatrick function = frame.GetFunction() 1121061da546Spatrick 1122061da546Spatrick load_addr = addrs[i].GetLoadAddress(target) 1123061da546Spatrick if not function: 1124061da546Spatrick file_addr = addrs[i].GetFileAddress() 1125061da546Spatrick start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress() 1126061da546Spatrick symbol_offset = file_addr - start_addr 1127061da546Spatrick print( 1128061da546Spatrick " frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format( 1129061da546Spatrick num=i, 1130061da546Spatrick addr=load_addr, 1131061da546Spatrick mod=mods[i], 1132061da546Spatrick symbol=symbols[i], 1133061da546Spatrick offset=symbol_offset), 1134061da546Spatrick file=output) 1135061da546Spatrick else: 1136061da546Spatrick print( 1137061da546Spatrick " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format( 1138061da546Spatrick num=i, 1139061da546Spatrick addr=load_addr, 1140061da546Spatrick mod=mods[i], 1141061da546Spatrick func='%s [inlined]' % 1142061da546Spatrick funcs[i] if frame.IsInlined() else funcs[i], 1143061da546Spatrick file=files[i], 1144061da546Spatrick line=lines[i], 1145061da546Spatrick args=get_args_as_string( 1146061da546Spatrick frame, 1147061da546Spatrick showFuncName=False) if not frame.IsInlined() else '()'), 1148061da546Spatrick file=output) 1149061da546Spatrick 1150061da546Spatrick if string_buffer: 1151061da546Spatrick return output.getvalue() 1152061da546Spatrick 1153061da546Spatrick 1154061da546Spatrickdef print_stacktraces(process, string_buffer=False): 1155061da546Spatrick """Prints the stack traces of all the threads.""" 1156061da546Spatrick 1157061da546Spatrick output = SixStringIO() if string_buffer else sys.stdout 1158061da546Spatrick 1159061da546Spatrick print("Stack traces for " + str(process), file=output) 1160061da546Spatrick 1161061da546Spatrick for thread in process: 1162061da546Spatrick print(print_stacktrace(thread, string_buffer=True), file=output) 1163061da546Spatrick 1164061da546Spatrick if string_buffer: 1165061da546Spatrick return output.getvalue() 1166061da546Spatrick 1167061da546Spatrick 1168dda28197Spatrickdef expect_state_changes(test, listener, process, states, timeout=30): 1169061da546Spatrick """Listens for state changed events on the listener and makes sure they match what we 1170061da546Spatrick expect. Stop-and-restart events (where GetRestartedFromEvent() returns true) are ignored.""" 1171061da546Spatrick 1172061da546Spatrick for expected_state in states: 1173061da546Spatrick def get_next_event(): 1174061da546Spatrick event = lldb.SBEvent() 1175061da546Spatrick if not listener.WaitForEventForBroadcasterWithType( 1176061da546Spatrick timeout, 1177061da546Spatrick process.GetBroadcaster(), 1178061da546Spatrick lldb.SBProcess.eBroadcastBitStateChanged, 1179061da546Spatrick event): 1180061da546Spatrick test.fail( 1181061da546Spatrick "Timed out while waiting for a transition to state %s" % 1182061da546Spatrick lldb.SBDebugger.StateAsCString(expected_state)) 1183061da546Spatrick return event 1184061da546Spatrick 1185061da546Spatrick event = get_next_event() 1186061da546Spatrick while (lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateStopped and 1187061da546Spatrick lldb.SBProcess.GetRestartedFromEvent(event)): 1188061da546Spatrick # Ignore restarted event and the subsequent running event. 1189061da546Spatrick event = get_next_event() 1190061da546Spatrick test.assertEqual( 1191061da546Spatrick lldb.SBProcess.GetStateFromEvent(event), 1192061da546Spatrick lldb.eStateRunning, 1193061da546Spatrick "Restarted event followed by a running event") 1194061da546Spatrick event = get_next_event() 1195061da546Spatrick 1196061da546Spatrick test.assertEqual( 1197061da546Spatrick lldb.SBProcess.GetStateFromEvent(event), 1198061da546Spatrick expected_state) 1199061da546Spatrick 1200061da546Spatrick# =================================== 1201061da546Spatrick# Utility functions related to Frames 1202061da546Spatrick# =================================== 1203061da546Spatrick 1204061da546Spatrick 1205061da546Spatrickdef get_parent_frame(frame): 1206061da546Spatrick """ 1207061da546Spatrick Returns the parent frame of the input frame object; None if not available. 1208061da546Spatrick """ 1209061da546Spatrick thread = frame.GetThread() 1210061da546Spatrick parent_found = False 1211061da546Spatrick for f in thread: 1212061da546Spatrick if parent_found: 1213061da546Spatrick return f 1214061da546Spatrick if f.GetFrameID() == frame.GetFrameID(): 1215061da546Spatrick parent_found = True 1216061da546Spatrick 1217061da546Spatrick # If we reach here, no parent has been found, return None. 1218061da546Spatrick return None 1219061da546Spatrick 1220061da546Spatrick 1221061da546Spatrickdef get_args_as_string(frame, showFuncName=True): 1222061da546Spatrick """ 1223061da546Spatrick Returns the args of the input frame object as a string. 1224061da546Spatrick """ 1225061da546Spatrick # arguments => True 1226061da546Spatrick # locals => False 1227061da546Spatrick # statics => False 1228061da546Spatrick # in_scope_only => True 1229061da546Spatrick vars = frame.GetVariables(True, False, False, True) # type of SBValueList 1230061da546Spatrick args = [] # list of strings 1231061da546Spatrick for var in vars: 1232061da546Spatrick args.append("(%s)%s=%s" % (var.GetTypeName(), 1233061da546Spatrick var.GetName(), 1234061da546Spatrick var.GetValue())) 1235061da546Spatrick if frame.GetFunction(): 1236061da546Spatrick name = frame.GetFunction().GetName() 1237061da546Spatrick elif frame.GetSymbol(): 1238061da546Spatrick name = frame.GetSymbol().GetName() 1239061da546Spatrick else: 1240061da546Spatrick name = "" 1241061da546Spatrick if showFuncName: 1242061da546Spatrick return "%s(%s)" % (name, ", ".join(args)) 1243061da546Spatrick else: 1244061da546Spatrick return "(%s)" % (", ".join(args)) 1245061da546Spatrick 1246061da546Spatrick 1247061da546Spatrickdef print_registers(frame, string_buffer=False): 1248061da546Spatrick """Prints all the register sets of the frame.""" 1249061da546Spatrick 1250061da546Spatrick output = SixStringIO() if string_buffer else sys.stdout 1251061da546Spatrick 1252061da546Spatrick print("Register sets for " + str(frame), file=output) 1253061da546Spatrick 1254061da546Spatrick registerSet = frame.GetRegisters() # Return type of SBValueList. 1255061da546Spatrick print("Frame registers (size of register set = %d):" % 1256061da546Spatrick registerSet.GetSize(), file=output) 1257061da546Spatrick for value in registerSet: 1258061da546Spatrick #print(value, file=output) 1259061da546Spatrick print("%s (number of children = %d):" % 1260061da546Spatrick (value.GetName(), value.GetNumChildren()), file=output) 1261061da546Spatrick for child in value: 1262061da546Spatrick print( 1263061da546Spatrick "Name: %s, Value: %s" % 1264061da546Spatrick (child.GetName(), 1265061da546Spatrick child.GetValue()), 1266061da546Spatrick file=output) 1267061da546Spatrick 1268061da546Spatrick if string_buffer: 1269061da546Spatrick return output.getvalue() 1270061da546Spatrick 1271061da546Spatrick 1272061da546Spatrickdef get_registers(frame, kind): 1273061da546Spatrick """Returns the registers given the frame and the kind of registers desired. 1274061da546Spatrick 1275061da546Spatrick Returns None if there's no such kind. 1276061da546Spatrick """ 1277061da546Spatrick registerSet = frame.GetRegisters() # Return type of SBValueList. 1278061da546Spatrick for value in registerSet: 1279061da546Spatrick if kind.lower() in value.GetName().lower(): 1280061da546Spatrick return value 1281061da546Spatrick 1282061da546Spatrick return None 1283061da546Spatrick 1284061da546Spatrick 1285061da546Spatrickdef get_GPRs(frame): 1286061da546Spatrick """Returns the general purpose registers of the frame as an SBValue. 1287061da546Spatrick 1288061da546Spatrick The returned SBValue object is iterable. An example: 1289061da546Spatrick ... 1290061da546Spatrick from lldbutil import get_GPRs 1291061da546Spatrick regs = get_GPRs(frame) 1292061da546Spatrick for reg in regs: 1293061da546Spatrick print("%s => %s" % (reg.GetName(), reg.GetValue())) 1294061da546Spatrick ... 1295061da546Spatrick """ 1296061da546Spatrick return get_registers(frame, "general purpose") 1297061da546Spatrick 1298061da546Spatrick 1299061da546Spatrickdef get_FPRs(frame): 1300061da546Spatrick """Returns the floating point registers of the frame as an SBValue. 1301061da546Spatrick 1302061da546Spatrick The returned SBValue object is iterable. An example: 1303061da546Spatrick ... 1304061da546Spatrick from lldbutil import get_FPRs 1305061da546Spatrick regs = get_FPRs(frame) 1306061da546Spatrick for reg in regs: 1307061da546Spatrick print("%s => %s" % (reg.GetName(), reg.GetValue())) 1308061da546Spatrick ... 1309061da546Spatrick """ 1310061da546Spatrick return get_registers(frame, "floating point") 1311061da546Spatrick 1312061da546Spatrick 1313061da546Spatrickdef get_ESRs(frame): 1314061da546Spatrick """Returns the exception state registers of the frame as an SBValue. 1315061da546Spatrick 1316061da546Spatrick The returned SBValue object is iterable. An example: 1317061da546Spatrick ... 1318061da546Spatrick from lldbutil import get_ESRs 1319061da546Spatrick regs = get_ESRs(frame) 1320061da546Spatrick for reg in regs: 1321061da546Spatrick print("%s => %s" % (reg.GetName(), reg.GetValue())) 1322061da546Spatrick ... 1323061da546Spatrick """ 1324061da546Spatrick return get_registers(frame, "exception state") 1325061da546Spatrick 1326061da546Spatrick# ====================================== 1327061da546Spatrick# Utility classes/functions for SBValues 1328061da546Spatrick# ====================================== 1329061da546Spatrick 1330061da546Spatrick 1331061da546Spatrickclass BasicFormatter(object): 1332061da546Spatrick """The basic formatter inspects the value object and prints the value.""" 1333061da546Spatrick 1334061da546Spatrick def format(self, value, buffer=None, indent=0): 1335061da546Spatrick if not buffer: 1336061da546Spatrick output = SixStringIO() 1337061da546Spatrick else: 1338061da546Spatrick output = buffer 1339061da546Spatrick # If there is a summary, it suffices. 1340061da546Spatrick val = value.GetSummary() 1341061da546Spatrick # Otherwise, get the value. 1342061da546Spatrick if val is None: 1343061da546Spatrick val = value.GetValue() 1344061da546Spatrick if val is None and value.GetNumChildren() > 0: 1345061da546Spatrick val = "%s (location)" % value.GetLocation() 1346061da546Spatrick print("{indentation}({type}) {name} = {value}".format( 1347061da546Spatrick indentation=' ' * indent, 1348061da546Spatrick type=value.GetTypeName(), 1349061da546Spatrick name=value.GetName(), 1350061da546Spatrick value=val), file=output) 1351061da546Spatrick return output.getvalue() 1352061da546Spatrick 1353061da546Spatrick 1354061da546Spatrickclass ChildVisitingFormatter(BasicFormatter): 1355061da546Spatrick """The child visiting formatter prints the value and its immediate children. 1356061da546Spatrick 1357061da546Spatrick The constructor takes a keyword arg: indent_child, which defaults to 2. 1358061da546Spatrick """ 1359061da546Spatrick 1360061da546Spatrick def __init__(self, indent_child=2): 1361061da546Spatrick """Default indentation of 2 SPC's for the children.""" 1362061da546Spatrick self.cindent = indent_child 1363061da546Spatrick 1364061da546Spatrick def format(self, value, buffer=None): 1365061da546Spatrick if not buffer: 1366061da546Spatrick output = SixStringIO() 1367061da546Spatrick else: 1368061da546Spatrick output = buffer 1369061da546Spatrick 1370061da546Spatrick BasicFormatter.format(self, value, buffer=output) 1371061da546Spatrick for child in value: 1372061da546Spatrick BasicFormatter.format( 1373061da546Spatrick self, child, buffer=output, indent=self.cindent) 1374061da546Spatrick 1375061da546Spatrick return output.getvalue() 1376061da546Spatrick 1377061da546Spatrick 1378061da546Spatrickclass RecursiveDecentFormatter(BasicFormatter): 1379061da546Spatrick """The recursive decent formatter prints the value and the decendents. 1380061da546Spatrick 1381061da546Spatrick The constructor takes two keyword args: indent_level, which defaults to 0, 1382061da546Spatrick and indent_child, which defaults to 2. The current indentation level is 1383061da546Spatrick determined by indent_level, while the immediate children has an additional 1384061da546Spatrick indentation by inden_child. 1385061da546Spatrick """ 1386061da546Spatrick 1387061da546Spatrick def __init__(self, indent_level=0, indent_child=2): 1388061da546Spatrick self.lindent = indent_level 1389061da546Spatrick self.cindent = indent_child 1390061da546Spatrick 1391061da546Spatrick def format(self, value, buffer=None): 1392061da546Spatrick if not buffer: 1393061da546Spatrick output = SixStringIO() 1394061da546Spatrick else: 1395061da546Spatrick output = buffer 1396061da546Spatrick 1397061da546Spatrick BasicFormatter.format(self, value, buffer=output, indent=self.lindent) 1398061da546Spatrick new_indent = self.lindent + self.cindent 1399061da546Spatrick for child in value: 1400061da546Spatrick if child.GetSummary() is not None: 1401061da546Spatrick BasicFormatter.format( 1402061da546Spatrick self, child, buffer=output, indent=new_indent) 1403061da546Spatrick else: 1404061da546Spatrick if child.GetNumChildren() > 0: 1405061da546Spatrick rdf = RecursiveDecentFormatter(indent_level=new_indent) 1406061da546Spatrick rdf.format(child, buffer=output) 1407061da546Spatrick else: 1408061da546Spatrick BasicFormatter.format( 1409061da546Spatrick self, child, buffer=output, indent=new_indent) 1410061da546Spatrick 1411061da546Spatrick return output.getvalue() 1412061da546Spatrick 1413061da546Spatrick# =========================================================== 1414061da546Spatrick# Utility functions for path manipulation on remote platforms 1415061da546Spatrick# =========================================================== 1416061da546Spatrick 1417061da546Spatrick 1418061da546Spatrickdef join_remote_paths(*paths): 1419061da546Spatrick # TODO: update with actual platform name for remote windows once it exists 1420061da546Spatrick if lldb.remote_platform.GetName() == 'remote-windows': 1421061da546Spatrick return os.path.join(*paths).replace(os.path.sep, '\\') 1422061da546Spatrick return os.path.join(*paths).replace(os.path.sep, '/') 1423061da546Spatrick 1424061da546Spatrick 1425061da546Spatrickdef append_to_process_working_directory(test, *paths): 1426061da546Spatrick remote = lldb.remote_platform 1427061da546Spatrick if remote: 1428061da546Spatrick return join_remote_paths(remote.GetWorkingDirectory(), *paths) 1429061da546Spatrick return os.path.join(test.getBuildDir(), *paths) 1430061da546Spatrick 1431061da546Spatrick# ================================================== 1432061da546Spatrick# Utility functions to get the correct signal number 1433061da546Spatrick# ================================================== 1434061da546Spatrick 1435061da546Spatrickimport signal 1436061da546Spatrick 1437061da546Spatrick 1438061da546Spatrickdef get_signal_number(signal_name): 1439061da546Spatrick platform = lldb.remote_platform 1440061da546Spatrick if platform and platform.IsValid(): 1441061da546Spatrick signals = platform.GetUnixSignals() 1442061da546Spatrick if signals.IsValid(): 1443061da546Spatrick signal_number = signals.GetSignalNumberFromName(signal_name) 1444061da546Spatrick if signal_number > 0: 1445061da546Spatrick return signal_number 1446061da546Spatrick # No remote platform; fall back to using local python signals. 1447061da546Spatrick return getattr(signal, signal_name) 1448061da546Spatrick 1449061da546Spatrick 1450061da546Spatrickclass PrintableRegex(object): 1451061da546Spatrick 1452061da546Spatrick def __init__(self, text): 1453061da546Spatrick self.regex = re.compile(text) 1454061da546Spatrick self.text = text 1455061da546Spatrick 1456061da546Spatrick def match(self, str): 1457061da546Spatrick return self.regex.match(str) 1458061da546Spatrick 1459061da546Spatrick def __str__(self): 1460061da546Spatrick return "%s" % (self.text) 1461061da546Spatrick 1462061da546Spatrick def __repr__(self): 1463061da546Spatrick return "re.compile(%s) -> %s" % (self.text, self.regex) 1464061da546Spatrick 1465061da546Spatrick 1466061da546Spatrickdef skip_if_callable(test, mycallable, reason): 1467061da546Spatrick if six.callable(mycallable): 1468061da546Spatrick if mycallable(test): 1469061da546Spatrick test.skipTest(reason) 1470061da546Spatrick return True 1471061da546Spatrick return False 1472061da546Spatrick 1473061da546Spatrick 1474061da546Spatrickdef skip_if_library_missing(test, target, library): 1475061da546Spatrick def find_library(target, library): 1476061da546Spatrick for module in target.modules: 1477061da546Spatrick filename = module.file.GetFilename() 1478061da546Spatrick if isinstance(library, str): 1479061da546Spatrick if library == filename: 1480061da546Spatrick return False 1481061da546Spatrick elif hasattr(library, 'match'): 1482061da546Spatrick if library.match(filename): 1483061da546Spatrick return False 1484061da546Spatrick return True 1485061da546Spatrick 1486061da546Spatrick def find_library_callable(test): 1487061da546Spatrick return find_library(target, library) 1488061da546Spatrick return skip_if_callable( 1489061da546Spatrick test, 1490061da546Spatrick find_library_callable, 1491061da546Spatrick "could not find library matching '%s' in target %s" % 1492061da546Spatrick (library, 1493061da546Spatrick target)) 1494061da546Spatrick 1495061da546Spatrick 1496061da546Spatrickdef read_file_on_target(test, remote): 1497061da546Spatrick if lldb.remote_platform: 1498061da546Spatrick local = test.getBuildArtifact("file_from_target") 1499061da546Spatrick error = lldb.remote_platform.Get(lldb.SBFileSpec(remote, False), 1500061da546Spatrick lldb.SBFileSpec(local, True)) 1501061da546Spatrick test.assertTrue(error.Success(), "Reading file {0} failed: {1}".format(remote, error)) 1502061da546Spatrick else: 1503061da546Spatrick local = remote 1504061da546Spatrick with open(local, 'r') as f: 1505061da546Spatrick return f.read() 1506061da546Spatrick 1507061da546Spatrickdef read_file_from_process_wd(test, name): 1508061da546Spatrick path = append_to_process_working_directory(test, name) 1509061da546Spatrick return read_file_on_target(test, path) 1510061da546Spatrick 1511061da546Spatrickdef wait_for_file_on_target(testcase, file_path, max_attempts=6): 1512061da546Spatrick for i in range(max_attempts): 1513061da546Spatrick err, retcode, msg = testcase.run_platform_command("ls %s" % file_path) 1514061da546Spatrick if err.Success() and retcode == 0: 1515061da546Spatrick break 1516061da546Spatrick if i < max_attempts: 1517061da546Spatrick # Exponential backoff! 1518061da546Spatrick import time 1519061da546Spatrick time.sleep(pow(2, i) * 0.25) 1520061da546Spatrick else: 1521061da546Spatrick testcase.fail( 1522061da546Spatrick "File %s not found even after %d attempts." % 1523061da546Spatrick (file_path, max_attempts)) 1524061da546Spatrick 1525061da546Spatrick return read_file_on_target(testcase, file_path) 1526*be691f3bSpatrick 1527*be691f3bSpatrickdef packetlog_get_process_info(log): 1528*be691f3bSpatrick """parse a gdb-remote packet log file and extract the response to qProcessInfo""" 1529*be691f3bSpatrick process_info = dict() 1530*be691f3bSpatrick with open(log, "r") as logfile: 1531*be691f3bSpatrick process_info_ostype = None 1532*be691f3bSpatrick expect_process_info_response = False 1533*be691f3bSpatrick for line in logfile: 1534*be691f3bSpatrick if expect_process_info_response: 1535*be691f3bSpatrick for pair in line.split(';'): 1536*be691f3bSpatrick keyval = pair.split(':') 1537*be691f3bSpatrick if len(keyval) == 2: 1538*be691f3bSpatrick process_info[keyval[0]] = keyval[1] 1539*be691f3bSpatrick break 1540*be691f3bSpatrick if 'send packet: $qProcessInfo#' in line: 1541*be691f3bSpatrick expect_process_info_response = True 1542*be691f3bSpatrick return process_info 1543*be691f3bSpatrick 1544*be691f3bSpatrickdef packetlog_get_dylib_info(log): 1545*be691f3bSpatrick """parse a gdb-remote packet log file and extract the *last* complete 1546*be691f3bSpatrick (=> fetch_all_solibs=true) response to jGetLoadedDynamicLibrariesInfos""" 1547*be691f3bSpatrick import json 1548*be691f3bSpatrick dylib_info = None 1549*be691f3bSpatrick with open(log, "r") as logfile: 1550*be691f3bSpatrick dylib_info = None 1551*be691f3bSpatrick expect_dylib_info_response = False 1552*be691f3bSpatrick for line in logfile: 1553*be691f3bSpatrick if expect_dylib_info_response: 1554*be691f3bSpatrick while line[0] != '$': 1555*be691f3bSpatrick line = line[1:] 1556*be691f3bSpatrick line = line[1:] 1557*be691f3bSpatrick # Unescape '}'. 1558*be691f3bSpatrick dylib_info = json.loads(line.replace('}]','}')[:-4]) 1559*be691f3bSpatrick expect_dylib_info_response = False 1560*be691f3bSpatrick if 'send packet: $jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true}' in line: 1561*be691f3bSpatrick expect_dylib_info_response = True 1562*be691f3bSpatrick 1563*be691f3bSpatrick return dylib_info 1564