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