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: 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 test.assertEqual(process.GetState(), lldb.eStateStopped) 792 793 # Frame #0 should be at our breakpoint. 794 threads = get_threads_stopped_at_breakpoint( 795 process, bkpt) 796 797 num_threads = len(threads) 798 if only_one_thread: 799 test.assertEqual(num_threads, 1, "Expected 1 thread to stop at breakpoint, %d did."%(num_threads)) 800 else: 801 test.assertGreater(num_threads, 0, "No threads stopped at breakpoint") 802 803 thread = threads[0] 804 return (target, process, thread, bkpt) 805 806def run_to_name_breakpoint (test, bkpt_name, launch_info = None, 807 exe_name = "a.out", 808 bkpt_module = None, 809 in_cwd = True, 810 only_one_thread = True, 811 extra_images = None): 812 """Start up a target, using exe_name as the executable, and run it to 813 a breakpoint set by name on bkpt_name restricted to bkpt_module. 814 815 If you want to pass in launch arguments or environment 816 variables, you can optionally pass in an SBLaunchInfo. If you 817 do that, remember to set the working directory as well. 818 819 If your executable isn't called a.out, you can pass that in. 820 And if your executable isn't in the CWD, pass in the absolute 821 path to the executable in exe_name, and set in_cwd to False. 822 823 If you need to restrict the breakpoint to a particular module, 824 pass the module name (a string not a FileSpec) in bkpt_module. If 825 nothing is passed in setting will be unrestricted. 826 827 If the target isn't valid, the breakpoint isn't found, or hit, the 828 function will cause a testsuite failure. 829 830 If successful it returns a tuple with the target process and 831 thread that hit the breakpoint, and the breakpoint that we set 832 for you. 833 834 If only_one_thread is true, we require that there be only one 835 thread stopped at the breakpoint. Otherwise we only require one 836 or more threads stop there. If there are more than one, we return 837 the first thread that stopped. 838 """ 839 840 target = run_to_breakpoint_make_target(test, exe_name, in_cwd) 841 842 breakpoint = target.BreakpointCreateByName(bkpt_name, bkpt_module) 843 844 845 test.assertTrue(breakpoint.GetNumLocations() > 0, 846 "No locations found for name breakpoint: '%s'."%(bkpt_name)) 847 return run_to_breakpoint_do_run(test, target, breakpoint, launch_info, 848 only_one_thread, extra_images) 849 850def run_to_source_breakpoint(test, bkpt_pattern, source_spec, 851 launch_info = None, exe_name = "a.out", 852 bkpt_module = None, 853 in_cwd = True, 854 only_one_thread = True, 855 extra_images = None): 856 """Start up a target, using exe_name as the executable, and run it to 857 a breakpoint set by source regex bkpt_pattern. 858 859 The rest of the behavior is the same as run_to_name_breakpoint. 860 """ 861 862 target = run_to_breakpoint_make_target(test, exe_name, in_cwd) 863 # Set the breakpoints 864 breakpoint = target.BreakpointCreateBySourceRegex( 865 bkpt_pattern, source_spec, bkpt_module) 866 test.assertTrue(breakpoint.GetNumLocations() > 0, 867 'No locations found for source breakpoint: "%s", file: "%s", dir: "%s"' 868 %(bkpt_pattern, source_spec.GetFilename(), source_spec.GetDirectory())) 869 return run_to_breakpoint_do_run(test, target, breakpoint, launch_info, 870 only_one_thread, extra_images) 871 872def run_to_line_breakpoint(test, source_spec, line_number, column = 0, 873 launch_info = None, exe_name = "a.out", 874 bkpt_module = None, 875 in_cwd = True, 876 only_one_thread = True, 877 extra_images = None): 878 """Start up a target, using exe_name as the executable, and run it to 879 a breakpoint set by (source_spec, line_number(, column)). 880 881 The rest of the behavior is the same as run_to_name_breakpoint. 882 """ 883 884 target = run_to_breakpoint_make_target(test, exe_name, in_cwd) 885 # Set the breakpoints 886 breakpoint = target.BreakpointCreateByLocation( 887 source_spec, line_number, column, 0, lldb.SBFileSpecList()) 888 test.assertTrue(breakpoint.GetNumLocations() > 0, 889 'No locations found for line breakpoint: "%s:%d(:%d)", dir: "%s"' 890 %(source_spec.GetFilename(), line_number, column, 891 source_spec.GetDirectory())) 892 return run_to_breakpoint_do_run(test, target, breakpoint, launch_info, 893 only_one_thread, extra_images) 894 895 896def continue_to_breakpoint(process, bkpt): 897 """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None""" 898 process.Continue() 899 if process.GetState() != lldb.eStateStopped: 900 return None 901 else: 902 return get_threads_stopped_at_breakpoint(process, bkpt) 903 904 905def get_caller_symbol(thread): 906 """ 907 Returns the symbol name for the call site of the leaf function. 908 """ 909 depth = thread.GetNumFrames() 910 if depth <= 1: 911 return None 912 caller = thread.GetFrameAtIndex(1).GetSymbol() 913 if caller: 914 return caller.GetName() 915 else: 916 return None 917 918 919def get_function_names(thread): 920 """ 921 Returns a sequence of function names from the stack frames of this thread. 922 """ 923 def GetFuncName(i): 924 return thread.GetFrameAtIndex(i).GetFunctionName() 925 926 return list(map(GetFuncName, list(range(thread.GetNumFrames())))) 927 928 929def get_symbol_names(thread): 930 """ 931 Returns a sequence of symbols for this thread. 932 """ 933 def GetSymbol(i): 934 return thread.GetFrameAtIndex(i).GetSymbol().GetName() 935 936 return list(map(GetSymbol, list(range(thread.GetNumFrames())))) 937 938 939def get_pc_addresses(thread): 940 """ 941 Returns a sequence of pc addresses for this thread. 942 """ 943 def GetPCAddress(i): 944 return thread.GetFrameAtIndex(i).GetPCAddress() 945 946 return list(map(GetPCAddress, list(range(thread.GetNumFrames())))) 947 948 949def get_filenames(thread): 950 """ 951 Returns a sequence of file names from the stack frames of this thread. 952 """ 953 def GetFilename(i): 954 return thread.GetFrameAtIndex( 955 i).GetLineEntry().GetFileSpec().GetFilename() 956 957 return list(map(GetFilename, list(range(thread.GetNumFrames())))) 958 959 960def get_line_numbers(thread): 961 """ 962 Returns a sequence of line numbers from the stack frames of this thread. 963 """ 964 def GetLineNumber(i): 965 return thread.GetFrameAtIndex(i).GetLineEntry().GetLine() 966 967 return list(map(GetLineNumber, list(range(thread.GetNumFrames())))) 968 969 970def get_module_names(thread): 971 """ 972 Returns a sequence of module names from the stack frames of this thread. 973 """ 974 def GetModuleName(i): 975 return thread.GetFrameAtIndex( 976 i).GetModule().GetFileSpec().GetFilename() 977 978 return list(map(GetModuleName, list(range(thread.GetNumFrames())))) 979 980 981def get_stack_frames(thread): 982 """ 983 Returns a sequence of stack frames for this thread. 984 """ 985 def GetStackFrame(i): 986 return thread.GetFrameAtIndex(i) 987 988 return list(map(GetStackFrame, list(range(thread.GetNumFrames())))) 989 990 991def print_stacktrace(thread, string_buffer=False): 992 """Prints a simple stack trace of this thread.""" 993 994 output = SixStringIO() if string_buffer else sys.stdout 995 target = thread.GetProcess().GetTarget() 996 997 depth = thread.GetNumFrames() 998 999 mods = get_module_names(thread) 1000 funcs = get_function_names(thread) 1001 symbols = get_symbol_names(thread) 1002 files = get_filenames(thread) 1003 lines = get_line_numbers(thread) 1004 addrs = get_pc_addresses(thread) 1005 1006 if thread.GetStopReason() != lldb.eStopReasonInvalid: 1007 desc = "stop reason=" + stop_reason_to_str(thread.GetStopReason()) 1008 else: 1009 desc = "" 1010 print( 1011 "Stack trace for thread id={0:#x} name={1} queue={2} ".format( 1012 thread.GetThreadID(), 1013 thread.GetName(), 1014 thread.GetQueueName()) + desc, 1015 file=output) 1016 1017 for i in range(depth): 1018 frame = thread.GetFrameAtIndex(i) 1019 function = frame.GetFunction() 1020 1021 load_addr = addrs[i].GetLoadAddress(target) 1022 if not function: 1023 file_addr = addrs[i].GetFileAddress() 1024 start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress() 1025 symbol_offset = file_addr - start_addr 1026 print( 1027 " frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format( 1028 num=i, 1029 addr=load_addr, 1030 mod=mods[i], 1031 symbol=symbols[i], 1032 offset=symbol_offset), 1033 file=output) 1034 else: 1035 print( 1036 " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format( 1037 num=i, 1038 addr=load_addr, 1039 mod=mods[i], 1040 func='%s [inlined]' % 1041 funcs[i] if frame.IsInlined() else funcs[i], 1042 file=files[i], 1043 line=lines[i], 1044 args=get_args_as_string( 1045 frame, 1046 showFuncName=False) if not frame.IsInlined() else '()'), 1047 file=output) 1048 1049 if string_buffer: 1050 return output.getvalue() 1051 1052 1053def print_stacktraces(process, string_buffer=False): 1054 """Prints the stack traces of all the threads.""" 1055 1056 output = SixStringIO() if string_buffer else sys.stdout 1057 1058 print("Stack traces for " + str(process), file=output) 1059 1060 for thread in process: 1061 print(print_stacktrace(thread, string_buffer=True), file=output) 1062 1063 if string_buffer: 1064 return output.getvalue() 1065 1066 1067def expect_state_changes(test, listener, process, states, timeout=30): 1068 """Listens for state changed events on the listener and makes sure they match what we 1069 expect. Stop-and-restart events (where GetRestartedFromEvent() returns true) are ignored.""" 1070 1071 for expected_state in states: 1072 def get_next_event(): 1073 event = lldb.SBEvent() 1074 if not listener.WaitForEventForBroadcasterWithType( 1075 timeout, 1076 process.GetBroadcaster(), 1077 lldb.SBProcess.eBroadcastBitStateChanged, 1078 event): 1079 test.fail( 1080 "Timed out while waiting for a transition to state %s" % 1081 lldb.SBDebugger.StateAsCString(expected_state)) 1082 return event 1083 1084 event = get_next_event() 1085 while (lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateStopped and 1086 lldb.SBProcess.GetRestartedFromEvent(event)): 1087 # Ignore restarted event and the subsequent running event. 1088 event = get_next_event() 1089 test.assertEqual( 1090 lldb.SBProcess.GetStateFromEvent(event), 1091 lldb.eStateRunning, 1092 "Restarted event followed by a running event") 1093 event = get_next_event() 1094 1095 test.assertEqual( 1096 lldb.SBProcess.GetStateFromEvent(event), 1097 expected_state) 1098 1099# =================================== 1100# Utility functions related to Frames 1101# =================================== 1102 1103 1104def get_parent_frame(frame): 1105 """ 1106 Returns the parent frame of the input frame object; None if not available. 1107 """ 1108 thread = frame.GetThread() 1109 parent_found = False 1110 for f in thread: 1111 if parent_found: 1112 return f 1113 if f.GetFrameID() == frame.GetFrameID(): 1114 parent_found = True 1115 1116 # If we reach here, no parent has been found, return None. 1117 return None 1118 1119 1120def get_args_as_string(frame, showFuncName=True): 1121 """ 1122 Returns the args of the input frame object as a string. 1123 """ 1124 # arguments => True 1125 # locals => False 1126 # statics => False 1127 # in_scope_only => True 1128 vars = frame.GetVariables(True, False, False, True) # type of SBValueList 1129 args = [] # list of strings 1130 for var in vars: 1131 args.append("(%s)%s=%s" % (var.GetTypeName(), 1132 var.GetName(), 1133 var.GetValue())) 1134 if frame.GetFunction(): 1135 name = frame.GetFunction().GetName() 1136 elif frame.GetSymbol(): 1137 name = frame.GetSymbol().GetName() 1138 else: 1139 name = "" 1140 if showFuncName: 1141 return "%s(%s)" % (name, ", ".join(args)) 1142 else: 1143 return "(%s)" % (", ".join(args)) 1144 1145 1146def print_registers(frame, string_buffer=False): 1147 """Prints all the register sets of the frame.""" 1148 1149 output = SixStringIO() if string_buffer else sys.stdout 1150 1151 print("Register sets for " + str(frame), file=output) 1152 1153 registerSet = frame.GetRegisters() # Return type of SBValueList. 1154 print("Frame registers (size of register set = %d):" % 1155 registerSet.GetSize(), file=output) 1156 for value in registerSet: 1157 #print(value, file=output) 1158 print("%s (number of children = %d):" % 1159 (value.GetName(), value.GetNumChildren()), file=output) 1160 for child in value: 1161 print( 1162 "Name: %s, Value: %s" % 1163 (child.GetName(), 1164 child.GetValue()), 1165 file=output) 1166 1167 if string_buffer: 1168 return output.getvalue() 1169 1170 1171def get_registers(frame, kind): 1172 """Returns the registers given the frame and the kind of registers desired. 1173 1174 Returns None if there's no such kind. 1175 """ 1176 registerSet = frame.GetRegisters() # Return type of SBValueList. 1177 for value in registerSet: 1178 if kind.lower() in value.GetName().lower(): 1179 return value 1180 1181 return None 1182 1183 1184def get_GPRs(frame): 1185 """Returns the general purpose registers of the frame as an SBValue. 1186 1187 The returned SBValue object is iterable. An example: 1188 ... 1189 from lldbutil import get_GPRs 1190 regs = get_GPRs(frame) 1191 for reg in regs: 1192 print("%s => %s" % (reg.GetName(), reg.GetValue())) 1193 ... 1194 """ 1195 return get_registers(frame, "general purpose") 1196 1197 1198def get_FPRs(frame): 1199 """Returns the floating point registers of the frame as an SBValue. 1200 1201 The returned SBValue object is iterable. An example: 1202 ... 1203 from lldbutil import get_FPRs 1204 regs = get_FPRs(frame) 1205 for reg in regs: 1206 print("%s => %s" % (reg.GetName(), reg.GetValue())) 1207 ... 1208 """ 1209 return get_registers(frame, "floating point") 1210 1211 1212def get_ESRs(frame): 1213 """Returns the exception state registers of the frame as an SBValue. 1214 1215 The returned SBValue object is iterable. An example: 1216 ... 1217 from lldbutil import get_ESRs 1218 regs = get_ESRs(frame) 1219 for reg in regs: 1220 print("%s => %s" % (reg.GetName(), reg.GetValue())) 1221 ... 1222 """ 1223 return get_registers(frame, "exception state") 1224 1225# ====================================== 1226# Utility classes/functions for SBValues 1227# ====================================== 1228 1229 1230class BasicFormatter(object): 1231 """The basic formatter inspects the value object and prints the value.""" 1232 1233 def format(self, value, buffer=None, indent=0): 1234 if not buffer: 1235 output = SixStringIO() 1236 else: 1237 output = buffer 1238 # If there is a summary, it suffices. 1239 val = value.GetSummary() 1240 # Otherwise, get the value. 1241 if val is None: 1242 val = value.GetValue() 1243 if val is None and value.GetNumChildren() > 0: 1244 val = "%s (location)" % value.GetLocation() 1245 print("{indentation}({type}) {name} = {value}".format( 1246 indentation=' ' * indent, 1247 type=value.GetTypeName(), 1248 name=value.GetName(), 1249 value=val), file=output) 1250 return output.getvalue() 1251 1252 1253class ChildVisitingFormatter(BasicFormatter): 1254 """The child visiting formatter prints the value and its immediate children. 1255 1256 The constructor takes a keyword arg: indent_child, which defaults to 2. 1257 """ 1258 1259 def __init__(self, indent_child=2): 1260 """Default indentation of 2 SPC's for the children.""" 1261 self.cindent = indent_child 1262 1263 def format(self, value, buffer=None): 1264 if not buffer: 1265 output = SixStringIO() 1266 else: 1267 output = buffer 1268 1269 BasicFormatter.format(self, value, buffer=output) 1270 for child in value: 1271 BasicFormatter.format( 1272 self, child, buffer=output, indent=self.cindent) 1273 1274 return output.getvalue() 1275 1276 1277class RecursiveDecentFormatter(BasicFormatter): 1278 """The recursive decent formatter prints the value and the decendents. 1279 1280 The constructor takes two keyword args: indent_level, which defaults to 0, 1281 and indent_child, which defaults to 2. The current indentation level is 1282 determined by indent_level, while the immediate children has an additional 1283 indentation by inden_child. 1284 """ 1285 1286 def __init__(self, indent_level=0, indent_child=2): 1287 self.lindent = indent_level 1288 self.cindent = indent_child 1289 1290 def format(self, value, buffer=None): 1291 if not buffer: 1292 output = SixStringIO() 1293 else: 1294 output = buffer 1295 1296 BasicFormatter.format(self, value, buffer=output, indent=self.lindent) 1297 new_indent = self.lindent + self.cindent 1298 for child in value: 1299 if child.GetSummary() is not None: 1300 BasicFormatter.format( 1301 self, child, buffer=output, indent=new_indent) 1302 else: 1303 if child.GetNumChildren() > 0: 1304 rdf = RecursiveDecentFormatter(indent_level=new_indent) 1305 rdf.format(child, buffer=output) 1306 else: 1307 BasicFormatter.format( 1308 self, child, buffer=output, indent=new_indent) 1309 1310 return output.getvalue() 1311 1312# =========================================================== 1313# Utility functions for path manipulation on remote platforms 1314# =========================================================== 1315 1316 1317def join_remote_paths(*paths): 1318 # TODO: update with actual platform name for remote windows once it exists 1319 if lldb.remote_platform.GetName() == 'remote-windows': 1320 return os.path.join(*paths).replace(os.path.sep, '\\') 1321 return os.path.join(*paths).replace(os.path.sep, '/') 1322 1323 1324def append_to_process_working_directory(test, *paths): 1325 remote = lldb.remote_platform 1326 if remote: 1327 return join_remote_paths(remote.GetWorkingDirectory(), *paths) 1328 return os.path.join(test.getBuildDir(), *paths) 1329 1330# ================================================== 1331# Utility functions to get the correct signal number 1332# ================================================== 1333 1334import signal 1335 1336 1337def get_signal_number(signal_name): 1338 platform = lldb.remote_platform 1339 if platform and platform.IsValid(): 1340 signals = platform.GetUnixSignals() 1341 if signals.IsValid(): 1342 signal_number = signals.GetSignalNumberFromName(signal_name) 1343 if signal_number > 0: 1344 return signal_number 1345 # No remote platform; fall back to using local python signals. 1346 return getattr(signal, signal_name) 1347 1348 1349class PrintableRegex(object): 1350 1351 def __init__(self, text): 1352 self.regex = re.compile(text) 1353 self.text = text 1354 1355 def match(self, str): 1356 return self.regex.match(str) 1357 1358 def __str__(self): 1359 return "%s" % (self.text) 1360 1361 def __repr__(self): 1362 return "re.compile(%s) -> %s" % (self.text, self.regex) 1363 1364 1365def skip_if_callable(test, mycallable, reason): 1366 if six.callable(mycallable): 1367 if mycallable(test): 1368 test.skipTest(reason) 1369 return True 1370 return False 1371 1372 1373def skip_if_library_missing(test, target, library): 1374 def find_library(target, library): 1375 for module in target.modules: 1376 filename = module.file.GetFilename() 1377 if isinstance(library, str): 1378 if library == filename: 1379 return False 1380 elif hasattr(library, 'match'): 1381 if library.match(filename): 1382 return False 1383 return True 1384 1385 def find_library_callable(test): 1386 return find_library(target, library) 1387 return skip_if_callable( 1388 test, 1389 find_library_callable, 1390 "could not find library matching '%s' in target %s" % 1391 (library, 1392 target)) 1393 1394 1395def read_file_on_target(test, remote): 1396 if lldb.remote_platform: 1397 local = test.getBuildArtifact("file_from_target") 1398 error = lldb.remote_platform.Get(lldb.SBFileSpec(remote, False), 1399 lldb.SBFileSpec(local, True)) 1400 test.assertTrue(error.Success(), "Reading file {0} failed: {1}".format(remote, error)) 1401 else: 1402 local = remote 1403 with open(local, 'r') as f: 1404 return f.read() 1405 1406def read_file_from_process_wd(test, name): 1407 path = append_to_process_working_directory(test, name) 1408 return read_file_on_target(test, path) 1409 1410def wait_for_file_on_target(testcase, file_path, max_attempts=6): 1411 for i in range(max_attempts): 1412 err, retcode, msg = testcase.run_platform_command("ls %s" % file_path) 1413 if err.Success() and retcode == 0: 1414 break 1415 if i < max_attempts: 1416 # Exponential backoff! 1417 import time 1418 time.sleep(pow(2, i) * 0.25) 1419 else: 1420 testcase.fail( 1421 "File %s not found even after %d attempts." % 1422 (file_path, max_attempts)) 1423 1424 return read_file_on_target(testcase, file_path) 1425