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