xref: /openbsd-src/gnu/llvm/lldb/packages/Python/lldbsuite/test/lldbutil.py (revision 24bb5fcea3ed904bc467217bdaadb5dfc618d5bf)
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