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