1""" 2This LLDB module contains miscellaneous utilities. 3Some of the test suite takes advantage of the utility functions defined here. 4They can also be useful for general purpose lldb scripting. 5""" 6 7from __future__ import print_function 8from __future__ import absolute_import 9 10# System modules 11import errno 12import os 13import re 14import sys 15 16# Third-party modules 17from six import StringIO as SixStringIO 18import six 19 20# LLDB modules 21import lldb 22from . import lldbtest_config 23 24 25# =================================================== 26# Utilities for locating/checking executable programs 27# =================================================== 28 29def is_exe(fpath): 30 """Returns True if fpath is an executable.""" 31 return os.path.isfile(fpath) and os.access(fpath, os.X_OK) 32 33 34def which(program): 35 """Returns the full path to a program; None otherwise.""" 36 fpath, fname = os.path.split(program) 37 if fpath: 38 if is_exe(program): 39 return program 40 else: 41 for path in os.environ["PATH"].split(os.pathsep): 42 exe_file = os.path.join(path, program) 43 if is_exe(exe_file): 44 return exe_file 45 return None 46 47def mkdir_p(path): 48 try: 49 os.makedirs(path) 50 except OSError as e: 51 if e.errno != errno.EEXIST: 52 raise 53 if not os.path.isdir(path): 54 raise OSError(errno.ENOTDIR, "%s is not a directory"%path) 55# =================================================== 56# Disassembly for an SBFunction or an SBSymbol object 57# =================================================== 58 59 60def disassemble(target, function_or_symbol): 61 """Disassemble the function or symbol given a target. 62 63 It returns the disassembly content in a string object. 64 """ 65 buf = SixStringIO() 66 insts = function_or_symbol.GetInstructions(target) 67 for i in insts: 68 print(i, file=buf) 69 return buf.getvalue() 70 71# ========================================================== 72# Integer (byte size 1, 2, 4, and 8) to bytearray conversion 73# ========================================================== 74 75 76def int_to_bytearray(val, bytesize): 77 """Utility function to convert an integer into a bytearray. 78 79 It returns the bytearray in the little endian format. It is easy to get the 80 big endian format, just do ba.reverse() on the returned object. 81 """ 82 import struct 83 84 if bytesize == 1: 85 return bytearray([val]) 86 87 # Little endian followed by a format character. 88 template = "<%c" 89 if bytesize == 2: 90 fmt = template % 'h' 91 elif bytesize == 4: 92 fmt = template % 'i' 93 elif bytesize == 4: 94 fmt = template % 'q' 95 else: 96 return None 97 98 packed = struct.pack(fmt, val) 99 return bytearray(packed) 100 101 102def bytearray_to_int(bytes, bytesize): 103 """Utility function to convert a bytearray into an integer. 104 105 It interprets the bytearray in the little endian format. For a big endian 106 bytearray, just do ba.reverse() on the object before passing it in. 107 """ 108 import struct 109 110 if bytesize == 1: 111 return bytes[0] 112 113 # Little endian followed by a format character. 114 template = "<%c" 115 if bytesize == 2: 116 fmt = template % 'h' 117 elif bytesize == 4: 118 fmt = template % 'i' 119 elif bytesize == 4: 120 fmt = template % 'q' 121 else: 122 return None 123 124 unpacked = struct.unpack_from(fmt, bytes) 125 return unpacked[0] 126 127 128# ============================================================== 129# Get the description of an lldb object or None if not available 130# ============================================================== 131def get_description(obj, option=None): 132 """Calls lldb_obj.GetDescription() and returns a string, or None. 133 134 For SBTarget, SBBreakpointLocation, and SBWatchpoint lldb objects, an extra 135 option can be passed in to describe the detailed level of description 136 desired: 137 o lldb.eDescriptionLevelBrief 138 o lldb.eDescriptionLevelFull 139 o lldb.eDescriptionLevelVerbose 140 """ 141 method = getattr(obj, 'GetDescription') 142 if not method: 143 return None 144 tuple = (lldb.SBTarget, lldb.SBBreakpointLocation, lldb.SBWatchpoint) 145 if isinstance(obj, tuple): 146 if option is None: 147 option = lldb.eDescriptionLevelBrief 148 149 stream = lldb.SBStream() 150 if option is None: 151 success = method(stream) 152 else: 153 success = method(stream, option) 154 if not success: 155 return None 156 return stream.GetData() 157 158 159# ================================================= 160# Convert some enum value to its string counterpart 161# ================================================= 162 163def state_type_to_str(enum): 164 """Returns the stateType string given an enum.""" 165 if enum == lldb.eStateInvalid: 166 return "invalid" 167 elif enum == lldb.eStateUnloaded: 168 return "unloaded" 169 elif enum == lldb.eStateConnected: 170 return "connected" 171 elif enum == lldb.eStateAttaching: 172 return "attaching" 173 elif enum == lldb.eStateLaunching: 174 return "launching" 175 elif enum == lldb.eStateStopped: 176 return "stopped" 177 elif enum == lldb.eStateRunning: 178 return "running" 179 elif enum == lldb.eStateStepping: 180 return "stepping" 181 elif enum == lldb.eStateCrashed: 182 return "crashed" 183 elif enum == lldb.eStateDetached: 184 return "detached" 185 elif enum == lldb.eStateExited: 186 return "exited" 187 elif enum == lldb.eStateSuspended: 188 return "suspended" 189 else: 190 raise Exception("Unknown StateType enum") 191 192 193def stop_reason_to_str(enum): 194 """Returns the stopReason string given an enum.""" 195 if enum == lldb.eStopReasonInvalid: 196 return "invalid" 197 elif enum == lldb.eStopReasonNone: 198 return "none" 199 elif enum == lldb.eStopReasonTrace: 200 return "trace" 201 elif enum == lldb.eStopReasonBreakpoint: 202 return "breakpoint" 203 elif enum == lldb.eStopReasonWatchpoint: 204 return "watchpoint" 205 elif enum == lldb.eStopReasonExec: 206 return "exec" 207 elif enum == lldb.eStopReasonSignal: 208 return "signal" 209 elif enum == lldb.eStopReasonException: 210 return "exception" 211 elif enum == lldb.eStopReasonPlanComplete: 212 return "plancomplete" 213 elif enum == lldb.eStopReasonThreadExiting: 214 return "threadexiting" 215 else: 216 raise Exception("Unknown StopReason enum") 217 218 219def symbol_type_to_str(enum): 220 """Returns the symbolType string given an enum.""" 221 if enum == lldb.eSymbolTypeInvalid: 222 return "invalid" 223 elif enum == lldb.eSymbolTypeAbsolute: 224 return "absolute" 225 elif enum == lldb.eSymbolTypeCode: 226 return "code" 227 elif enum == lldb.eSymbolTypeData: 228 return "data" 229 elif enum == lldb.eSymbolTypeTrampoline: 230 return "trampoline" 231 elif enum == lldb.eSymbolTypeRuntime: 232 return "runtime" 233 elif enum == lldb.eSymbolTypeException: 234 return "exception" 235 elif enum == lldb.eSymbolTypeSourceFile: 236 return "sourcefile" 237 elif enum == lldb.eSymbolTypeHeaderFile: 238 return "headerfile" 239 elif enum == lldb.eSymbolTypeObjectFile: 240 return "objectfile" 241 elif enum == lldb.eSymbolTypeCommonBlock: 242 return "commonblock" 243 elif enum == lldb.eSymbolTypeBlock: 244 return "block" 245 elif enum == lldb.eSymbolTypeLocal: 246 return "local" 247 elif enum == lldb.eSymbolTypeParam: 248 return "param" 249 elif enum == lldb.eSymbolTypeVariable: 250 return "variable" 251 elif enum == lldb.eSymbolTypeVariableType: 252 return "variabletype" 253 elif enum == lldb.eSymbolTypeLineEntry: 254 return "lineentry" 255 elif enum == lldb.eSymbolTypeLineHeader: 256 return "lineheader" 257 elif enum == lldb.eSymbolTypeScopeBegin: 258 return "scopebegin" 259 elif enum == lldb.eSymbolTypeScopeEnd: 260 return "scopeend" 261 elif enum == lldb.eSymbolTypeAdditional: 262 return "additional" 263 elif enum == lldb.eSymbolTypeCompiler: 264 return "compiler" 265 elif enum == lldb.eSymbolTypeInstrumentation: 266 return "instrumentation" 267 elif enum == lldb.eSymbolTypeUndefined: 268 return "undefined" 269 270 271def value_type_to_str(enum): 272 """Returns the valueType string given an enum.""" 273 if enum == lldb.eValueTypeInvalid: 274 return "invalid" 275 elif enum == lldb.eValueTypeVariableGlobal: 276 return "global_variable" 277 elif enum == lldb.eValueTypeVariableStatic: 278 return "static_variable" 279 elif enum == lldb.eValueTypeVariableArgument: 280 return "argument_variable" 281 elif enum == lldb.eValueTypeVariableLocal: 282 return "local_variable" 283 elif enum == lldb.eValueTypeRegister: 284 return "register" 285 elif enum == lldb.eValueTypeRegisterSet: 286 return "register_set" 287 elif enum == lldb.eValueTypeConstResult: 288 return "constant_result" 289 else: 290 raise Exception("Unknown ValueType enum") 291 292 293# ================================================== 294# Get stopped threads due to each stop reason. 295# ================================================== 296 297def sort_stopped_threads(process, 298 breakpoint_threads=None, 299 crashed_threads=None, 300 watchpoint_threads=None, 301 signal_threads=None, 302 exiting_threads=None, 303 other_threads=None): 304 """ Fills array *_threads with threads stopped for the corresponding stop 305 reason. 306 """ 307 for lst in [breakpoint_threads, 308 watchpoint_threads, 309 signal_threads, 310 exiting_threads, 311 other_threads]: 312 if lst is not None: 313 lst[:] = [] 314 315 for thread in process: 316 dispatched = False 317 for (reason, list) in [(lldb.eStopReasonBreakpoint, breakpoint_threads), 318 (lldb.eStopReasonException, crashed_threads), 319 (lldb.eStopReasonWatchpoint, watchpoint_threads), 320 (lldb.eStopReasonSignal, signal_threads), 321 (lldb.eStopReasonThreadExiting, exiting_threads), 322 (None, other_threads)]: 323 if not dispatched and list is not None: 324 if thread.GetStopReason() == reason or reason is None: 325 list.append(thread) 326 dispatched = True 327 328# ================================================== 329# Utility functions for setting breakpoints 330# ================================================== 331 332def run_break_set_by_script( 333 test, 334 class_name, 335 extra_options=None, 336 num_expected_locations=1): 337 """Set a scripted breakpoint. Check that it got the right number of locations.""" 338 test.assertTrue(class_name is not None, "Must pass in a class name.") 339 command = "breakpoint set -P " + class_name 340 if extra_options is not None: 341 command += " " + extra_options 342 343 break_results = run_break_set_command(test, command) 344 check_breakpoint_result(test, break_results, num_locations=num_expected_locations) 345 return get_bpno_from_match(break_results) 346 347def run_break_set_by_file_and_line( 348 test, 349 file_name, 350 line_number, 351 extra_options=None, 352 num_expected_locations=1, 353 loc_exact=False, 354 module_name=None): 355 """Set a breakpoint by file and line, returning the breakpoint number. 356 357 If extra_options is not None, then we append it to the breakpoint set command. 358 359 If num_expected_locations is -1, we check that we got AT LEAST one location. If num_expected_locations is -2, we don't 360 check the actual number at all. Otherwise, we check that num_expected_locations equals the number of locations. 361 362 If loc_exact is true, we check that there is one location, and that location must be at the input file and line number.""" 363 364 if file_name is None: 365 command = 'breakpoint set -l %d' % (line_number) 366 else: 367 command = 'breakpoint set -f "%s" -l %d' % (file_name, line_number) 368 369 if module_name: 370 command += " --shlib '%s'" % (module_name) 371 372 if extra_options: 373 command += " " + extra_options 374 375 break_results = run_break_set_command(test, command) 376 377 if num_expected_locations == 1 and loc_exact: 378 check_breakpoint_result( 379 test, 380 break_results, 381 num_locations=num_expected_locations, 382 file_name=file_name, 383 line_number=line_number, 384 module_name=module_name) 385 else: 386 check_breakpoint_result( 387 test, 388 break_results, 389 num_locations=num_expected_locations) 390 391 return get_bpno_from_match(break_results) 392 393 394def run_break_set_by_symbol( 395 test, 396 symbol, 397 extra_options=None, 398 num_expected_locations=-1, 399 sym_exact=False, 400 module_name=None): 401 """Set a breakpoint by symbol name. Common options are the same as run_break_set_by_file_and_line. 402 403 If sym_exact is true, then the output symbol must match the input exactly, otherwise we do a substring match.""" 404 command = 'breakpoint set -n "%s"' % (symbol) 405 406 if module_name: 407 command += " --shlib '%s'" % (module_name) 408 409 if extra_options: 410 command += " " + extra_options 411 412 break_results = run_break_set_command(test, command) 413 414 if num_expected_locations == 1 and sym_exact: 415 check_breakpoint_result( 416 test, 417 break_results, 418 num_locations=num_expected_locations, 419 symbol_name=symbol, 420 module_name=module_name) 421 else: 422 check_breakpoint_result( 423 test, 424 break_results, 425 num_locations=num_expected_locations) 426 427 return get_bpno_from_match(break_results) 428 429 430def run_break_set_by_selector( 431 test, 432 selector, 433 extra_options=None, 434 num_expected_locations=-1, 435 module_name=None): 436 """Set a breakpoint by selector. Common options are the same as run_break_set_by_file_and_line.""" 437 438 command = 'breakpoint set -S "%s"' % (selector) 439 440 if module_name: 441 command += ' --shlib "%s"' % (module_name) 442 443 if extra_options: 444 command += " " + extra_options 445 446 break_results = run_break_set_command(test, command) 447 448 if num_expected_locations == 1: 449 check_breakpoint_result( 450 test, 451 break_results, 452 num_locations=num_expected_locations, 453 symbol_name=selector, 454 symbol_match_exact=False, 455 module_name=module_name) 456 else: 457 check_breakpoint_result( 458 test, 459 break_results, 460 num_locations=num_expected_locations) 461 462 return get_bpno_from_match(break_results) 463 464 465def run_break_set_by_regexp( 466 test, 467 regexp, 468 extra_options=None, 469 num_expected_locations=-1): 470 """Set a breakpoint by regular expression match on symbol name. Common options are the same as run_break_set_by_file_and_line.""" 471 472 command = 'breakpoint set -r "%s"' % (regexp) 473 if extra_options: 474 command += " " + extra_options 475 476 break_results = run_break_set_command(test, command) 477 478 check_breakpoint_result( 479 test, 480 break_results, 481 num_locations=num_expected_locations) 482 483 return get_bpno_from_match(break_results) 484 485 486def run_break_set_by_source_regexp( 487 test, 488 regexp, 489 extra_options=None, 490 num_expected_locations=-1): 491 """Set a breakpoint by source regular expression. Common options are the same as run_break_set_by_file_and_line.""" 492 command = 'breakpoint set -p "%s"' % (regexp) 493 if extra_options: 494 command += " " + extra_options 495 496 break_results = run_break_set_command(test, command) 497 498 check_breakpoint_result( 499 test, 500 break_results, 501 num_locations=num_expected_locations) 502 503 return get_bpno_from_match(break_results) 504 505 506def run_break_set_command(test, command): 507 """Run the command passed in - it must be some break set variant - and analyze the result. 508 Returns a dictionary of information gleaned from the command-line results. 509 Will assert if the breakpoint setting fails altogether. 510 511 Dictionary will contain: 512 bpno - breakpoint of the newly created breakpoint, -1 on error. 513 num_locations - number of locations set for the breakpoint. 514 515 If there is only one location, the dictionary MAY contain: 516 file - source file name 517 line_no - source line number 518 symbol - symbol name 519 inline_symbol - inlined symbol name 520 offset - offset from the original symbol 521 module - module 522 address - address at which the breakpoint was set.""" 523 524 patterns = [ 525 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>[0-9]+) locations\.$", 526 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>no) locations \(pending\)\.", 527 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]+)$", 528 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]+)$"] 529 match_object = test.match(command, patterns) 530 break_results = match_object.groupdict() 531 532 # We always insert the breakpoint number, setting it to -1 if we couldn't find it 533 # Also, make sure it gets stored as an integer. 534 if not 'bpno' in break_results: 535 break_results['bpno'] = -1 536 else: 537 break_results['bpno'] = int(break_results['bpno']) 538 539 # We always insert the number of locations 540 # If ONE location is set for the breakpoint, then the output doesn't mention locations, but it has to be 1... 541 # We also make sure it is an integer. 542 543 if not 'num_locations' in break_results: 544 num_locations = 1 545 else: 546 num_locations = break_results['num_locations'] 547 if num_locations == 'no': 548 num_locations = 0 549 else: 550 num_locations = int(break_results['num_locations']) 551 552 break_results['num_locations'] = num_locations 553 554 if 'line_no' in break_results: 555 break_results['line_no'] = int(break_results['line_no']) 556 557 return break_results 558 559 560def get_bpno_from_match(break_results): 561 return int(break_results['bpno']) 562 563 564def check_breakpoint_result( 565 test, 566 break_results, 567 file_name=None, 568 line_number=-1, 569 symbol_name=None, 570 symbol_match_exact=True, 571 module_name=None, 572 offset=-1, 573 num_locations=-1): 574 575 out_num_locations = break_results['num_locations'] 576 577 if num_locations == -1: 578 test.assertTrue(out_num_locations > 0, 579 "Expecting one or more locations, got none.") 580 elif num_locations != -2: 581 test.assertTrue( 582 num_locations == out_num_locations, 583 "Expecting %d locations, got %d." % 584 (num_locations, 585 out_num_locations)) 586 587 if file_name: 588 out_file_name = "" 589 if 'file' in break_results: 590 out_file_name = break_results['file'] 591 test.assertTrue( 592 file_name.endswith(out_file_name), 593 "Breakpoint file name '%s' doesn't match resultant name '%s'." % 594 (file_name, 595 out_file_name)) 596 597 if line_number != -1: 598 out_line_number = -1 599 if 'line_no' in break_results: 600 out_line_number = break_results['line_no'] 601 602 test.assertTrue( 603 line_number == out_line_number, 604 "Breakpoint line number %s doesn't match resultant line %s." % 605 (line_number, 606 out_line_number)) 607 608 if symbol_name: 609 out_symbol_name = "" 610 # Look first for the inlined symbol name, otherwise use the symbol 611 # name: 612 if 'inline_symbol' in break_results and break_results['inline_symbol']: 613 out_symbol_name = break_results['inline_symbol'] 614 elif 'symbol' in break_results: 615 out_symbol_name = break_results['symbol'] 616 617 if symbol_match_exact: 618 test.assertTrue( 619 symbol_name == out_symbol_name, 620 "Symbol name '%s' doesn't match resultant symbol '%s'." % 621 (symbol_name, 622 out_symbol_name)) 623 else: 624 test.assertTrue( 625 out_symbol_name.find(symbol_name) != - 626 1, 627 "Symbol name '%s' isn't in resultant symbol '%s'." % 628 (symbol_name, 629 out_symbol_name)) 630 631 if module_name: 632 out_module_name = None 633 if 'module' in break_results: 634 out_module_name = break_results['module'] 635 636 test.assertTrue( 637 module_name.find(out_module_name) != - 638 1, 639 "Symbol module name '%s' isn't in expected module name '%s'." % 640 (out_module_name, 641 module_name)) 642 643# ================================================== 644# Utility functions related to Threads and Processes 645# ================================================== 646 647 648def get_stopped_threads(process, reason): 649 """Returns the thread(s) with the specified stop reason in a list. 650 651 The list can be empty if no such thread exists. 652 """ 653 threads = [] 654 for t in process: 655 if t.GetStopReason() == reason: 656 threads.append(t) 657 return threads 658 659 660def get_stopped_thread(process, reason): 661 """A convenience function which returns the first thread with the given stop 662 reason or None. 663 664 Example usages: 665 666 1. Get the stopped thread due to a breakpoint condition 667 668 ... 669 from lldbutil import get_stopped_thread 670 thread = get_stopped_thread(process, lldb.eStopReasonPlanComplete) 671 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition") 672 ... 673 674 2. Get the thread stopped due to a breakpoint 675 676 ... 677 from lldbutil import get_stopped_thread 678 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) 679 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint") 680 ... 681 682 """ 683 threads = get_stopped_threads(process, reason) 684 if len(threads) == 0: 685 return None 686 return threads[0] 687 688 689def get_threads_stopped_at_breakpoint_id(process, bpid): 690 """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt""" 691 stopped_threads = [] 692 threads = [] 693 694 stopped_threads = get_stopped_threads(process, lldb.eStopReasonBreakpoint) 695 696 if len(stopped_threads) == 0: 697 return threads 698 699 for thread in stopped_threads: 700 # Make sure we've hit our breakpoint... 701 break_id = thread.GetStopReasonDataAtIndex(0) 702 if break_id == bpid: 703 threads.append(thread) 704 705 return threads 706 707 708def get_threads_stopped_at_breakpoint(process, bkpt): 709 return get_threads_stopped_at_breakpoint_id(process, bkpt.GetID()) 710 711 712def get_one_thread_stopped_at_breakpoint_id( 713 process, bpid, require_exactly_one=True): 714 threads = get_threads_stopped_at_breakpoint_id(process, bpid) 715 if len(threads) == 0: 716 return None 717 if require_exactly_one and len(threads) != 1: 718 return None 719 720 return threads[0] 721 722 723def get_one_thread_stopped_at_breakpoint( 724 process, bkpt, require_exactly_one=True): 725 return get_one_thread_stopped_at_breakpoint_id( 726 process, bkpt.GetID(), require_exactly_one) 727 728 729def is_thread_crashed(test, thread): 730 """In the test suite we dereference a null pointer to simulate a crash. The way this is 731 reported depends on the platform.""" 732 if test.platformIsDarwin(): 733 return thread.GetStopReason( 734 ) == lldb.eStopReasonException and "EXC_BAD_ACCESS" in thread.GetStopDescription(100) 735 elif test.getPlatform() == "linux": 736 return thread.GetStopReason() == lldb.eStopReasonSignal and thread.GetStopReasonDataAtIndex( 737 0) == thread.GetProcess().GetUnixSignals().GetSignalNumberFromName("SIGSEGV") 738 elif test.getPlatform() == "windows": 739 return "Exception 0xc0000005" in thread.GetStopDescription(200) 740 else: 741 return "invalid address" in thread.GetStopDescription(100) 742 743 744def get_crashed_threads(test, process): 745 threads = [] 746 if process.GetState() != lldb.eStateStopped: 747 return threads 748 for thread in process: 749 if is_thread_crashed(test, thread): 750 threads.append(thread) 751 return threads 752 753# Helper functions for run_to_{source,name}_breakpoint: 754 755def run_to_breakpoint_make_target(test, exe_name = "a.out", in_cwd = True): 756 if in_cwd: 757 exe = test.getBuildArtifact(exe_name) 758 759 # Create the target 760 target = test.dbg.CreateTarget(exe) 761 test.assertTrue(target, "Target: %s is not valid."%(exe_name)) 762 763 # Set environment variables for the inferior. 764 if lldbtest_config.inferior_env: 765 test.runCmd('settings set target.env-vars {}'.format( 766 lldbtest_config.inferior_env)) 767 768 return target 769 770def run_to_breakpoint_do_run(test, target, bkpt, launch_info = None, 771 only_one_thread = True, extra_images = None): 772 773 # Launch the process, and do not stop at the entry point. 774 if not launch_info: 775 launch_info = target.GetLaunchInfo() 776 launch_info.SetWorkingDirectory(test.get_process_working_directory()) 777 778 if extra_images and lldb.remote_platform: 779 environ = test.registerSharedLibrariesWithTarget(target, extra_images) 780 launch_info.SetEnvironmentEntries(environ, True) 781 782 error = lldb.SBError() 783 process = target.Launch(launch_info, error) 784 785 test.assertTrue(process, 786 "Could not create a valid process for %s: %s"%(target.GetExecutable().GetFilename(), 787 error.GetCString())) 788 test.assertFalse(error.Fail(), 789 "Process launch failed: %s" % (error.GetCString())) 790 791 # Frame #0 should be at our breakpoint. 792 threads = get_threads_stopped_at_breakpoint( 793 process, bkpt) 794 795 num_threads = len(threads) 796 if only_one_thread: 797 test.assertEqual(num_threads, 1, "Expected 1 thread to stop at breakpoint, %d did."%(num_threads)) 798 else: 799 test.assertGreater(num_threads, 0, "No threads stopped at breakpoint") 800 801 thread = threads[0] 802 return (target, process, thread, bkpt) 803 804def run_to_name_breakpoint (test, bkpt_name, launch_info = None, 805 exe_name = "a.out", 806 bkpt_module = None, 807 in_cwd = True, 808 only_one_thread = True, 809 extra_images = None): 810 """Start up a target, using exe_name as the executable, and run it to 811 a breakpoint set by name on bkpt_name restricted to bkpt_module. 812 813 If you want to pass in launch arguments or environment 814 variables, you can optionally pass in an SBLaunchInfo. If you 815 do that, remember to set the working directory as well. 816 817 If your executable isn't called a.out, you can pass that in. 818 And if your executable isn't in the CWD, pass in the absolute 819 path to the executable in exe_name, and set in_cwd to False. 820 821 If you need to restrict the breakpoint to a particular module, 822 pass the module name (a string not a FileSpec) in bkpt_module. If 823 nothing is passed in setting will be unrestricted. 824 825 If the target isn't valid, the breakpoint isn't found, or hit, the 826 function will cause a testsuite failure. 827 828 If successful it returns a tuple with the target process and 829 thread that hit the breakpoint, and the breakpoint that we set 830 for you. 831 832 If only_one_thread is true, we require that there be only one 833 thread stopped at the breakpoint. Otherwise we only require one 834 or more threads stop there. If there are more than one, we return 835 the first thread that stopped. 836 """ 837 838 target = run_to_breakpoint_make_target(test, exe_name, in_cwd) 839 840 breakpoint = target.BreakpointCreateByName(bkpt_name, bkpt_module) 841 842 843 test.assertTrue(breakpoint.GetNumLocations() > 0, 844 "No locations found for name breakpoint: '%s'."%(bkpt_name)) 845 return run_to_breakpoint_do_run(test, target, breakpoint, launch_info, 846 only_one_thread, extra_images) 847 848def run_to_source_breakpoint(test, bkpt_pattern, source_spec, 849 launch_info = None, exe_name = "a.out", 850 bkpt_module = None, 851 in_cwd = True, 852 only_one_thread = True, 853 extra_images = None): 854 """Start up a target, using exe_name as the executable, and run it to 855 a breakpoint set by source regex bkpt_pattern. 856 857 The rest of the behavior is the same as run_to_name_breakpoint. 858 """ 859 860 target = run_to_breakpoint_make_target(test, exe_name, in_cwd) 861 # Set the breakpoints 862 breakpoint = target.BreakpointCreateBySourceRegex( 863 bkpt_pattern, source_spec, bkpt_module) 864 test.assertTrue(breakpoint.GetNumLocations() > 0, 865 'No locations found for source breakpoint: "%s", file: "%s", dir: "%s"' 866 %(bkpt_pattern, source_spec.GetFilename(), source_spec.GetDirectory())) 867 return run_to_breakpoint_do_run(test, target, breakpoint, launch_info, 868 only_one_thread, extra_images) 869 870def run_to_line_breakpoint(test, source_spec, line_number, column = 0, 871 launch_info = None, exe_name = "a.out", 872 bkpt_module = None, 873 in_cwd = True, 874 only_one_thread = True, 875 extra_images = None): 876 """Start up a target, using exe_name as the executable, and run it to 877 a breakpoint set by (source_spec, line_number(, column)). 878 879 The rest of the behavior is the same as run_to_name_breakpoint. 880 """ 881 882 target = run_to_breakpoint_make_target(test, exe_name, in_cwd) 883 # Set the breakpoints 884 breakpoint = target.BreakpointCreateByLocation( 885 source_spec, line_number, column, 0, lldb.SBFileSpecList()) 886 test.assertTrue(breakpoint.GetNumLocations() > 0, 887 'No locations found for line breakpoint: "%s:%d(:%d)", dir: "%s"' 888 %(source_spec.GetFilename(), line_number, column, 889 source_spec.GetDirectory())) 890 return run_to_breakpoint_do_run(test, target, breakpoint, launch_info, 891 only_one_thread, extra_images) 892 893 894def continue_to_breakpoint(process, bkpt): 895 """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None""" 896 process.Continue() 897 if process.GetState() != lldb.eStateStopped: 898 return None 899 else: 900 return get_threads_stopped_at_breakpoint(process, bkpt) 901 902 903def get_caller_symbol(thread): 904 """ 905 Returns the symbol name for the call site of the leaf function. 906 """ 907 depth = thread.GetNumFrames() 908 if depth <= 1: 909 return None 910 caller = thread.GetFrameAtIndex(1).GetSymbol() 911 if caller: 912 return caller.GetName() 913 else: 914 return None 915 916 917def get_function_names(thread): 918 """ 919 Returns a sequence of function names from the stack frames of this thread. 920 """ 921 def GetFuncName(i): 922 return thread.GetFrameAtIndex(i).GetFunctionName() 923 924 return list(map(GetFuncName, list(range(thread.GetNumFrames())))) 925 926 927def get_symbol_names(thread): 928 """ 929 Returns a sequence of symbols for this thread. 930 """ 931 def GetSymbol(i): 932 return thread.GetFrameAtIndex(i).GetSymbol().GetName() 933 934 return list(map(GetSymbol, list(range(thread.GetNumFrames())))) 935 936 937def get_pc_addresses(thread): 938 """ 939 Returns a sequence of pc addresses for this thread. 940 """ 941 def GetPCAddress(i): 942 return thread.GetFrameAtIndex(i).GetPCAddress() 943 944 return list(map(GetPCAddress, list(range(thread.GetNumFrames())))) 945 946 947def get_filenames(thread): 948 """ 949 Returns a sequence of file names from the stack frames of this thread. 950 """ 951 def GetFilename(i): 952 return thread.GetFrameAtIndex( 953 i).GetLineEntry().GetFileSpec().GetFilename() 954 955 return list(map(GetFilename, list(range(thread.GetNumFrames())))) 956 957 958def get_line_numbers(thread): 959 """ 960 Returns a sequence of line numbers from the stack frames of this thread. 961 """ 962 def GetLineNumber(i): 963 return thread.GetFrameAtIndex(i).GetLineEntry().GetLine() 964 965 return list(map(GetLineNumber, list(range(thread.GetNumFrames())))) 966 967 968def get_module_names(thread): 969 """ 970 Returns a sequence of module names from the stack frames of this thread. 971 """ 972 def GetModuleName(i): 973 return thread.GetFrameAtIndex( 974 i).GetModule().GetFileSpec().GetFilename() 975 976 return list(map(GetModuleName, list(range(thread.GetNumFrames())))) 977 978 979def get_stack_frames(thread): 980 """ 981 Returns a sequence of stack frames for this thread. 982 """ 983 def GetStackFrame(i): 984 return thread.GetFrameAtIndex(i) 985 986 return list(map(GetStackFrame, list(range(thread.GetNumFrames())))) 987 988 989def print_stacktrace(thread, string_buffer=False): 990 """Prints a simple stack trace of this thread.""" 991 992 output = SixStringIO() if string_buffer else sys.stdout 993 target = thread.GetProcess().GetTarget() 994 995 depth = thread.GetNumFrames() 996 997 mods = get_module_names(thread) 998 funcs = get_function_names(thread) 999 symbols = get_symbol_names(thread) 1000 files = get_filenames(thread) 1001 lines = get_line_numbers(thread) 1002 addrs = get_pc_addresses(thread) 1003 1004 if thread.GetStopReason() != lldb.eStopReasonInvalid: 1005 desc = "stop reason=" + stop_reason_to_str(thread.GetStopReason()) 1006 else: 1007 desc = "" 1008 print( 1009 "Stack trace for thread id={0:#x} name={1} queue={2} ".format( 1010 thread.GetThreadID(), 1011 thread.GetName(), 1012 thread.GetQueueName()) + desc, 1013 file=output) 1014 1015 for i in range(depth): 1016 frame = thread.GetFrameAtIndex(i) 1017 function = frame.GetFunction() 1018 1019 load_addr = addrs[i].GetLoadAddress(target) 1020 if not function: 1021 file_addr = addrs[i].GetFileAddress() 1022 start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress() 1023 symbol_offset = file_addr - start_addr 1024 print( 1025 " frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format( 1026 num=i, 1027 addr=load_addr, 1028 mod=mods[i], 1029 symbol=symbols[i], 1030 offset=symbol_offset), 1031 file=output) 1032 else: 1033 print( 1034 " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format( 1035 num=i, 1036 addr=load_addr, 1037 mod=mods[i], 1038 func='%s [inlined]' % 1039 funcs[i] if frame.IsInlined() else funcs[i], 1040 file=files[i], 1041 line=lines[i], 1042 args=get_args_as_string( 1043 frame, 1044 showFuncName=False) if not frame.IsInlined() else '()'), 1045 file=output) 1046 1047 if string_buffer: 1048 return output.getvalue() 1049 1050 1051def print_stacktraces(process, string_buffer=False): 1052 """Prints the stack traces of all the threads.""" 1053 1054 output = SixStringIO() if string_buffer else sys.stdout 1055 1056 print("Stack traces for " + str(process), file=output) 1057 1058 for thread in process: 1059 print(print_stacktrace(thread, string_buffer=True), file=output) 1060 1061 if string_buffer: 1062 return output.getvalue() 1063 1064 1065def expect_state_changes(test, listener, process, states, timeout=5): 1066 """Listens for state changed events on the listener and makes sure they match what we 1067 expect. Stop-and-restart events (where GetRestartedFromEvent() returns true) are ignored.""" 1068 1069 for expected_state in states: 1070 def get_next_event(): 1071 event = lldb.SBEvent() 1072 if not listener.WaitForEventForBroadcasterWithType( 1073 timeout, 1074 process.GetBroadcaster(), 1075 lldb.SBProcess.eBroadcastBitStateChanged, 1076 event): 1077 test.fail( 1078 "Timed out while waiting for a transition to state %s" % 1079 lldb.SBDebugger.StateAsCString(expected_state)) 1080 return event 1081 1082 event = get_next_event() 1083 while (lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateStopped and 1084 lldb.SBProcess.GetRestartedFromEvent(event)): 1085 # Ignore restarted event and the subsequent running event. 1086 event = get_next_event() 1087 test.assertEqual( 1088 lldb.SBProcess.GetStateFromEvent(event), 1089 lldb.eStateRunning, 1090 "Restarted event followed by a running event") 1091 event = get_next_event() 1092 1093 test.assertEqual( 1094 lldb.SBProcess.GetStateFromEvent(event), 1095 expected_state) 1096 1097# =================================== 1098# Utility functions related to Frames 1099# =================================== 1100 1101 1102def get_parent_frame(frame): 1103 """ 1104 Returns the parent frame of the input frame object; None if not available. 1105 """ 1106 thread = frame.GetThread() 1107 parent_found = False 1108 for f in thread: 1109 if parent_found: 1110 return f 1111 if f.GetFrameID() == frame.GetFrameID(): 1112 parent_found = True 1113 1114 # If we reach here, no parent has been found, return None. 1115 return None 1116 1117 1118def get_args_as_string(frame, showFuncName=True): 1119 """ 1120 Returns the args of the input frame object as a string. 1121 """ 1122 # arguments => True 1123 # locals => False 1124 # statics => False 1125 # in_scope_only => True 1126 vars = frame.GetVariables(True, False, False, True) # type of SBValueList 1127 args = [] # list of strings 1128 for var in vars: 1129 args.append("(%s)%s=%s" % (var.GetTypeName(), 1130 var.GetName(), 1131 var.GetValue())) 1132 if frame.GetFunction(): 1133 name = frame.GetFunction().GetName() 1134 elif frame.GetSymbol(): 1135 name = frame.GetSymbol().GetName() 1136 else: 1137 name = "" 1138 if showFuncName: 1139 return "%s(%s)" % (name, ", ".join(args)) 1140 else: 1141 return "(%s)" % (", ".join(args)) 1142 1143 1144def print_registers(frame, string_buffer=False): 1145 """Prints all the register sets of the frame.""" 1146 1147 output = SixStringIO() if string_buffer else sys.stdout 1148 1149 print("Register sets for " + str(frame), file=output) 1150 1151 registerSet = frame.GetRegisters() # Return type of SBValueList. 1152 print("Frame registers (size of register set = %d):" % 1153 registerSet.GetSize(), file=output) 1154 for value in registerSet: 1155 #print(value, file=output) 1156 print("%s (number of children = %d):" % 1157 (value.GetName(), value.GetNumChildren()), file=output) 1158 for child in value: 1159 print( 1160 "Name: %s, Value: %s" % 1161 (child.GetName(), 1162 child.GetValue()), 1163 file=output) 1164 1165 if string_buffer: 1166 return output.getvalue() 1167 1168 1169def get_registers(frame, kind): 1170 """Returns the registers given the frame and the kind of registers desired. 1171 1172 Returns None if there's no such kind. 1173 """ 1174 registerSet = frame.GetRegisters() # Return type of SBValueList. 1175 for value in registerSet: 1176 if kind.lower() in value.GetName().lower(): 1177 return value 1178 1179 return None 1180 1181 1182def get_GPRs(frame): 1183 """Returns the general purpose registers of the frame as an SBValue. 1184 1185 The returned SBValue object is iterable. An example: 1186 ... 1187 from lldbutil import get_GPRs 1188 regs = get_GPRs(frame) 1189 for reg in regs: 1190 print("%s => %s" % (reg.GetName(), reg.GetValue())) 1191 ... 1192 """ 1193 return get_registers(frame, "general purpose") 1194 1195 1196def get_FPRs(frame): 1197 """Returns the floating point registers of the frame as an SBValue. 1198 1199 The returned SBValue object is iterable. An example: 1200 ... 1201 from lldbutil import get_FPRs 1202 regs = get_FPRs(frame) 1203 for reg in regs: 1204 print("%s => %s" % (reg.GetName(), reg.GetValue())) 1205 ... 1206 """ 1207 return get_registers(frame, "floating point") 1208 1209 1210def get_ESRs(frame): 1211 """Returns the exception state registers of the frame as an SBValue. 1212 1213 The returned SBValue object is iterable. An example: 1214 ... 1215 from lldbutil import get_ESRs 1216 regs = get_ESRs(frame) 1217 for reg in regs: 1218 print("%s => %s" % (reg.GetName(), reg.GetValue())) 1219 ... 1220 """ 1221 return get_registers(frame, "exception state") 1222 1223# ====================================== 1224# Utility classes/functions for SBValues 1225# ====================================== 1226 1227 1228class BasicFormatter(object): 1229 """The basic formatter inspects the value object and prints the value.""" 1230 1231 def format(self, value, buffer=None, indent=0): 1232 if not buffer: 1233 output = SixStringIO() 1234 else: 1235 output = buffer 1236 # If there is a summary, it suffices. 1237 val = value.GetSummary() 1238 # Otherwise, get the value. 1239 if val is None: 1240 val = value.GetValue() 1241 if val is None and value.GetNumChildren() > 0: 1242 val = "%s (location)" % value.GetLocation() 1243 print("{indentation}({type}) {name} = {value}".format( 1244 indentation=' ' * indent, 1245 type=value.GetTypeName(), 1246 name=value.GetName(), 1247 value=val), file=output) 1248 return output.getvalue() 1249 1250 1251class ChildVisitingFormatter(BasicFormatter): 1252 """The child visiting formatter prints the value and its immediate children. 1253 1254 The constructor takes a keyword arg: indent_child, which defaults to 2. 1255 """ 1256 1257 def __init__(self, indent_child=2): 1258 """Default indentation of 2 SPC's for the children.""" 1259 self.cindent = indent_child 1260 1261 def format(self, value, buffer=None): 1262 if not buffer: 1263 output = SixStringIO() 1264 else: 1265 output = buffer 1266 1267 BasicFormatter.format(self, value, buffer=output) 1268 for child in value: 1269 BasicFormatter.format( 1270 self, child, buffer=output, indent=self.cindent) 1271 1272 return output.getvalue() 1273 1274 1275class RecursiveDecentFormatter(BasicFormatter): 1276 """The recursive decent formatter prints the value and the decendents. 1277 1278 The constructor takes two keyword args: indent_level, which defaults to 0, 1279 and indent_child, which defaults to 2. The current indentation level is 1280 determined by indent_level, while the immediate children has an additional 1281 indentation by inden_child. 1282 """ 1283 1284 def __init__(self, indent_level=0, indent_child=2): 1285 self.lindent = indent_level 1286 self.cindent = indent_child 1287 1288 def format(self, value, buffer=None): 1289 if not buffer: 1290 output = SixStringIO() 1291 else: 1292 output = buffer 1293 1294 BasicFormatter.format(self, value, buffer=output, indent=self.lindent) 1295 new_indent = self.lindent + self.cindent 1296 for child in value: 1297 if child.GetSummary() is not None: 1298 BasicFormatter.format( 1299 self, child, buffer=output, indent=new_indent) 1300 else: 1301 if child.GetNumChildren() > 0: 1302 rdf = RecursiveDecentFormatter(indent_level=new_indent) 1303 rdf.format(child, buffer=output) 1304 else: 1305 BasicFormatter.format( 1306 self, child, buffer=output, indent=new_indent) 1307 1308 return output.getvalue() 1309 1310# =========================================================== 1311# Utility functions for path manipulation on remote platforms 1312# =========================================================== 1313 1314 1315def join_remote_paths(*paths): 1316 # TODO: update with actual platform name for remote windows once it exists 1317 if lldb.remote_platform.GetName() == 'remote-windows': 1318 return os.path.join(*paths).replace(os.path.sep, '\\') 1319 return os.path.join(*paths).replace(os.path.sep, '/') 1320 1321 1322def append_to_process_working_directory(test, *paths): 1323 remote = lldb.remote_platform 1324 if remote: 1325 return join_remote_paths(remote.GetWorkingDirectory(), *paths) 1326 return os.path.join(test.getBuildDir(), *paths) 1327 1328# ================================================== 1329# Utility functions to get the correct signal number 1330# ================================================== 1331 1332import signal 1333 1334 1335def get_signal_number(signal_name): 1336 platform = lldb.remote_platform 1337 if platform and platform.IsValid(): 1338 signals = platform.GetUnixSignals() 1339 if signals.IsValid(): 1340 signal_number = signals.GetSignalNumberFromName(signal_name) 1341 if signal_number > 0: 1342 return signal_number 1343 # No remote platform; fall back to using local python signals. 1344 return getattr(signal, signal_name) 1345 1346 1347class PrintableRegex(object): 1348 1349 def __init__(self, text): 1350 self.regex = re.compile(text) 1351 self.text = text 1352 1353 def match(self, str): 1354 return self.regex.match(str) 1355 1356 def __str__(self): 1357 return "%s" % (self.text) 1358 1359 def __repr__(self): 1360 return "re.compile(%s) -> %s" % (self.text, self.regex) 1361 1362 1363def skip_if_callable(test, mycallable, reason): 1364 if six.callable(mycallable): 1365 if mycallable(test): 1366 test.skipTest(reason) 1367 return True 1368 return False 1369 1370 1371def skip_if_library_missing(test, target, library): 1372 def find_library(target, library): 1373 for module in target.modules: 1374 filename = module.file.GetFilename() 1375 if isinstance(library, str): 1376 if library == filename: 1377 return False 1378 elif hasattr(library, 'match'): 1379 if library.match(filename): 1380 return False 1381 return True 1382 1383 def find_library_callable(test): 1384 return find_library(target, library) 1385 return skip_if_callable( 1386 test, 1387 find_library_callable, 1388 "could not find library matching '%s' in target %s" % 1389 (library, 1390 target)) 1391 1392 1393def read_file_on_target(test, remote): 1394 if lldb.remote_platform: 1395 local = test.getBuildArtifact("file_from_target") 1396 error = lldb.remote_platform.Get(lldb.SBFileSpec(remote, False), 1397 lldb.SBFileSpec(local, True)) 1398 test.assertTrue(error.Success(), "Reading file {0} failed: {1}".format(remote, error)) 1399 else: 1400 local = remote 1401 with open(local, 'r') as f: 1402 return f.read() 1403 1404def read_file_from_process_wd(test, name): 1405 path = append_to_process_working_directory(test, name) 1406 return read_file_on_target(test, path) 1407 1408def wait_for_file_on_target(testcase, file_path, max_attempts=6): 1409 for i in range(max_attempts): 1410 err, retcode, msg = testcase.run_platform_command("ls %s" % file_path) 1411 if err.Success() and retcode == 0: 1412 break 1413 if i < max_attempts: 1414 # Exponential backoff! 1415 import time 1416 time.sleep(pow(2, i) * 0.25) 1417 else: 1418 testcase.fail( 1419 "File %s not found even after %d attempts." % 1420 (file_path, max_attempts)) 1421 1422 return read_file_on_target(testcase, file_path) 1423