1"""
2LLDB module which provides the abstract base class of lldb test case.
3
4The concrete subclass can override lldbtest.TestBase in order to inherit the
5common behavior for unitest.TestCase.setUp/tearDown implemented in this file.
6
7The subclass should override the attribute mydir in order for the python runtime
8to locate the individual test cases when running as part of a large test suite
9or when running each test case as a separate python invocation.
10
11./dotest.py provides a test driver which sets up the environment to run the
12entire of part of the test suite .  Example:
13
14# Exercises the test suite in the types directory....
15/Volumes/data/lldb/svn/ToT/test $ ./dotest.py -A x86_64 types
16...
17
18Session logs for test failures/errors/unexpected successes will go into directory '2012-05-16-13_35_42'
19Command invoked: python ./dotest.py -A x86_64 types
20compilers=['clang']
21
22Configuration: arch=x86_64 compiler=clang
23----------------------------------------------------------------------
24Collected 72 tests
25
26........................................................................
27----------------------------------------------------------------------
28Ran 72 tests in 135.468s
29
30OK
31$
32"""
33
34from __future__ import absolute_import
35from __future__ import print_function
36
37# System modules
38import abc
39from distutils.version import LooseVersion
40from functools import wraps
41import gc
42import glob
43import io
44import os.path
45import re
46import shutil
47import signal
48from subprocess import *
49import sys
50import time
51import traceback
52import distutils.spawn
53
54# Third-party modules
55import unittest2
56from six import add_metaclass
57from six import StringIO as SixStringIO
58import six
59
60# LLDB modules
61import lldb
62from . import configuration
63from . import decorators
64from . import lldbplatformutil
65from . import lldbtest_config
66from . import lldbutil
67from . import test_categories
68from lldbsuite.support import encoded_file
69from lldbsuite.support import funcutils
70from lldbsuite.test.builders import get_builder
71
72# See also dotest.parseOptionsAndInitTestdirs(), where the environment variables
73# LLDB_COMMAND_TRACE is set from '-t' option.
74
75# By default, traceAlways is False.
76if "LLDB_COMMAND_TRACE" in os.environ and os.environ[
77        "LLDB_COMMAND_TRACE"] == "YES":
78    traceAlways = True
79else:
80    traceAlways = False
81
82# By default, doCleanup is True.
83if "LLDB_DO_CLEANUP" in os.environ and os.environ["LLDB_DO_CLEANUP"] == "NO":
84    doCleanup = False
85else:
86    doCleanup = True
87
88
89#
90# Some commonly used assert messages.
91#
92
93COMMAND_FAILED_AS_EXPECTED = "Command has failed as expected"
94
95CURRENT_EXECUTABLE_SET = "Current executable set successfully"
96
97PROCESS_IS_VALID = "Process is valid"
98
99PROCESS_KILLED = "Process is killed successfully"
100
101PROCESS_EXITED = "Process exited successfully"
102
103PROCESS_STOPPED = "Process status should be stopped"
104
105RUN_SUCCEEDED = "Process is launched successfully"
106
107RUN_COMPLETED = "Process exited successfully"
108
109BACKTRACE_DISPLAYED_CORRECTLY = "Backtrace displayed correctly"
110
111BREAKPOINT_CREATED = "Breakpoint created successfully"
112
113BREAKPOINT_STATE_CORRECT = "Breakpoint state is correct"
114
115BREAKPOINT_PENDING_CREATED = "Pending breakpoint created successfully"
116
117BREAKPOINT_HIT_ONCE = "Breakpoint resolved with hit count = 1"
118
119BREAKPOINT_HIT_TWICE = "Breakpoint resolved with hit count = 2"
120
121BREAKPOINT_HIT_THRICE = "Breakpoint resolved with hit count = 3"
122
123MISSING_EXPECTED_REGISTERS = "At least one expected register is unavailable."
124
125OBJECT_PRINTED_CORRECTLY = "Object printed correctly"
126
127SOURCE_DISPLAYED_CORRECTLY = "Source code displayed correctly"
128
129STEP_IN_SUCCEEDED = "Thread step-in succeeded"
130
131STEP_OUT_SUCCEEDED = "Thread step-out succeeded"
132
133STOPPED_DUE_TO_EXC_BAD_ACCESS = "Process should be stopped due to bad access exception"
134
135STOPPED_DUE_TO_ASSERT = "Process should be stopped due to an assertion"
136
137STOPPED_DUE_TO_BREAKPOINT = "Process should be stopped due to breakpoint"
138
139STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS = "%s, %s" % (
140    STOPPED_DUE_TO_BREAKPOINT, "instead, the actual stop reason is: '%s'")
141
142STOPPED_DUE_TO_BREAKPOINT_CONDITION = "Stopped due to breakpoint condition"
143
144STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT = "Stopped due to breakpoint and ignore count"
145
146STOPPED_DUE_TO_BREAKPOINT_JITTED_CONDITION = "Stopped due to breakpoint jitted condition"
147
148STOPPED_DUE_TO_SIGNAL = "Process state is stopped due to signal"
149
150STOPPED_DUE_TO_STEP_IN = "Process state is stopped due to step in"
151
152STOPPED_DUE_TO_WATCHPOINT = "Process should be stopped due to watchpoint"
153
154DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly"
155
156VALID_BREAKPOINT = "Got a valid breakpoint"
157
158VALID_BREAKPOINT_LOCATION = "Got a valid breakpoint location"
159
160VALID_COMMAND_INTERPRETER = "Got a valid command interpreter"
161
162VALID_FILESPEC = "Got a valid filespec"
163
164VALID_MODULE = "Got a valid module"
165
166VALID_PROCESS = "Got a valid process"
167
168VALID_SYMBOL = "Got a valid symbol"
169
170VALID_TARGET = "Got a valid target"
171
172VALID_PLATFORM = "Got a valid platform"
173
174VALID_TYPE = "Got a valid type"
175
176VALID_VARIABLE = "Got a valid variable"
177
178VARIABLES_DISPLAYED_CORRECTLY = "Variable(s) displayed correctly"
179
180WATCHPOINT_CREATED = "Watchpoint created successfully"
181
182
183def CMD_MSG(str):
184    '''A generic "Command '%s' did not return successfully" message generator.'''
185    return "Command '%s' did not return successfully" % str
186
187
188def COMPLETION_MSG(str_before, str_after, completions):
189    '''A generic assertion failed message generator for the completion mechanism.'''
190    return ("'%s' successfully completes to '%s', but completions were:\n%s"
191           % (str_before, str_after, "\n".join(completions)))
192
193
194def EXP_MSG(str, actual, exe):
195    '''A generic "'%s' returned unexpected result" message generator if exe.
196    Otherwise, it generates "'%s' does not match expected result" message.'''
197
198    return "'%s' %s result, got '%s'" % (
199        str, 'returned unexpected' if exe else 'does not match expected', actual.strip())
200
201
202def SETTING_MSG(setting):
203    '''A generic "Value of setting '%s' is not correct" message generator.'''
204    return "Value of setting '%s' is not correct" % setting
205
206
207def line_number(filename, string_to_match):
208    """Helper function to return the line number of the first matched string."""
209    with io.open(filename, mode='r', encoding="utf-8") as f:
210        for i, line in enumerate(f):
211            if line.find(string_to_match) != -1:
212                # Found our match.
213                return i + 1
214    raise Exception(
215        "Unable to find '%s' within file %s" %
216        (string_to_match, filename))
217
218def get_line(filename, line_number):
219    """Return the text of the line at the 1-based line number."""
220    with io.open(filename, mode='r', encoding="utf-8") as f:
221        return f.readlines()[line_number - 1]
222
223def pointer_size():
224    """Return the pointer size of the host system."""
225    import ctypes
226    a_pointer = ctypes.c_void_p(0xffff)
227    return 8 * ctypes.sizeof(a_pointer)
228
229
230def is_exe(fpath):
231    """Returns true if fpath is an executable."""
232    return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
233
234
235def which(program):
236    """Returns the full path to a program; None otherwise."""
237    fpath, fname = os.path.split(program)
238    if fpath:
239        if is_exe(program):
240            return program
241    else:
242        for path in os.environ["PATH"].split(os.pathsep):
243            exe_file = os.path.join(path, program)
244            if is_exe(exe_file):
245                return exe_file
246    return None
247
248class ValueCheck:
249    def __init__(self, name=None, value=None, type=None, summary=None,
250                 children=None):
251        """
252        :param name: The name that the SBValue should have. None if the summary
253                     should not be checked.
254        :param summary: The summary that the SBValue should have. None if the
255                        summary should not be checked.
256        :param value: The value that the SBValue should have. None if the value
257                      should not be checked.
258        :param type: The type that the SBValue result should have. None if the
259                     type should not be checked.
260        :param children: A list of ValueChecks that need to match the children
261                         of this SBValue. None if children shouldn't be checked.
262                         The order of checks is the order of the checks in the
263                         list. The number of checks has to match the number of
264                         children.
265        """
266        self.expect_name = name
267        self.expect_value = value
268        self.expect_type = type
269        self.expect_summary = summary
270        self.children = children
271
272    def check_value(self, test_base, val, error_msg=None):
273        """
274        Checks that the given value matches the currently set properties
275        of this ValueCheck. If a match failed, the given TestBase will
276        be used to emit an error. A custom error message can be specified
277        that will be used to describe failed check for this SBValue (but
278        not errors in the child values).
279        """
280
281        this_error_msg = error_msg if error_msg else ""
282        this_error_msg += "\nChecking SBValue: " + str(val)
283
284        test_base.assertSuccess(val.GetError())
285
286        if self.expect_name:
287            test_base.assertEqual(self.expect_name, val.GetName(),
288                                  this_error_msg)
289        if self.expect_value:
290            test_base.assertEqual(self.expect_value, val.GetValue(),
291                                  this_error_msg)
292        if self.expect_type:
293            test_base.assertEqual(self.expect_type, val.GetDisplayTypeName(),
294                                  this_error_msg)
295        if self.expect_summary:
296            test_base.assertEqual(self.expect_summary, val.GetSummary(),
297                                  this_error_msg)
298        if self.children is not None:
299            self.check_value_children(test_base, val, error_msg)
300
301    def check_value_children(self, test_base, val, error_msg=None):
302        """
303        Checks that the children of a SBValue match a certain structure and
304        have certain properties.
305
306        :param test_base: The current test's TestBase object.
307        :param val: The SBValue to check.
308        """
309
310        this_error_msg = error_msg if error_msg else ""
311        this_error_msg += "\nChecking SBValue: " + str(val)
312
313        test_base.assertEqual(len(self.children), val.GetNumChildren(), this_error_msg)
314
315        for i in range(0, val.GetNumChildren()):
316            expected_child = self.children[i]
317            actual_child = val.GetChildAtIndex(i)
318            expected_child.check_value(test_base, actual_child, error_msg)
319
320class recording(SixStringIO):
321    """
322    A nice little context manager for recording the debugger interactions into
323    our session object.  If trace flag is ON, it also emits the interactions
324    into the stderr.
325    """
326
327    def __init__(self, test, trace):
328        """Create a SixStringIO instance; record the session obj and trace flag."""
329        SixStringIO.__init__(self)
330        # The test might not have undergone the 'setUp(self)' phase yet, so that
331        # the attribute 'session' might not even exist yet.
332        self.session = getattr(test, "session", None) if test else None
333        self.trace = trace
334
335    def __enter__(self):
336        """
337        Context management protocol on entry to the body of the with statement.
338        Just return the SixStringIO object.
339        """
340        return self
341
342    def __exit__(self, type, value, tb):
343        """
344        Context management protocol on exit from the body of the with statement.
345        If trace is ON, it emits the recordings into stderr.  Always add the
346        recordings to our session object.  And close the SixStringIO object, too.
347        """
348        if self.trace:
349            print(self.getvalue(), file=sys.stderr)
350        if self.session:
351            print(self.getvalue(), file=self.session)
352        self.close()
353
354
355@add_metaclass(abc.ABCMeta)
356class _BaseProcess(object):
357
358    @abc.abstractproperty
359    def pid(self):
360        """Returns process PID if has been launched already."""
361
362    @abc.abstractmethod
363    def launch(self, executable, args):
364        """Launches new process with given executable and args."""
365
366    @abc.abstractmethod
367    def terminate(self):
368        """Terminates previously launched process.."""
369
370
371class _LocalProcess(_BaseProcess):
372
373    def __init__(self, trace_on):
374        self._proc = None
375        self._trace_on = trace_on
376        self._delayafterterminate = 0.1
377
378    @property
379    def pid(self):
380        return self._proc.pid
381
382    def launch(self, executable, args):
383        self._proc = Popen(
384            [executable] + args,
385            stdout=open(
386                os.devnull) if not self._trace_on else None,
387            stdin=PIPE,
388            preexec_fn=lldbplatformutil.enable_attach)
389
390    def terminate(self):
391        if self._proc.poll() is None:
392            # Terminate _proc like it does the pexpect
393            signals_to_try = [
394                sig for sig in [
395                    'SIGHUP',
396                    'SIGCONT',
397                    'SIGINT'] if sig in dir(signal)]
398            for sig in signals_to_try:
399                try:
400                    self._proc.send_signal(getattr(signal, sig))
401                    time.sleep(self._delayafterterminate)
402                    if self._proc.poll() is not None:
403                        return
404                except ValueError:
405                    pass  # Windows says SIGINT is not a valid signal to send
406            self._proc.terminate()
407            time.sleep(self._delayafterterminate)
408            if self._proc.poll() is not None:
409                return
410            self._proc.kill()
411            time.sleep(self._delayafterterminate)
412
413    def poll(self):
414        return self._proc.poll()
415
416
417class _RemoteProcess(_BaseProcess):
418
419    def __init__(self, install_remote):
420        self._pid = None
421        self._install_remote = install_remote
422
423    @property
424    def pid(self):
425        return self._pid
426
427    def launch(self, executable, args):
428        if self._install_remote:
429            src_path = executable
430            dst_path = lldbutil.join_remote_paths(
431                    lldb.remote_platform.GetWorkingDirectory(), os.path.basename(executable))
432
433            dst_file_spec = lldb.SBFileSpec(dst_path, False)
434            err = lldb.remote_platform.Install(
435                lldb.SBFileSpec(src_path, True), dst_file_spec)
436            if err.Fail():
437                raise Exception(
438                    "remote_platform.Install('%s', '%s') failed: %s" %
439                    (src_path, dst_path, err))
440        else:
441            dst_path = executable
442            dst_file_spec = lldb.SBFileSpec(executable, False)
443
444        launch_info = lldb.SBLaunchInfo(args)
445        launch_info.SetExecutableFile(dst_file_spec, True)
446        launch_info.SetWorkingDirectory(
447            lldb.remote_platform.GetWorkingDirectory())
448
449        # Redirect stdout and stderr to /dev/null
450        launch_info.AddSuppressFileAction(1, False, True)
451        launch_info.AddSuppressFileAction(2, False, True)
452
453        err = lldb.remote_platform.Launch(launch_info)
454        if err.Fail():
455            raise Exception(
456                "remote_platform.Launch('%s', '%s') failed: %s" %
457                (dst_path, args, err))
458        self._pid = launch_info.GetProcessID()
459
460    def terminate(self):
461        lldb.remote_platform.Kill(self._pid)
462
463# From 2.7's subprocess.check_output() convenience function.
464# Return a tuple (stdoutdata, stderrdata).
465
466
467def system(commands, **kwargs):
468    r"""Run an os command with arguments and return its output as a byte string.
469
470    If the exit code was non-zero it raises a CalledProcessError.  The
471    CalledProcessError object will have the return code in the returncode
472    attribute and output in the output attribute.
473
474    The arguments are the same as for the Popen constructor.  Example:
475
476    >>> check_output(["ls", "-l", "/dev/null"])
477    'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'
478
479    The stdout argument is not allowed as it is used internally.
480    To capture standard error in the result, use stderr=STDOUT.
481
482    >>> check_output(["/bin/sh", "-c",
483    ...               "ls -l non_existent_file ; exit 0"],
484    ...              stderr=STDOUT)
485    'ls: non_existent_file: No such file or directory\n'
486    """
487
488    # Assign the sender object to variable 'test' and remove it from kwargs.
489    test = kwargs.pop('sender', None)
490
491    # [['make', 'clean', 'foo'], ['make', 'foo']] -> ['make clean foo', 'make foo']
492    commandList = [' '.join(x) for x in commands]
493    output = ""
494    error = ""
495    for shellCommand in commandList:
496        if 'stdout' in kwargs:
497            raise ValueError(
498                'stdout argument not allowed, it will be overridden.')
499        if 'shell' in kwargs and kwargs['shell'] == False:
500            raise ValueError('shell=False not allowed')
501        process = Popen(
502            shellCommand,
503            stdout=PIPE,
504            stderr=STDOUT,
505            shell=True,
506            **kwargs)
507        pid = process.pid
508        this_output, this_error = process.communicate()
509        retcode = process.poll()
510
511        if retcode:
512            cmd = kwargs.get("args")
513            if cmd is None:
514                cmd = shellCommand
515            cpe = CalledProcessError(retcode, cmd)
516            # Ensure caller can access the stdout/stderr.
517            cpe.lldb_extensions = {
518                "combined_output": this_output,
519                "command": shellCommand
520            }
521            raise cpe
522        output = output + this_output.decode("utf-8", errors='ignore')
523    return output
524
525
526def getsource_if_available(obj):
527    """
528    Return the text of the source code for an object if available.  Otherwise,
529    a print representation is returned.
530    """
531    import inspect
532    try:
533        return inspect.getsource(obj)
534    except:
535        return repr(obj)
536
537
538def builder_module():
539    return get_builder(sys.platform)
540
541
542class Base(unittest2.TestCase):
543    """
544    Abstract base for performing lldb (see TestBase) or other generic tests (see
545    BenchBase for one example).  lldbtest.Base works with the test driver to
546    accomplish things.
547
548    """
549
550    # The concrete subclass should override this attribute.
551    mydir = None
552
553    # Keep track of the old current working directory.
554    oldcwd = None
555
556    @staticmethod
557    def compute_mydir(test_file):
558        '''Subclasses should call this function to correctly calculate the
559           required "mydir" attribute as follows:
560
561            mydir = TestBase.compute_mydir(__file__)
562        '''
563        # /abs/path/to/packages/group/subdir/mytest.py -> group/subdir
564        lldb_test_src = configuration.test_src_root
565        if not test_file.startswith(lldb_test_src):
566          raise Exception(
567              "Test file '%s' must reside within lldb_test_src "
568              "(which is '%s')." % (test_file, lldb_test_src))
569        return os.path.dirname(os.path.relpath(test_file, start=lldb_test_src))
570
571    def TraceOn(self):
572        """Returns True if we are in trace mode (tracing detailed test execution)."""
573        return traceAlways
574
575    def trace(self, *args,**kwargs):
576        with recording(self, self.TraceOn()) as sbuf:
577            print(*args, file=sbuf, **kwargs)
578
579    @classmethod
580    def setUpClass(cls):
581        """
582        Python unittest framework class setup fixture.
583        Do current directory manipulation.
584        """
585        # Fail fast if 'mydir' attribute is not overridden.
586        if not cls.mydir or len(cls.mydir) == 0:
587            raise Exception("Subclasses must override the 'mydir' attribute.")
588
589        # Save old working directory.
590        cls.oldcwd = os.getcwd()
591
592        full_dir = os.path.join(configuration.test_src_root, cls.mydir)
593        if traceAlways:
594            print("Change dir to:", full_dir, file=sys.stderr)
595        os.chdir(full_dir)
596        lldb.SBReproducer.SetWorkingDirectory(full_dir)
597
598        # Set platform context.
599        cls.platformContext = lldbplatformutil.createPlatformContext()
600
601    @classmethod
602    def tearDownClass(cls):
603        """
604        Python unittest framework class teardown fixture.
605        Do class-wide cleanup.
606        """
607
608        if doCleanup:
609            # First, let's do the platform-specific cleanup.
610            module = builder_module()
611            module.cleanup()
612
613            # Subclass might have specific cleanup function defined.
614            if getattr(cls, "classCleanup", None):
615                if traceAlways:
616                    print(
617                        "Call class-specific cleanup function for class:",
618                        cls,
619                        file=sys.stderr)
620                try:
621                    cls.classCleanup()
622                except:
623                    exc_type, exc_value, exc_tb = sys.exc_info()
624                    traceback.print_exception(exc_type, exc_value, exc_tb)
625
626        # Restore old working directory.
627        if traceAlways:
628            print("Restore dir to:", cls.oldcwd, file=sys.stderr)
629        os.chdir(cls.oldcwd)
630
631    def enableLogChannelsForCurrentTest(self):
632        if len(lldbtest_config.channels) == 0:
633            return
634
635        # if debug channels are specified in lldbtest_config.channels,
636        # create a new set of log files for every test
637        log_basename = self.getLogBasenameForCurrentTest()
638
639        # confirm that the file is writeable
640        host_log_path = "{}-host.log".format(log_basename)
641        open(host_log_path, 'w').close()
642        self.log_files.append(host_log_path)
643
644        log_enable = "log enable -Tpn -f {} ".format(host_log_path)
645        for channel_with_categories in lldbtest_config.channels:
646            channel_then_categories = channel_with_categories.split(' ', 1)
647            channel = channel_then_categories[0]
648            if len(channel_then_categories) > 1:
649                categories = channel_then_categories[1]
650            else:
651                categories = "default"
652
653            if channel == "gdb-remote" and lldb.remote_platform is None:
654                # communicate gdb-remote categories to debugserver
655                os.environ["LLDB_DEBUGSERVER_LOG_FLAGS"] = categories
656
657            self.ci.HandleCommand(
658                log_enable + channel_with_categories, self.res)
659            if not self.res.Succeeded():
660                raise Exception(
661                    'log enable failed (check LLDB_LOG_OPTION env variable)')
662
663        # Communicate log path name to debugserver & lldb-server
664        # For remote debugging, these variables need to be set when starting the platform
665        # instance.
666        if lldb.remote_platform is None:
667            server_log_path = "{}-server.log".format(log_basename)
668            open(server_log_path, 'w').close()
669            self.log_files.append(server_log_path)
670            os.environ["LLDB_DEBUGSERVER_LOG_FILE"] = server_log_path
671
672            # Communicate channels to lldb-server
673            os.environ["LLDB_SERVER_LOG_CHANNELS"] = ":".join(
674                lldbtest_config.channels)
675
676        self.addTearDownHook(self.disableLogChannelsForCurrentTest)
677
678    def disableLogChannelsForCurrentTest(self):
679        # close all log files that we opened
680        for channel_and_categories in lldbtest_config.channels:
681            # channel format - <channel-name> [<category0> [<category1> ...]]
682            channel = channel_and_categories.split(' ', 1)[0]
683            self.ci.HandleCommand("log disable " + channel, self.res)
684            if not self.res.Succeeded():
685                raise Exception(
686                    'log disable failed (check LLDB_LOG_OPTION env variable)')
687
688        # Retrieve the server log (if any) from the remote system. It is assumed the server log
689        # is writing to the "server.log" file in the current test directory. This can be
690        # achieved by setting LLDB_DEBUGSERVER_LOG_FILE="server.log" when starting remote
691        # platform.
692        if lldb.remote_platform:
693            server_log_path = self.getLogBasenameForCurrentTest() + "-server.log"
694            if lldb.remote_platform.Get(
695                lldb.SBFileSpec("server.log"),
696                lldb.SBFileSpec(server_log_path)).Success():
697                self.log_files.append(server_log_path)
698
699    def setPlatformWorkingDir(self):
700        if not lldb.remote_platform or not configuration.lldb_platform_working_dir:
701            return
702
703        components = self.mydir.split(os.path.sep) + [str(self.test_number), self.getBuildDirBasename()]
704        remote_test_dir = configuration.lldb_platform_working_dir
705        for c in components:
706            remote_test_dir = lldbutil.join_remote_paths(remote_test_dir, c)
707            error = lldb.remote_platform.MakeDirectory(
708                remote_test_dir, 448)  # 448 = 0o700
709            if error.Fail():
710                raise Exception("making remote directory '%s': %s" % (
711                    remote_test_dir, error))
712
713        lldb.remote_platform.SetWorkingDirectory(remote_test_dir)
714
715        # This function removes all files from the current working directory while leaving
716        # the directories in place. The cleanup is required to reduce the disk space required
717        # by the test suite while leaving the directories untouched is neccessary because
718        # sub-directories might belong to an other test
719        def clean_working_directory():
720            # TODO: Make it working on Windows when we need it for remote debugging support
721            # TODO: Replace the heuristic to remove the files with a logic what collects the
722            # list of files we have to remove during test runs.
723            shell_cmd = lldb.SBPlatformShellCommand(
724                "rm %s/*" % remote_test_dir)
725            lldb.remote_platform.Run(shell_cmd)
726        self.addTearDownHook(clean_working_directory)
727
728    def getSourceDir(self):
729        """Return the full path to the current test."""
730        return os.path.join(configuration.test_src_root, self.mydir)
731
732    def getBuildDirBasename(self):
733        return self.__class__.__module__ + "." + self.testMethodName
734
735    def getBuildDir(self):
736        """Return the full path to the current test."""
737        return os.path.join(configuration.test_build_dir, self.mydir,
738                            self.getBuildDirBasename())
739
740    def getReproducerDir(self):
741        """Return the full path to the reproducer if enabled."""
742        if configuration.capture_path:
743            return configuration.capture_path
744        if configuration.replay_path:
745            return configuration.replay_path
746        return None
747
748    def makeBuildDir(self):
749        """Create the test-specific working directory, deleting any previous
750        contents."""
751        bdir = self.getBuildDir()
752        if os.path.isdir(bdir):
753            shutil.rmtree(bdir)
754        lldbutil.mkdir_p(bdir)
755
756    def getBuildArtifact(self, name="a.out"):
757        """Return absolute path to an artifact in the test's build directory."""
758        return os.path.join(self.getBuildDir(), name)
759
760    def getSourcePath(self, name):
761        """Return absolute path to a file in the test's source directory."""
762        return os.path.join(self.getSourceDir(), name)
763
764    def getReproducerArtifact(self, name):
765        lldbutil.mkdir_p(self.getReproducerDir())
766        return os.path.join(self.getReproducerDir(), name)
767
768    def getReproducerRemappedPath(self, path):
769        assert configuration.replay_path
770        assert os.path.isabs(path)
771        path = os.path.relpath(path, '/')
772        return os.path.join(configuration.replay_path, 'root', path)
773
774    @classmethod
775    def setUpCommands(cls):
776        commands = [
777            # First of all, clear all settings to have clean state of global properties.
778            "settings clear -all",
779
780            # Disable Spotlight lookup. The testsuite creates
781            # different binaries with the same UUID, because they only
782            # differ in the debug info, which is not being hashed.
783            "settings set symbols.enable-external-lookup false",
784
785            # Inherit the TCC permissions from the inferior's parent.
786            "settings set target.inherit-tcc true",
787
788            # Kill rather than detach from the inferior if something goes wrong.
789            "settings set target.detach-on-error false",
790
791            # Disable fix-its by default so that incorrect expressions in tests don't
792            # pass just because Clang thinks it has a fix-it.
793            "settings set target.auto-apply-fixits false",
794
795            # Testsuite runs in parallel and the host can have also other load.
796            "settings set plugin.process.gdb-remote.packet-timeout 60",
797
798            'settings set symbols.clang-modules-cache-path "{}"'.format(
799                configuration.lldb_module_cache_dir),
800            "settings set use-color false",
801        ]
802
803        # Set any user-overridden settings.
804        for setting, value in configuration.settings:
805            commands.append('setting set %s %s'%(setting, value))
806
807        # Make sure that a sanitizer LLDB's environment doesn't get passed on.
808        if cls.platformContext and cls.platformContext.shlib_environment_var in os.environ:
809            commands.append('settings set target.env-vars {}='.format(
810                cls.platformContext.shlib_environment_var))
811
812        # Set environment variables for the inferior.
813        if lldbtest_config.inferior_env:
814            commands.append('settings set target.env-vars {}'.format(
815                lldbtest_config.inferior_env))
816        return commands
817
818    def setUp(self):
819        """Fixture for unittest test case setup.
820
821        It works with the test driver to conditionally skip tests and does other
822        initializations."""
823        #import traceback
824        # traceback.print_stack()
825
826        if "LIBCXX_PATH" in os.environ:
827            self.libcxxPath = os.environ["LIBCXX_PATH"]
828        else:
829            self.libcxxPath = None
830
831        if "LLDBVSCODE_EXEC" in os.environ:
832            self.lldbVSCodeExec = os.environ["LLDBVSCODE_EXEC"]
833        else:
834            self.lldbVSCodeExec = None
835
836        self.lldbOption = " ".join(
837            "-o '" + s + "'" for s in self.setUpCommands())
838
839        # If we spawn an lldb process for test (via pexpect), do not load the
840        # init file unless told otherwise.
841        if os.environ.get("NO_LLDBINIT") != "NO":
842            self.lldbOption += " --no-lldbinit"
843
844        # Assign the test method name to self.testMethodName.
845        #
846        # For an example of the use of this attribute, look at test/types dir.
847        # There are a bunch of test cases under test/types and we don't want the
848        # module cacheing subsystem to be confused with executable name "a.out"
849        # used for all the test cases.
850        self.testMethodName = self._testMethodName
851
852        # This is for the case of directly spawning 'lldb'/'gdb' and interacting
853        # with it using pexpect.
854        self.child = None
855        self.child_prompt = "(lldb) "
856        # If the child is interacting with the embedded script interpreter,
857        # there are two exits required during tear down, first to quit the
858        # embedded script interpreter and second to quit the lldb command
859        # interpreter.
860        self.child_in_script_interpreter = False
861
862        # These are for customized teardown cleanup.
863        self.dict = None
864        self.doTearDownCleanup = False
865        # And in rare cases where there are multiple teardown cleanups.
866        self.dicts = []
867        self.doTearDownCleanups = False
868
869        # List of spawned subproces.Popen objects
870        self.subprocesses = []
871
872        # List of log files produced by the current test.
873        self.log_files = []
874
875        # Create the build directory.
876        # The logs are stored in the build directory, so we have to create it
877        # before creating the first log file.
878        self.makeBuildDir()
879
880        session_file = self.getLogBasenameForCurrentTest()+".log"
881        self.log_files.append(session_file)
882
883        # Python 3 doesn't support unbuffered I/O in text mode.  Open buffered.
884        self.session = encoded_file.open(session_file, "utf-8", mode="w")
885
886        # Optimistically set __errored__, __failed__, __expected__ to False
887        # initially.  If the test errored/failed, the session info
888        # (self.session) is then dumped into a session specific file for
889        # diagnosis.
890        self.__cleanup_errored__ = False
891        self.__errored__ = False
892        self.__failed__ = False
893        self.__expected__ = False
894        # We are also interested in unexpected success.
895        self.__unexpected__ = False
896        # And skipped tests.
897        self.__skipped__ = False
898
899        # See addTearDownHook(self, hook) which allows the client to add a hook
900        # function to be run during tearDown() time.
901        self.hooks = []
902
903        # See HideStdout(self).
904        self.sys_stdout_hidden = False
905
906        if self.platformContext:
907            # set environment variable names for finding shared libraries
908            self.dylibPath = self.platformContext.shlib_environment_var
909
910        # Create the debugger instance.
911        self.dbg = lldb.SBDebugger.Create()
912        # Copy selected platform from a global instance if it exists.
913        if lldb.selected_platform is not None:
914            self.dbg.SetSelectedPlatform(lldb.selected_platform)
915
916        if not self.dbg:
917            raise Exception('Invalid debugger instance')
918
919        # Retrieve the associated command interpreter instance.
920        self.ci = self.dbg.GetCommandInterpreter()
921        if not self.ci:
922            raise Exception('Could not get the command interpreter')
923
924        # And the result object.
925        self.res = lldb.SBCommandReturnObject()
926
927        self.setPlatformWorkingDir()
928        self.enableLogChannelsForCurrentTest()
929
930        self.lib_lldb = None
931        self.framework_dir = None
932        self.darwinWithFramework = False
933
934        if sys.platform.startswith("darwin") and configuration.lldb_framework_path:
935            framework = configuration.lldb_framework_path
936            lib = os.path.join(framework, 'LLDB')
937            if os.path.exists(lib):
938                self.framework_dir = os.path.dirname(framework)
939                self.lib_lldb = lib
940                self.darwinWithFramework = self.platformIsDarwin()
941
942    def setAsync(self, value):
943        """ Sets async mode to True/False and ensures it is reset after the testcase completes."""
944        old_async = self.dbg.GetAsync()
945        self.dbg.SetAsync(value)
946        self.addTearDownHook(lambda: self.dbg.SetAsync(old_async))
947
948    def cleanupSubprocesses(self):
949        # Terminate subprocesses in reverse order from how they were created.
950        for p in reversed(self.subprocesses):
951            p.terminate()
952            del p
953        del self.subprocesses[:]
954
955    def spawnSubprocess(self, executable, args=[], install_remote=True):
956        """ Creates a subprocess.Popen object with the specified executable and arguments,
957            saves it in self.subprocesses, and returns the object.
958        """
959        proc = _RemoteProcess(
960            install_remote) if lldb.remote_platform else _LocalProcess(self.TraceOn())
961        proc.launch(executable, args)
962        self.subprocesses.append(proc)
963        return proc
964
965    def HideStdout(self):
966        """Hide output to stdout from the user.
967
968        During test execution, there might be cases where we don't want to show the
969        standard output to the user.  For example,
970
971            self.runCmd(r'''sc print("\n\n\tHello!\n")''')
972
973        tests whether command abbreviation for 'script' works or not.  There is no
974        need to show the 'Hello' output to the user as long as the 'script' command
975        succeeds and we are not in TraceOn() mode (see the '-t' option).
976
977        In this case, the test method calls self.HideStdout(self) to redirect the
978        sys.stdout to a null device, and restores the sys.stdout upon teardown.
979
980        Note that you should only call this method at most once during a test case
981        execution.  Any subsequent call has no effect at all."""
982        if self.sys_stdout_hidden:
983            return
984
985        self.sys_stdout_hidden = True
986        old_stdout = sys.stdout
987        sys.stdout = open(os.devnull, 'w')
988
989        def restore_stdout():
990            sys.stdout = old_stdout
991        self.addTearDownHook(restore_stdout)
992
993    # =======================================================================
994    # Methods for customized teardown cleanups as well as execution of hooks.
995    # =======================================================================
996
997    def setTearDownCleanup(self, dictionary=None):
998        """Register a cleanup action at tearDown() time with a dictionary"""
999        self.dict = dictionary
1000        self.doTearDownCleanup = True
1001
1002    def addTearDownCleanup(self, dictionary):
1003        """Add a cleanup action at tearDown() time with a dictionary"""
1004        self.dicts.append(dictionary)
1005        self.doTearDownCleanups = True
1006
1007    def addTearDownHook(self, hook):
1008        """
1009        Add a function to be run during tearDown() time.
1010
1011        Hooks are executed in a first come first serve manner.
1012        """
1013        if six.callable(hook):
1014            with recording(self, traceAlways) as sbuf:
1015                print(
1016                    "Adding tearDown hook:",
1017                    getsource_if_available(hook),
1018                    file=sbuf)
1019            self.hooks.append(hook)
1020
1021        return self
1022
1023    def deletePexpectChild(self):
1024        # This is for the case of directly spawning 'lldb' and interacting with it
1025        # using pexpect.
1026        if self.child and self.child.isalive():
1027            import pexpect
1028            with recording(self, traceAlways) as sbuf:
1029                print("tearing down the child process....", file=sbuf)
1030            try:
1031                if self.child_in_script_interpreter:
1032                    self.child.sendline('quit()')
1033                    self.child.expect_exact(self.child_prompt)
1034                self.child.sendline(
1035                    'settings set interpreter.prompt-on-quit false')
1036                self.child.sendline('quit')
1037                self.child.expect(pexpect.EOF)
1038            except (ValueError, pexpect.ExceptionPexpect):
1039                # child is already terminated
1040                pass
1041            except OSError as exception:
1042                import errno
1043                if exception.errno != errno.EIO:
1044                    # unexpected error
1045                    raise
1046                # child is already terminated
1047            finally:
1048                # Give it one final blow to make sure the child is terminated.
1049                self.child.close()
1050
1051    def tearDown(self):
1052        """Fixture for unittest test case teardown."""
1053        self.deletePexpectChild()
1054
1055        # Check and run any hook functions.
1056        for hook in reversed(self.hooks):
1057            with recording(self, traceAlways) as sbuf:
1058                print(
1059                    "Executing tearDown hook:",
1060                    getsource_if_available(hook),
1061                    file=sbuf)
1062            if funcutils.requires_self(hook):
1063                hook(self)
1064            else:
1065                hook()  # try the plain call and hope it works
1066
1067        del self.hooks
1068
1069        # Perform registered teardown cleanup.
1070        if doCleanup and self.doTearDownCleanup:
1071            self.cleanup(dictionary=self.dict)
1072
1073        # In rare cases where there are multiple teardown cleanups added.
1074        if doCleanup and self.doTearDownCleanups:
1075            if self.dicts:
1076                for dict in reversed(self.dicts):
1077                    self.cleanup(dictionary=dict)
1078
1079        # Remove subprocesses created by the test.
1080        self.cleanupSubprocesses()
1081
1082        # This must be the last statement, otherwise teardown hooks or other
1083        # lines might depend on this still being active.
1084        lldb.SBDebugger.Destroy(self.dbg)
1085        del self.dbg
1086
1087        # All modules should be orphaned now so that they can be cleared from
1088        # the shared module cache.
1089        lldb.SBModule.GarbageCollectAllocatedModules()
1090
1091        # Modules are not orphaned during reproducer replay because they're
1092        # leaked on purpose.
1093        if not configuration.is_reproducer():
1094            # Assert that the global module cache is empty.
1095            self.assertEqual(lldb.SBModule.GetNumberAllocatedModules(), 0)
1096
1097
1098    # =========================================================
1099    # Various callbacks to allow introspection of test progress
1100    # =========================================================
1101
1102    def markError(self):
1103        """Callback invoked when an error (unexpected exception) errored."""
1104        self.__errored__ = True
1105        with recording(self, False) as sbuf:
1106            # False because there's no need to write "ERROR" to the stderr twice.
1107            # Once by the Python unittest framework, and a second time by us.
1108            print("ERROR", file=sbuf)
1109
1110    def markCleanupError(self):
1111        """Callback invoked when an error occurs while a test is cleaning up."""
1112        self.__cleanup_errored__ = True
1113        with recording(self, False) as sbuf:
1114            # False because there's no need to write "CLEANUP_ERROR" to the stderr twice.
1115            # Once by the Python unittest framework, and a second time by us.
1116            print("CLEANUP_ERROR", file=sbuf)
1117
1118    def markFailure(self):
1119        """Callback invoked when a failure (test assertion failure) occurred."""
1120        self.__failed__ = True
1121        with recording(self, False) as sbuf:
1122            # False because there's no need to write "FAIL" to the stderr twice.
1123            # Once by the Python unittest framework, and a second time by us.
1124            print("FAIL", file=sbuf)
1125
1126    def markExpectedFailure(self, err, bugnumber):
1127        """Callback invoked when an expected failure/error occurred."""
1128        self.__expected__ = True
1129        with recording(self, False) as sbuf:
1130            # False because there's no need to write "expected failure" to the
1131            # stderr twice.
1132            # Once by the Python unittest framework, and a second time by us.
1133            if bugnumber is None:
1134                print("expected failure", file=sbuf)
1135            else:
1136                print(
1137                    "expected failure (problem id:" + str(bugnumber) + ")",
1138                    file=sbuf)
1139
1140    def markSkippedTest(self):
1141        """Callback invoked when a test is skipped."""
1142        self.__skipped__ = True
1143        with recording(self, False) as sbuf:
1144            # False because there's no need to write "skipped test" to the
1145            # stderr twice.
1146            # Once by the Python unittest framework, and a second time by us.
1147            print("skipped test", file=sbuf)
1148
1149    def markUnexpectedSuccess(self, bugnumber):
1150        """Callback invoked when an unexpected success occurred."""
1151        self.__unexpected__ = True
1152        with recording(self, False) as sbuf:
1153            # False because there's no need to write "unexpected success" to the
1154            # stderr twice.
1155            # Once by the Python unittest framework, and a second time by us.
1156            if bugnumber is None:
1157                print("unexpected success", file=sbuf)
1158            else:
1159                print(
1160                    "unexpected success (problem id:" + str(bugnumber) + ")",
1161                    file=sbuf)
1162
1163    def getRerunArgs(self):
1164        return " -f %s.%s" % (self.__class__.__name__, self._testMethodName)
1165
1166    def getLogBasenameForCurrentTest(self, prefix="Incomplete"):
1167        """
1168        returns a partial path that can be used as the beginning of the name of multiple
1169        log files pertaining to this test
1170        """
1171        return os.path.join(self.getBuildDir(), prefix)
1172
1173    def dumpSessionInfo(self):
1174        """
1175        Dump the debugger interactions leading to a test error/failure.  This
1176        allows for more convenient postmortem analysis.
1177
1178        See also LLDBTestResult (dotest.py) which is a singlton class derived
1179        from TextTestResult and overwrites addError, addFailure, and
1180        addExpectedFailure methods to allow us to to mark the test instance as
1181        such.
1182        """
1183
1184        # We are here because self.tearDown() detected that this test instance
1185        # either errored or failed.  The lldb.test_result singleton contains
1186        # two lists (errors and failures) which get populated by the unittest
1187        # framework.  Look over there for stack trace information.
1188        #
1189        # The lists contain 2-tuples of TestCase instances and strings holding
1190        # formatted tracebacks.
1191        #
1192        # See http://docs.python.org/library/unittest.html#unittest.TestResult.
1193
1194        # output tracebacks into session
1195        pairs = []
1196        if self.__errored__:
1197            pairs = configuration.test_result.errors
1198            prefix = 'Error'
1199        elif self.__cleanup_errored__:
1200            pairs = configuration.test_result.cleanup_errors
1201            prefix = 'CleanupError'
1202        elif self.__failed__:
1203            pairs = configuration.test_result.failures
1204            prefix = 'Failure'
1205        elif self.__expected__:
1206            pairs = configuration.test_result.expectedFailures
1207            prefix = 'ExpectedFailure'
1208        elif self.__skipped__:
1209            prefix = 'SkippedTest'
1210        elif self.__unexpected__:
1211            prefix = 'UnexpectedSuccess'
1212        else:
1213            prefix = 'Success'
1214
1215        if not self.__unexpected__ and not self.__skipped__:
1216            for test, traceback in pairs:
1217                if test is self:
1218                    print(traceback, file=self.session)
1219
1220        import datetime
1221        print(
1222            "Session info generated @",
1223            datetime.datetime.now().ctime(),
1224            file=self.session)
1225        self.session.close()
1226        del self.session
1227
1228        # process the log files
1229        if prefix != 'Success' or lldbtest_config.log_success:
1230            # keep all log files, rename them to include prefix
1231            src_log_basename = self.getLogBasenameForCurrentTest()
1232            dst_log_basename = self.getLogBasenameForCurrentTest(prefix)
1233            for src in self.log_files:
1234                if os.path.isfile(src):
1235                    dst = src.replace(src_log_basename, dst_log_basename)
1236                    if os.name == "nt" and os.path.isfile(dst):
1237                        # On Windows, renaming a -> b will throw an exception if
1238                        # b exists.  On non-Windows platforms it silently
1239                        # replaces the destination.  Ultimately this means that
1240                        # atomic renames are not guaranteed to be possible on
1241                        # Windows, but we need this to work anyway, so just
1242                        # remove the destination first if it already exists.
1243                        remove_file(dst)
1244
1245                    lldbutil.mkdir_p(os.path.dirname(dst))
1246                    os.rename(src, dst)
1247        else:
1248            # success!  (and we don't want log files) delete log files
1249            for log_file in self.log_files:
1250                if os.path.isfile(log_file):
1251                    remove_file(log_file)
1252
1253    # ====================================================
1254    # Config. methods supported through a plugin interface
1255    # (enables reading of the current test configuration)
1256    # ====================================================
1257
1258    def isMIPS(self):
1259        """Returns true if the architecture is MIPS."""
1260        arch = self.getArchitecture()
1261        if re.match("mips", arch):
1262            return True
1263        return False
1264
1265    def isPPC64le(self):
1266        """Returns true if the architecture is PPC64LE."""
1267        arch = self.getArchitecture()
1268        if re.match("powerpc64le", arch):
1269            return True
1270        return False
1271
1272    def isAArch64SVE(self):
1273        triple = self.dbg.GetSelectedPlatform().GetTriple()
1274
1275        # TODO other platforms, please implement this function
1276        if not re.match(".*-.*-linux", triple):
1277            return False
1278
1279        # Need to do something different for non-Linux/Android targets
1280        cpuinfo_path = self.getBuildArtifact("cpuinfo")
1281        if configuration.lldb_platform_name:
1282            self.runCmd('platform get-file "/proc/cpuinfo" ' + cpuinfo_path)
1283        else:
1284            cpuinfo_path = "/proc/cpuinfo"
1285
1286        try:
1287            f = open(cpuinfo_path, 'r')
1288            cpuinfo = f.read()
1289            f.close()
1290        except:
1291            return False
1292
1293        return " sve " in cpuinfo
1294
1295    def hasLinuxVmFlags(self):
1296        """ Check that the target machine has "VmFlags" lines in
1297        its /proc/{pid}/smaps files."""
1298
1299        triple = self.dbg.GetSelectedPlatform().GetTriple()
1300        if not re.match(".*-.*-linux", triple):
1301            return False
1302
1303        self.runCmd('platform process list')
1304        pid = None
1305        for line in self.res.GetOutput().splitlines():
1306            if 'lldb-server' in line:
1307                pid = line.split(' ')[0]
1308                break
1309
1310        if pid is None:
1311            return False
1312
1313        smaps_path = self.getBuildArtifact('smaps')
1314        self.runCmd('platform get-file "/proc/{}/smaps" {}'.format(pid, smaps_path))
1315
1316        with open(smaps_path, 'r') as f:
1317            return "VmFlags" in f.read()
1318
1319    def getArchitecture(self):
1320        """Returns the architecture in effect the test suite is running with."""
1321        module = builder_module()
1322        arch = module.getArchitecture()
1323        if arch == 'amd64':
1324            arch = 'x86_64'
1325        if arch in ['armv7l', 'armv8l'] :
1326            arch = 'arm'
1327        return arch
1328
1329    def getLldbArchitecture(self):
1330        """Returns the architecture of the lldb binary."""
1331        if not hasattr(self, 'lldbArchitecture'):
1332
1333            # spawn local process
1334            command = [
1335                lldbtest_config.lldbExec,
1336                "-o",
1337                "file " + lldbtest_config.lldbExec,
1338                "-o",
1339                "quit"
1340            ]
1341
1342            output = check_output(command)
1343            str = output.decode("utf-8")
1344
1345            for line in str.splitlines():
1346                m = re.search(
1347                    "Current executable set to '.*' \\((.*)\\)\\.", line)
1348                if m:
1349                    self.lldbArchitecture = m.group(1)
1350                    break
1351
1352        return self.lldbArchitecture
1353
1354    def getCompiler(self):
1355        """Returns the compiler in effect the test suite is running with."""
1356        module = builder_module()
1357        return module.getCompiler()
1358
1359    def getCompilerBinary(self):
1360        """Returns the compiler binary the test suite is running with."""
1361        return self.getCompiler().split()[0]
1362
1363    def getCompilerVersion(self):
1364        """ Returns a string that represents the compiler version.
1365            Supports: llvm, clang.
1366        """
1367        compiler = self.getCompilerBinary()
1368        version_output = system([[compiler, "--version"]])
1369        for line in version_output.split(os.linesep):
1370            m = re.search('version ([0-9.]+)', line)
1371            if m:
1372                return m.group(1)
1373        return 'unknown'
1374
1375    def getDwarfVersion(self):
1376        """ Returns the dwarf version generated by clang or '0'. """
1377        if configuration.dwarf_version:
1378            return str(configuration.dwarf_version)
1379        if 'clang' in self.getCompiler():
1380            try:
1381                driver_output = check_output(
1382                    [self.getCompiler()] + '-g -c -x c - -o - -###'.split(),
1383                    stderr=STDOUT)
1384                driver_output = driver_output.decode("utf-8")
1385                for line in driver_output.split(os.linesep):
1386                    m = re.search('dwarf-version=([0-9])', line)
1387                    if m:
1388                        return m.group(1)
1389            except: pass
1390        return '0'
1391
1392    def platformIsDarwin(self):
1393        """Returns true if the OS triple for the selected platform is any valid apple OS"""
1394        return lldbplatformutil.platformIsDarwin()
1395
1396    def hasDarwinFramework(self):
1397        return self.darwinWithFramework
1398
1399    def getPlatform(self):
1400        """Returns the target platform the test suite is running on."""
1401        return lldbplatformutil.getPlatform()
1402
1403    def isIntelCompiler(self):
1404        """ Returns true if using an Intel (ICC) compiler, false otherwise. """
1405        return any([x in self.getCompiler() for x in ["icc", "icpc", "icl"]])
1406
1407    def expectedCompilerVersion(self, compiler_version):
1408        """Returns True iff compiler_version[1] matches the current compiler version.
1409           Use compiler_version[0] to specify the operator used to determine if a match has occurred.
1410           Any operator other than the following defaults to an equality test:
1411             '>', '>=', "=>", '<', '<=', '=<', '!=', "!" or 'not'
1412
1413           If the current compiler version cannot be determined, we assume it is close to the top
1414           of trunk, so any less-than or equal-to comparisons will return False, and any
1415           greater-than or not-equal-to comparisons will return True.
1416        """
1417        if compiler_version is None:
1418            return True
1419        operator = str(compiler_version[0])
1420        version = compiler_version[1]
1421
1422        if version is None:
1423            return True
1424
1425        test_compiler_version = self.getCompilerVersion()
1426        if test_compiler_version == 'unknown':
1427            # Assume the compiler version is at or near the top of trunk.
1428            return operator in ['>', '>=', '!', '!=', 'not']
1429
1430        if operator == '>':
1431            return LooseVersion(test_compiler_version) > LooseVersion(version)
1432        if operator == '>=' or operator == '=>':
1433            return LooseVersion(test_compiler_version) >= LooseVersion(version)
1434        if operator == '<':
1435            return LooseVersion(test_compiler_version) < LooseVersion(version)
1436        if operator == '<=' or operator == '=<':
1437            return LooseVersion(test_compiler_version) <= LooseVersion(version)
1438        if operator == '!=' or operator == '!' or operator == 'not':
1439            return str(version) not in str(test_compiler_version)
1440        return str(version) in str(test_compiler_version)
1441
1442    def expectedCompiler(self, compilers):
1443        """Returns True iff any element of compilers is a sub-string of the current compiler."""
1444        if (compilers is None):
1445            return True
1446
1447        for compiler in compilers:
1448            if compiler in self.getCompiler():
1449                return True
1450
1451        return False
1452
1453    def expectedArch(self, archs):
1454        """Returns True iff any element of archs is a sub-string of the current architecture."""
1455        if (archs is None):
1456            return True
1457
1458        for arch in archs:
1459            if arch in self.getArchitecture():
1460                return True
1461
1462        return False
1463
1464    def getRunOptions(self):
1465        """Command line option for -A and -C to run this test again, called from
1466        self.dumpSessionInfo()."""
1467        arch = self.getArchitecture()
1468        comp = self.getCompiler()
1469        option_str = ""
1470        if arch:
1471            option_str = "-A " + arch
1472        if comp:
1473            option_str += " -C " + comp
1474        return option_str
1475
1476    def getDebugInfo(self):
1477        method = getattr(self, self.testMethodName)
1478        return getattr(method, "debug_info", None)
1479
1480    # ==================================================
1481    # Build methods supported through a plugin interface
1482    # ==================================================
1483
1484    def getstdlibFlag(self):
1485        """ Returns the proper -stdlib flag, or empty if not required."""
1486        if self.platformIsDarwin() or self.getPlatform() == "freebsd" or self.getPlatform() == "openbsd":
1487            stdlibflag = "-stdlib=libc++"
1488        else:  # this includes NetBSD
1489            stdlibflag = ""
1490        return stdlibflag
1491
1492    def getstdFlag(self):
1493        """ Returns the proper stdflag. """
1494        if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
1495            stdflag = "-std=c++0x"
1496        else:
1497            stdflag = "-std=c++11"
1498        return stdflag
1499
1500    def buildDriver(self, sources, exe_name):
1501        """ Platform-specific way to build a program that links with LLDB (via the liblldb.so
1502            or LLDB.framework).
1503        """
1504        stdflag = self.getstdFlag()
1505        stdlibflag = self.getstdlibFlag()
1506
1507        lib_dir = configuration.lldb_libs_dir
1508        if self.hasDarwinFramework():
1509            d = {'CXX_SOURCES': sources,
1510                 'EXE': exe_name,
1511                 'CFLAGS_EXTRAS': "%s %s" % (stdflag, stdlibflag),
1512                 'FRAMEWORK_INCLUDES': "-F%s" % self.framework_dir,
1513                 'LD_EXTRAS': "%s -Wl,-rpath,%s" % (self.lib_lldb, self.framework_dir),
1514                 }
1515        elif sys.platform.startswith('win'):
1516            d = {
1517                'CXX_SOURCES': sources,
1518                'EXE': exe_name,
1519                'CFLAGS_EXTRAS': "%s %s -I%s" % (stdflag,
1520                                                 stdlibflag,
1521                                                 os.path.join(
1522                                                     os.environ["LLDB_SRC"],
1523                                                     "include")),
1524                'LD_EXTRAS': "-L%s -lliblldb" % lib_dir}
1525        else:
1526            d = {
1527                'CXX_SOURCES': sources,
1528                'EXE': exe_name,
1529                'CFLAGS_EXTRAS': "%s %s -I%s" % (stdflag,
1530                                                 stdlibflag,
1531                                                 os.path.join(
1532                                                     os.environ["LLDB_SRC"],
1533                                                     "include")),
1534                'LD_EXTRAS': "-L%s -llldb -Wl,-rpath,%s" % (lib_dir, lib_dir)}
1535        if self.TraceOn():
1536            print(
1537                "Building LLDB Driver (%s) from sources %s" %
1538                (exe_name, sources))
1539
1540        self.buildDefault(dictionary=d)
1541
1542    def buildLibrary(self, sources, lib_name):
1543        """Platform specific way to build a default library. """
1544
1545        stdflag = self.getstdFlag()
1546
1547        lib_dir = configuration.lldb_libs_dir
1548        if self.hasDarwinFramework():
1549            d = {'DYLIB_CXX_SOURCES': sources,
1550                 'DYLIB_NAME': lib_name,
1551                 'CFLAGS_EXTRAS': "%s -stdlib=libc++" % stdflag,
1552                 'FRAMEWORK_INCLUDES': "-F%s" % self.framework_dir,
1553                 'LD_EXTRAS': "%s -Wl,-rpath,%s -dynamiclib" % (self.lib_lldb, self.framework_dir),
1554                 }
1555        elif self.getPlatform() == 'windows':
1556            d = {
1557                'DYLIB_CXX_SOURCES': sources,
1558                'DYLIB_NAME': lib_name,
1559                'CFLAGS_EXTRAS': "%s -I%s " % (stdflag,
1560                                               os.path.join(
1561                                                   os.environ["LLDB_SRC"],
1562                                                   "include")),
1563                'LD_EXTRAS': "-shared -l%s\liblldb.lib" % lib_dir}
1564        else:
1565            d = {
1566                'DYLIB_CXX_SOURCES': sources,
1567                'DYLIB_NAME': lib_name,
1568                'CFLAGS_EXTRAS': "%s -I%s -fPIC" % (stdflag,
1569                                                    os.path.join(
1570                                                        os.environ["LLDB_SRC"],
1571                                                        "include")),
1572                'LD_EXTRAS': "-shared -L%s -llldb -Wl,-rpath,%s" % (lib_dir, lib_dir)}
1573        if self.TraceOn():
1574            print(
1575                "Building LLDB Library (%s) from sources %s" %
1576                (lib_name, sources))
1577
1578        self.buildDefault(dictionary=d)
1579
1580    def buildProgram(self, sources, exe_name):
1581        """ Platform specific way to build an executable from C/C++ sources. """
1582        d = {'CXX_SOURCES': sources,
1583             'EXE': exe_name}
1584        self.buildDefault(dictionary=d)
1585
1586    def buildDefault(
1587            self,
1588            architecture=None,
1589            compiler=None,
1590            dictionary=None):
1591        """Platform specific way to build the default binaries."""
1592        testdir = self.mydir
1593        testname = self.getBuildDirBasename()
1594
1595        if not architecture and configuration.arch:
1596            architecture = configuration.arch
1597
1598        if self.getDebugInfo():
1599            raise Exception("buildDefault tests must set NO_DEBUG_INFO_TESTCASE")
1600        module = builder_module()
1601        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1602        if not module.buildDefault(self, architecture, compiler,
1603                                   dictionary, testdir, testname):
1604            raise Exception("Don't know how to build default binary")
1605
1606    def buildDsym(
1607            self,
1608            architecture=None,
1609            compiler=None,
1610            dictionary=None):
1611        """Platform specific way to build binaries with dsym info."""
1612        testdir = self.mydir
1613        testname = self.getBuildDirBasename()
1614        if self.getDebugInfo() != "dsym":
1615            raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")
1616
1617        module = builder_module()
1618        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1619        if not module.buildDsym(self, architecture, compiler,
1620                                dictionary, testdir, testname):
1621            raise Exception("Don't know how to build binary with dsym")
1622
1623    def buildDwarf(
1624            self,
1625            architecture=None,
1626            compiler=None,
1627            dictionary=None):
1628        """Platform specific way to build binaries with dwarf maps."""
1629        testdir = self.mydir
1630        testname = self.getBuildDirBasename()
1631        if self.getDebugInfo() != "dwarf":
1632            raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")
1633
1634        module = builder_module()
1635        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1636        if not module.buildDwarf(self, architecture, compiler,
1637                                   dictionary, testdir, testname):
1638            raise Exception("Don't know how to build binary with dwarf")
1639
1640    def buildDwo(
1641            self,
1642            architecture=None,
1643            compiler=None,
1644            dictionary=None):
1645        """Platform specific way to build binaries with dwarf maps."""
1646        testdir = self.mydir
1647        testname = self.getBuildDirBasename()
1648        if self.getDebugInfo() != "dwo":
1649            raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")
1650
1651        module = builder_module()
1652        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1653        if not module.buildDwo(self, architecture, compiler,
1654                                   dictionary, testdir, testname):
1655            raise Exception("Don't know how to build binary with dwo")
1656
1657    def buildGModules(
1658            self,
1659            architecture=None,
1660            compiler=None,
1661            dictionary=None):
1662        """Platform specific way to build binaries with gmodules info."""
1663        testdir = self.mydir
1664        testname = self.getBuildDirBasename()
1665        if self.getDebugInfo() != "gmodules":
1666            raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")
1667
1668        module = builder_module()
1669        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1670        if not module.buildGModules(self, architecture, compiler,
1671                                    dictionary, testdir, testname):
1672            raise Exception("Don't know how to build binary with gmodules")
1673
1674    def signBinary(self, binary_path):
1675        if sys.platform.startswith("darwin"):
1676            codesign_cmd = "codesign --force --sign \"%s\" %s" % (
1677                lldbtest_config.codesign_identity, binary_path)
1678            call(codesign_cmd, shell=True)
1679
1680    def findBuiltClang(self):
1681        """Tries to find and use Clang from the build directory as the compiler (instead of the system compiler)."""
1682        paths_to_try = [
1683            "llvm-build/Release+Asserts/x86_64/bin/clang",
1684            "llvm-build/Debug+Asserts/x86_64/bin/clang",
1685            "llvm-build/Release/x86_64/bin/clang",
1686            "llvm-build/Debug/x86_64/bin/clang",
1687        ]
1688        lldb_root_path = os.path.join(
1689            os.path.dirname(__file__), "..", "..", "..", "..")
1690        for p in paths_to_try:
1691            path = os.path.join(lldb_root_path, p)
1692            if os.path.exists(path):
1693                return path
1694
1695        # Tries to find clang at the same folder as the lldb
1696        lldb_dir = os.path.dirname(lldbtest_config.lldbExec)
1697        path = distutils.spawn.find_executable("clang", lldb_dir)
1698        if path is not None:
1699            return path
1700
1701        return os.environ["CC"]
1702
1703
1704    def yaml2obj(self, yaml_path, obj_path):
1705        """
1706        Create an object file at the given path from a yaml file.
1707
1708        Throws subprocess.CalledProcessError if the object could not be created.
1709        """
1710        yaml2obj_bin = configuration.get_yaml2obj_path()
1711        if not yaml2obj_bin:
1712            self.assertTrue(False, "No valid yaml2obj executable specified")
1713        command = [yaml2obj_bin, "-o=%s" % obj_path, yaml_path]
1714        system([command])
1715
1716    def getBuildFlags(
1717            self,
1718            use_cpp11=True,
1719            use_libcxx=False,
1720            use_libstdcxx=False):
1721        """ Returns a dictionary (which can be provided to build* functions above) which
1722            contains OS-specific build flags.
1723        """
1724        cflags = ""
1725        ldflags = ""
1726
1727        # On Mac OS X, unless specifically requested to use libstdc++, use
1728        # libc++
1729        if not use_libstdcxx and self.platformIsDarwin():
1730            use_libcxx = True
1731
1732        if use_libcxx and self.libcxxPath:
1733            cflags += "-stdlib=libc++ "
1734            if self.libcxxPath:
1735                libcxxInclude = os.path.join(self.libcxxPath, "include")
1736                libcxxLib = os.path.join(self.libcxxPath, "lib")
1737                if os.path.isdir(libcxxInclude) and os.path.isdir(libcxxLib):
1738                    cflags += "-nostdinc++ -I%s -L%s -Wl,-rpath,%s " % (
1739                        libcxxInclude, libcxxLib, libcxxLib)
1740
1741        if use_cpp11:
1742            cflags += "-std="
1743            if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
1744                cflags += "c++0x"
1745            else:
1746                cflags += "c++11"
1747        if self.platformIsDarwin() or self.getPlatform() == "freebsd":
1748            cflags += " -stdlib=libc++"
1749        elif self.getPlatform() == "openbsd":
1750            cflags += " -stdlib=libc++"
1751        elif self.getPlatform() == "netbsd":
1752            # NetBSD defaults to libc++
1753            pass
1754        elif "clang" in self.getCompiler():
1755            cflags += " -stdlib=libstdc++"
1756
1757        return {'CFLAGS_EXTRAS': cflags,
1758                'LD_EXTRAS': ldflags,
1759                }
1760
1761    def cleanup(self, dictionary=None):
1762        """Platform specific way to do cleanup after build."""
1763        module = builder_module()
1764        if not module.cleanup(self, dictionary):
1765            raise Exception(
1766                "Don't know how to do cleanup with dictionary: " +
1767                dictionary)
1768
1769    def invoke(self, obj, name, trace=False):
1770        """Use reflection to call a method dynamically with no argument."""
1771        trace = (True if traceAlways else trace)
1772
1773        method = getattr(obj, name)
1774        import inspect
1775        self.assertTrue(inspect.ismethod(method),
1776                        name + "is a method name of object: " + str(obj))
1777        result = method()
1778        with recording(self, trace) as sbuf:
1779            print(str(method) + ":", result, file=sbuf)
1780        return result
1781
1782    def getLLDBLibraryEnvVal(self):
1783        """ Returns the path that the OS-specific library search environment variable
1784            (self.dylibPath) should be set to in order for a program to find the LLDB
1785            library. If an environment variable named self.dylibPath is already set,
1786            the new path is appended to it and returned.
1787        """
1788        existing_library_path = os.environ[
1789            self.dylibPath] if self.dylibPath in os.environ else None
1790        if existing_library_path:
1791            return "%s:%s" % (existing_library_path, configuration.lldb_libs_dir)
1792        if sys.platform.startswith("darwin") and configuration.lldb_framework_path:
1793            return configuration.lldb_framework_path
1794        return configuration.lldb_libs_dir
1795
1796    def getLibcPlusPlusLibs(self):
1797        if self.getPlatform() in ('freebsd', 'linux', 'netbsd', 'openbsd'):
1798            return ['libc++.so.1']
1799        else:
1800            return ['libc++.1.dylib', 'libc++abi.']
1801
1802    def run_platform_command(self, cmd):
1803        platform = self.dbg.GetSelectedPlatform()
1804        shell_command = lldb.SBPlatformShellCommand(cmd)
1805        err = platform.Run(shell_command)
1806        return (err, shell_command.GetStatus(), shell_command.GetOutput())
1807
1808# Metaclass for TestBase to change the list of test metods when a new TestCase is loaded.
1809# We change the test methods to create a new test method for each test for each debug info we are
1810# testing. The name of the new test method will be '<original-name>_<debug-info>' and with adding
1811# the new test method we remove the old method at the same time. This functionality can be
1812# supressed by at test case level setting the class attribute NO_DEBUG_INFO_TESTCASE or at test
1813# level by using the decorator @no_debug_info_test.
1814
1815
1816class LLDBTestCaseFactory(type):
1817
1818    def __new__(cls, name, bases, attrs):
1819        original_testcase = super(
1820            LLDBTestCaseFactory, cls).__new__(
1821            cls, name, bases, attrs)
1822        if original_testcase.NO_DEBUG_INFO_TESTCASE:
1823            return original_testcase
1824
1825        newattrs = {}
1826        for attrname, attrvalue in attrs.items():
1827            if attrname.startswith("test") and not getattr(
1828                    attrvalue, "__no_debug_info_test__", False):
1829
1830                # If any debug info categories were explicitly tagged, assume that list to be
1831                # authoritative.  If none were specified, try with all debug
1832                # info formats.
1833                all_dbginfo_categories = set(test_categories.debug_info_categories)
1834                categories = set(
1835                    getattr(
1836                        attrvalue,
1837                        "categories",
1838                        [])) & all_dbginfo_categories
1839                if not categories:
1840                    categories = all_dbginfo_categories
1841
1842                for cat in categories:
1843                    @decorators.add_test_categories([cat])
1844                    @wraps(attrvalue)
1845                    def test_method(self, attrvalue=attrvalue):
1846                        return attrvalue(self)
1847
1848                    method_name = attrname + "_" + cat
1849                    test_method.__name__ = method_name
1850                    test_method.debug_info = cat
1851                    newattrs[method_name] = test_method
1852
1853            else:
1854                newattrs[attrname] = attrvalue
1855        return super(
1856            LLDBTestCaseFactory,
1857            cls).__new__(
1858            cls,
1859            name,
1860            bases,
1861            newattrs)
1862
1863# Setup the metaclass for this class to change the list of the test
1864# methods when a new class is loaded
1865
1866
1867@add_metaclass(LLDBTestCaseFactory)
1868class TestBase(Base):
1869    """
1870    This abstract base class is meant to be subclassed.  It provides default
1871    implementations for setUpClass(), tearDownClass(), setUp(), and tearDown(),
1872    among other things.
1873
1874    Important things for test class writers:
1875
1876        - Overwrite the mydir class attribute, otherwise your test class won't
1877          run.  It specifies the relative directory to the top level 'test' so
1878          the test harness can change to the correct working directory before
1879          running your test.
1880
1881        - The setUp method sets up things to facilitate subsequent interactions
1882          with the debugger as part of the test.  These include:
1883              - populate the test method name
1884              - create/get a debugger set with synchronous mode (self.dbg)
1885              - get the command interpreter from with the debugger (self.ci)
1886              - create a result object for use with the command interpreter
1887                (self.res)
1888              - plus other stuffs
1889
1890        - The tearDown method tries to perform some necessary cleanup on behalf
1891          of the test to return the debugger to a good state for the next test.
1892          These include:
1893              - execute any tearDown hooks registered by the test method with
1894                TestBase.addTearDownHook(); examples can be found in
1895                settings/TestSettings.py
1896              - kill the inferior process associated with each target, if any,
1897                and, then delete the target from the debugger's target list
1898              - perform build cleanup before running the next test method in the
1899                same test class; examples of registering for this service can be
1900                found in types/TestIntegerTypes.py with the call:
1901                    - self.setTearDownCleanup(dictionary=d)
1902
1903        - Similarly setUpClass and tearDownClass perform classwise setup and
1904          teardown fixtures.  The tearDownClass method invokes a default build
1905          cleanup for the entire test class;  also, subclasses can implement the
1906          classmethod classCleanup(cls) to perform special class cleanup action.
1907
1908        - The instance methods runCmd and expect are used heavily by existing
1909          test cases to send a command to the command interpreter and to perform
1910          string/pattern matching on the output of such command execution.  The
1911          expect method also provides a mode to peform string/pattern matching
1912          without running a command.
1913
1914        - The build methods buildDefault, buildDsym, and buildDwarf are used to
1915          build the binaries used during a particular test scenario.  A plugin
1916          should be provided for the sys.platform running the test suite.  The
1917          Mac OS X implementation is located in builders/darwin.py.
1918    """
1919
1920    # Subclasses can set this to true (if they don't depend on debug info) to avoid running the
1921    # test multiple times with various debug info types.
1922    NO_DEBUG_INFO_TESTCASE = False
1923
1924    # Maximum allowed attempts when launching the inferior process.
1925    # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
1926    maxLaunchCount = 1
1927
1928    # Time to wait before the next launching attempt in second(s).
1929    # Can be overridden by the LLDB_TIME_WAIT_NEXT_LAUNCH environment variable.
1930    timeWaitNextLaunch = 1.0
1931
1932    def generateSource(self, source):
1933        template = source + '.template'
1934        temp = os.path.join(self.getSourceDir(), template)
1935        with open(temp, 'r') as f:
1936            content = f.read()
1937
1938        public_api_dir = os.path.join(
1939            os.environ["LLDB_SRC"], "include", "lldb", "API")
1940
1941        # Look under the include/lldb/API directory and add #include statements
1942        # for all the SB API headers.
1943        public_headers = os.listdir(public_api_dir)
1944        # For different platforms, the include statement can vary.
1945        if self.hasDarwinFramework():
1946            include_stmt = "'#include <%s>' % os.path.join('LLDB', header)"
1947        else:
1948            include_stmt = "'#include <%s>' % os.path.join('" + public_api_dir + "', header)"
1949        list = [eval(include_stmt) for header in public_headers if (
1950            header.startswith("SB") and header.endswith(".h"))]
1951        includes = '\n'.join(list)
1952        new_content = content.replace('%include_SB_APIs%', includes)
1953        new_content = new_content.replace('%SOURCE_DIR%', self.getSourceDir())
1954        src = os.path.join(self.getBuildDir(), source)
1955        with open(src, 'w') as f:
1956            f.write(new_content)
1957
1958        self.addTearDownHook(lambda: os.remove(src))
1959
1960    def setUp(self):
1961        # Works with the test driver to conditionally skip tests via
1962        # decorators.
1963        Base.setUp(self)
1964
1965        for s in self.setUpCommands():
1966            self.runCmd(s)
1967
1968        if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
1969            self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])
1970
1971        if "LLDB_TIME_WAIT_NEXT_LAUNCH" in os.environ:
1972            self.timeWaitNextLaunch = float(
1973                os.environ["LLDB_TIME_WAIT_NEXT_LAUNCH"])
1974
1975        # We want our debugger to be synchronous.
1976        self.dbg.SetAsync(False)
1977
1978        # Retrieve the associated command interpreter instance.
1979        self.ci = self.dbg.GetCommandInterpreter()
1980        if not self.ci:
1981            raise Exception('Could not get the command interpreter')
1982
1983        # And the result object.
1984        self.res = lldb.SBCommandReturnObject()
1985
1986    def registerSharedLibrariesWithTarget(self, target, shlibs):
1987        '''If we are remotely running the test suite, register the shared libraries with the target so they get uploaded, otherwise do nothing
1988
1989        Any modules in the target that have their remote install file specification set will
1990        get uploaded to the remote host. This function registers the local copies of the
1991        shared libraries with the target and sets their remote install locations so they will
1992        be uploaded when the target is run.
1993        '''
1994        if not shlibs or not self.platformContext:
1995            return None
1996
1997        shlib_environment_var = self.platformContext.shlib_environment_var
1998        shlib_prefix = self.platformContext.shlib_prefix
1999        shlib_extension = '.' + self.platformContext.shlib_extension
2000
2001        dirs = []
2002        # Add any shared libraries to our target if remote so they get
2003        # uploaded into the working directory on the remote side
2004        for name in shlibs:
2005            # The path can be a full path to a shared library, or a make file name like "Foo" for
2006            # "libFoo.dylib" or "libFoo.so", or "Foo.so" for "Foo.so" or "libFoo.so", or just a
2007            # basename like "libFoo.so". So figure out which one it is and resolve the local copy
2008            # of the shared library accordingly
2009            if os.path.isfile(name):
2010                local_shlib_path = name  # name is the full path to the local shared library
2011            else:
2012                # Check relative names
2013                local_shlib_path = os.path.join(
2014                    self.getBuildDir(), shlib_prefix + name + shlib_extension)
2015                if not os.path.exists(local_shlib_path):
2016                    local_shlib_path = os.path.join(
2017                        self.getBuildDir(), name + shlib_extension)
2018                    if not os.path.exists(local_shlib_path):
2019                        local_shlib_path = os.path.join(self.getBuildDir(), name)
2020
2021                # Make sure we found the local shared library in the above code
2022                self.assertTrue(os.path.exists(local_shlib_path))
2023
2024
2025            # Add the shared library to our target
2026            shlib_module = target.AddModule(local_shlib_path, None, None, None)
2027            if lldb.remote_platform:
2028                # We must set the remote install location if we want the shared library
2029                # to get uploaded to the remote target
2030                remote_shlib_path = lldbutil.append_to_process_working_directory(self,
2031                    os.path.basename(local_shlib_path))
2032                shlib_module.SetRemoteInstallFileSpec(
2033                    lldb.SBFileSpec(remote_shlib_path, False))
2034                dir_to_add = self.get_process_working_directory()
2035            else:
2036                dir_to_add = os.path.dirname(local_shlib_path)
2037
2038            if dir_to_add not in dirs:
2039                dirs.append(dir_to_add)
2040
2041        env_value = self.platformContext.shlib_path_separator.join(dirs)
2042        return ['%s=%s' % (shlib_environment_var, env_value)]
2043
2044    def registerSanitizerLibrariesWithTarget(self, target):
2045        runtimes = []
2046        for m in target.module_iter():
2047            libspec = m.GetFileSpec()
2048            if "clang_rt" in libspec.GetFilename():
2049                runtimes.append(os.path.join(libspec.GetDirectory(),
2050                                             libspec.GetFilename()))
2051        return self.registerSharedLibrariesWithTarget(target, runtimes)
2052
2053    # utility methods that tests can use to access the current objects
2054    def target(self):
2055        if not self.dbg:
2056            raise Exception('Invalid debugger instance')
2057        return self.dbg.GetSelectedTarget()
2058
2059    def process(self):
2060        if not self.dbg:
2061            raise Exception('Invalid debugger instance')
2062        return self.dbg.GetSelectedTarget().GetProcess()
2063
2064    def thread(self):
2065        if not self.dbg:
2066            raise Exception('Invalid debugger instance')
2067        return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread()
2068
2069    def frame(self):
2070        if not self.dbg:
2071            raise Exception('Invalid debugger instance')
2072        return self.dbg.GetSelectedTarget().GetProcess(
2073        ).GetSelectedThread().GetSelectedFrame()
2074
2075    def get_process_working_directory(self):
2076        '''Get the working directory that should be used when launching processes for local or remote processes.'''
2077        if lldb.remote_platform:
2078            # Remote tests set the platform working directory up in
2079            # TestBase.setUp()
2080            return lldb.remote_platform.GetWorkingDirectory()
2081        else:
2082            # local tests change directory into each test subdirectory
2083            return self.getBuildDir()
2084
2085    def tearDown(self):
2086        # Ensure all the references to SB objects have gone away so that we can
2087        # be sure that all test-specific resources have been freed before we
2088        # attempt to delete the targets.
2089        gc.collect()
2090
2091        # Delete the target(s) from the debugger as a general cleanup step.
2092        # This includes terminating the process for each target, if any.
2093        # We'd like to reuse the debugger for our next test without incurring
2094        # the initialization overhead.
2095        targets = []
2096        for target in self.dbg:
2097            if target:
2098                targets.append(target)
2099                process = target.GetProcess()
2100                if process:
2101                    rc = self.invoke(process, "Kill")
2102                    assert rc.Success()
2103        for target in targets:
2104            self.dbg.DeleteTarget(target)
2105
2106        if not configuration.is_reproducer():
2107            # Assert that all targets are deleted.
2108            self.assertEqual(self.dbg.GetNumTargets(), 0)
2109
2110        # Do this last, to make sure it's in reverse order from how we setup.
2111        Base.tearDown(self)
2112
2113    def switch_to_thread_with_stop_reason(self, stop_reason):
2114        """
2115        Run the 'thread list' command, and select the thread with stop reason as
2116        'stop_reason'.  If no such thread exists, no select action is done.
2117        """
2118        from .lldbutil import stop_reason_to_str
2119        self.runCmd('thread list')
2120        output = self.res.GetOutput()
2121        thread_line_pattern = re.compile(
2122            "^[ *] thread #([0-9]+):.*stop reason = %s" %
2123            stop_reason_to_str(stop_reason))
2124        for line in output.splitlines():
2125            matched = thread_line_pattern.match(line)
2126            if matched:
2127                self.runCmd('thread select %s' % matched.group(1))
2128
2129    def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False):
2130        """
2131        Ask the command interpreter to handle the command and then check its
2132        return status.
2133        """
2134        # Fail fast if 'cmd' is not meaningful.
2135        if cmd is None:
2136            raise Exception("Bad 'cmd' parameter encountered")
2137
2138        trace = (True if traceAlways else trace)
2139
2140        if cmd.startswith("target create "):
2141            cmd = cmd.replace("target create ", "file ")
2142
2143        running = (cmd.startswith("run") or cmd.startswith("process launch"))
2144
2145        for i in range(self.maxLaunchCount if running else 1):
2146            self.ci.HandleCommand(cmd, self.res, inHistory)
2147
2148            with recording(self, trace) as sbuf:
2149                print("runCmd:", cmd, file=sbuf)
2150                if not check:
2151                    print("check of return status not required", file=sbuf)
2152                if self.res.Succeeded():
2153                    print("output:", self.res.GetOutput(), file=sbuf)
2154                else:
2155                    print("runCmd failed!", file=sbuf)
2156                    print(self.res.GetError(), file=sbuf)
2157
2158            if self.res.Succeeded():
2159                break
2160            elif running:
2161                # For process launch, wait some time before possible next try.
2162                time.sleep(self.timeWaitNextLaunch)
2163                with recording(self, trace) as sbuf:
2164                    print("Command '" + cmd + "' failed!", file=sbuf)
2165
2166        if check:
2167            output = ""
2168            if self.res.GetOutput():
2169                output += "\nCommand output:\n" + self.res.GetOutput()
2170            if self.res.GetError():
2171                output += "\nError output:\n" + self.res.GetError()
2172            if msg:
2173                msg += output
2174            if cmd:
2175                cmd += output
2176            self.assertTrue(self.res.Succeeded(),
2177                            msg if (msg) else CMD_MSG(cmd))
2178
2179    def match(
2180            self,
2181            str,
2182            patterns,
2183            msg=None,
2184            trace=False,
2185            error=False,
2186            matching=True,
2187            exe=True):
2188        """run command in str, and match the result against regexp in patterns returning the match object for the first matching pattern
2189
2190        Otherwise, all the arguments have the same meanings as for the expect function"""
2191
2192        trace = (True if traceAlways else trace)
2193
2194        if exe:
2195            # First run the command.  If we are expecting error, set check=False.
2196            # Pass the assert message along since it provides more semantic
2197            # info.
2198            self.runCmd(
2199                str,
2200                msg=msg,
2201                trace=(
2202                    True if trace else False),
2203                check=not error)
2204
2205            # Then compare the output against expected strings.
2206            output = self.res.GetError() if error else self.res.GetOutput()
2207
2208            # If error is True, the API client expects the command to fail!
2209            if error:
2210                self.assertFalse(self.res.Succeeded(),
2211                                 "Command '" + str + "' is expected to fail!")
2212        else:
2213            # No execution required, just compare str against the golden input.
2214            output = str
2215            with recording(self, trace) as sbuf:
2216                print("looking at:", output, file=sbuf)
2217
2218        # The heading says either "Expecting" or "Not expecting".
2219        heading = "Expecting" if matching else "Not expecting"
2220
2221        for pattern in patterns:
2222            # Match Objects always have a boolean value of True.
2223            match_object = re.search(pattern, output)
2224            matched = bool(match_object)
2225            with recording(self, trace) as sbuf:
2226                print("%s pattern: %s" % (heading, pattern), file=sbuf)
2227                print("Matched" if matched else "Not matched", file=sbuf)
2228            if matched:
2229                break
2230
2231        self.assertTrue(matched if matching else not matched,
2232                        msg if msg else EXP_MSG(str, output, exe))
2233
2234        return match_object
2235
2236    def check_completion_with_desc(self, str_input, match_desc_pairs, enforce_order=False):
2237        """
2238        Checks that when the given input is completed at the given list of
2239        completions and descriptions is returned.
2240        :param str_input: The input that should be completed. The completion happens at the end of the string.
2241        :param match_desc_pairs: A list of pairs that indicate what completions have to be in the list of
2242                                 completions returned by LLDB. The first element of the pair is the completion
2243                                 string that LLDB should generate and the second element the description.
2244        :param enforce_order: True iff the order in which the completions are returned by LLDB
2245                              should match the order of the match_desc_pairs pairs.
2246        """
2247        interp = self.dbg.GetCommandInterpreter()
2248        match_strings = lldb.SBStringList()
2249        description_strings = lldb.SBStringList()
2250        num_matches = interp.HandleCompletionWithDescriptions(str_input, len(str_input), 0, -1, match_strings, description_strings)
2251        self.assertEqual(len(description_strings), len(match_strings))
2252
2253        # The index of the last matched description in description_strings or
2254        # -1 if no description has been matched yet.
2255        last_found_index = -1
2256        out_of_order_errors = ""
2257        missing_pairs = []
2258        for pair in match_desc_pairs:
2259            found_pair = False
2260            for i in range(num_matches + 1):
2261                match_candidate = match_strings.GetStringAtIndex(i)
2262                description_candidate = description_strings.GetStringAtIndex(i)
2263                if match_candidate == pair[0] and description_candidate == pair[1]:
2264                    found_pair = True
2265                    if enforce_order and last_found_index > i:
2266                        new_err = ("Found completion " + pair[0] + " at index " +
2267                                  str(i) + " in returned completion list but " +
2268                                  "should have been after completion " +
2269                                  match_strings.GetStringAtIndex(last_found_index) +
2270                                  " (index:" + str(last_found_index) + ")\n")
2271                        out_of_order_errors += new_err
2272                    last_found_index = i
2273                    break
2274            if not found_pair:
2275                missing_pairs.append(pair)
2276
2277        error_msg = ""
2278        got_failure = False
2279        if len(missing_pairs):
2280            got_failure = True
2281            error_msg += "Missing pairs:\n"
2282            for pair in missing_pairs:
2283                error_msg += " [" + pair[0] + ":" + pair[1] + "]\n"
2284        if len(out_of_order_errors):
2285            got_failure = True
2286            error_msg += out_of_order_errors
2287        if got_failure:
2288            error_msg += "Got the following " + str(num_matches) + " completions back:\n"
2289            for i in range(num_matches + 1):
2290                match_candidate = match_strings.GetStringAtIndex(i)
2291                description_candidate = description_strings.GetStringAtIndex(i)
2292                error_msg += "[" + match_candidate + ":" + description_candidate + "] index " + str(i) + "\n"
2293            self.assertFalse(got_failure, error_msg)
2294
2295    def complete_exactly(self, str_input, patterns):
2296        self.complete_from_to(str_input, patterns, True)
2297
2298    def complete_from_to(self, str_input, patterns, turn_off_re_match=False):
2299        """Test that the completion mechanism completes str_input to patterns,
2300        where patterns could be a pattern-string or a list of pattern-strings"""
2301        # Patterns should not be None in order to proceed.
2302        self.assertFalse(patterns is None)
2303        # And should be either a string or list of strings.  Check for list type
2304        # below, if not, make a list out of the singleton string.  If patterns
2305        # is not a string or not a list of strings, there'll be runtime errors
2306        # later on.
2307        if not isinstance(patterns, list):
2308            patterns = [patterns]
2309
2310        interp = self.dbg.GetCommandInterpreter()
2311        match_strings = lldb.SBStringList()
2312        num_matches = interp.HandleCompletion(str_input, len(str_input), 0, -1, match_strings)
2313        common_match = match_strings.GetStringAtIndex(0)
2314        if num_matches == 0:
2315            compare_string = str_input
2316        else:
2317            if common_match != None and len(common_match) > 0:
2318                compare_string = str_input + common_match
2319            else:
2320                compare_string = ""
2321                for idx in range(1, num_matches+1):
2322                    compare_string += match_strings.GetStringAtIndex(idx) + "\n"
2323
2324        for p in patterns:
2325            if turn_off_re_match:
2326                self.expect(
2327                    compare_string, msg=COMPLETION_MSG(
2328                        str_input, p, match_strings), exe=False, substrs=[p])
2329            else:
2330                self.expect(
2331                    compare_string, msg=COMPLETION_MSG(
2332                        str_input, p, match_strings), exe=False, patterns=[p])
2333
2334    def completions_match(self, command, completions):
2335        """Checks that the completions for the given command are equal to the
2336        given list of completions"""
2337        interp = self.dbg.GetCommandInterpreter()
2338        match_strings = lldb.SBStringList()
2339        interp.HandleCompletion(command, len(command), 0, -1, match_strings)
2340        # match_strings is a 1-indexed list, so we have to slice...
2341        self.assertItemsEqual(completions, list(match_strings)[1:],
2342                              "List of returned completion is wrong")
2343
2344    def completions_contain(self, command, completions):
2345        """Checks that the completions for the given command contain the given
2346        list of completions."""
2347        interp = self.dbg.GetCommandInterpreter()
2348        match_strings = lldb.SBStringList()
2349        interp.HandleCompletion(command, len(command), 0, -1, match_strings)
2350        for completion in completions:
2351            # match_strings is a 1-indexed list, so we have to slice...
2352            self.assertIn(completion, list(match_strings)[1:],
2353                          "Couldn't find expected completion")
2354
2355    def filecheck(
2356            self,
2357            command,
2358            check_file,
2359            filecheck_options = '',
2360            expect_cmd_failure = False):
2361        # Run the command.
2362        self.runCmd(
2363                command,
2364                check=(not expect_cmd_failure),
2365                msg="FileCheck'ing result of `{0}`".format(command))
2366
2367        self.assertTrue((not expect_cmd_failure) == self.res.Succeeded())
2368
2369        # Get the error text if there was an error, and the regular text if not.
2370        output = self.res.GetOutput() if self.res.Succeeded() \
2371                else self.res.GetError()
2372
2373        # Assemble the absolute path to the check file. As a convenience for
2374        # LLDB inline tests, assume that the check file is a relative path to
2375        # a file within the inline test directory.
2376        if check_file.endswith('.pyc'):
2377            check_file = check_file[:-1]
2378        check_file_abs = os.path.abspath(check_file)
2379
2380        # Run FileCheck.
2381        filecheck_bin = configuration.get_filecheck_path()
2382        if not filecheck_bin:
2383            self.assertTrue(False, "No valid FileCheck executable specified")
2384        filecheck_args = [filecheck_bin, check_file_abs]
2385        if filecheck_options:
2386            filecheck_args.append(filecheck_options)
2387        subproc = Popen(filecheck_args, stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines = True)
2388        cmd_stdout, cmd_stderr = subproc.communicate(input=output)
2389        cmd_status = subproc.returncode
2390
2391        filecheck_cmd = " ".join(filecheck_args)
2392        filecheck_trace = """
2393--- FileCheck trace (code={0}) ---
2394{1}
2395
2396FileCheck input:
2397{2}
2398
2399FileCheck output:
2400{3}
2401{4}
2402""".format(cmd_status, filecheck_cmd, output, cmd_stdout, cmd_stderr)
2403
2404        trace = cmd_status != 0 or traceAlways
2405        with recording(self, trace) as sbuf:
2406            print(filecheck_trace, file=sbuf)
2407
2408        self.assertTrue(cmd_status == 0)
2409
2410    def expect(
2411            self,
2412            str,
2413            msg=None,
2414            patterns=None,
2415            startstr=None,
2416            endstr=None,
2417            substrs=None,
2418            trace=False,
2419            error=False,
2420            ordered=True,
2421            matching=True,
2422            exe=True,
2423            inHistory=False):
2424        """
2425        Similar to runCmd; with additional expect style output matching ability.
2426
2427        Ask the command interpreter to handle the command and then check its
2428        return status.  The 'msg' parameter specifies an informational assert
2429        message.  We expect the output from running the command to start with
2430        'startstr', matches the substrings contained in 'substrs', and regexp
2431        matches the patterns contained in 'patterns'.
2432
2433        When matching is true and ordered is true, which are both the default,
2434        the strings in the substrs array have to appear in the command output
2435        in the order in which they appear in the array.
2436
2437        If the keyword argument error is set to True, it signifies that the API
2438        client is expecting the command to fail.  In this case, the error stream
2439        from running the command is retrieved and compared against the golden
2440        input, instead.
2441
2442        If the keyword argument matching is set to False, it signifies that the API
2443        client is expecting the output of the command not to match the golden
2444        input.
2445
2446        Finally, the required argument 'str' represents the lldb command to be
2447        sent to the command interpreter.  In case the keyword argument 'exe' is
2448        set to False, the 'str' is treated as a string to be matched/not-matched
2449        against the golden input.
2450        """
2451        # Catch cases where `expect` has been miscalled. Specifically, prevent
2452        # this easy to make mistake:
2453        #     self.expect("lldb command", "some substr")
2454        # The `msg` parameter is used only when a failed match occurs. A failed
2455        # match can only occur when one of `patterns`, `startstr`, `endstr`, or
2456        # `substrs` has been given. Thus, if a `msg` is given, it's an error to
2457        # not also provide one of the matcher parameters.
2458        if msg and not (patterns or startstr or endstr or substrs or error):
2459            assert False, "expect() missing a matcher argument"
2460
2461        # Check `patterns` and `substrs` are not accidentally given as strings.
2462        assert not isinstance(patterns, six.string_types), \
2463            "patterns must be a collection of strings"
2464        assert not isinstance(substrs, six.string_types), \
2465            "substrs must be a collection of strings"
2466
2467        trace = (True if traceAlways else trace)
2468
2469        if exe:
2470            # First run the command.  If we are expecting error, set check=False.
2471            # Pass the assert message along since it provides more semantic
2472            # info.
2473            self.runCmd(
2474                str,
2475                msg=msg,
2476                trace=(
2477                    True if trace else False),
2478                check=not error,
2479                inHistory=inHistory)
2480
2481            # Then compare the output against expected strings.
2482            output = self.res.GetError() if error else self.res.GetOutput()
2483
2484            # If error is True, the API client expects the command to fail!
2485            if error:
2486                self.assertFalse(self.res.Succeeded(),
2487                                 "Command '" + str + "' is expected to fail!")
2488        else:
2489            # No execution required, just compare str against the golden input.
2490            if isinstance(str, lldb.SBCommandReturnObject):
2491                output = str.GetOutput()
2492            else:
2493                output = str
2494            with recording(self, trace) as sbuf:
2495                print("looking at:", output, file=sbuf)
2496
2497        expecting_str = "Expecting" if matching else "Not expecting"
2498        def found_str(matched):
2499            return "was found" if matched else "was not found"
2500
2501        # To be used as assert fail message and/or trace content
2502        log_lines = [
2503                "{}:".format("Ran command" if exe else "Checking string"),
2504                "\"{}\"".format(str),
2505                # Space out command and output
2506                "",
2507        ]
2508        if exe:
2509            # Newline before output to make large strings more readable
2510            log_lines.append("Got output:\n{}".format(output))
2511
2512        # Assume that we start matched if we want a match
2513        # Meaning if you have no conditions, matching or
2514        # not matching will always pass
2515        matched = matching
2516
2517        # We will stop checking on first failure
2518        if startstr:
2519            matched = output.startswith(startstr)
2520            log_lines.append("{} start string: \"{}\" ({})".format(
2521                    expecting_str, startstr, found_str(matched)))
2522
2523        if endstr and matched == matching:
2524            matched = output.endswith(endstr)
2525            log_lines.append("{} end string: \"{}\" ({})".format(
2526                    expecting_str, endstr, found_str(matched)))
2527
2528        if substrs and matched == matching:
2529            start = 0
2530            for substr in substrs:
2531                index = output[start:].find(substr)
2532                start = start + index if ordered and matching else 0
2533                matched = index != -1
2534                log_lines.append("{} sub string: \"{}\" ({})".format(
2535                        expecting_str, substr, found_str(matched)))
2536
2537                if matched != matching:
2538                    break
2539
2540        if patterns and matched == matching:
2541            for pattern in patterns:
2542                matched = re.search(pattern, output)
2543
2544                pattern_line = "{} regex pattern: \"{}\" ({}".format(
2545                        expecting_str, pattern, found_str(matched))
2546                if matched:
2547                    pattern_line += ", matched \"{}\"".format(
2548                            matched.group(0))
2549                pattern_line += ")"
2550                log_lines.append(pattern_line)
2551
2552                # Convert to bool because match objects
2553                # are True-ish but != True itself
2554                matched = bool(matched)
2555                if matched != matching:
2556                    break
2557
2558        # If a check failed, add any extra assert message
2559        if msg is not None and matched != matching:
2560            log_lines.append(msg)
2561
2562        log_msg = "\n".join(log_lines)
2563        with recording(self, trace) as sbuf:
2564            print(log_msg, file=sbuf)
2565        if matched != matching:
2566            self.fail(log_msg)
2567
2568    def expect_expr(
2569            self,
2570            expr,
2571            result_summary=None,
2572            result_value=None,
2573            result_type=None,
2574            result_children=None
2575            ):
2576        """
2577        Evaluates the given expression and verifies the result.
2578        :param expr: The expression as a string.
2579        :param result_summary: The summary that the expression should have. None if the summary should not be checked.
2580        :param result_value: The value that the expression should have. None if the value should not be checked.
2581        :param result_type: The type that the expression result should have. None if the type should not be checked.
2582        :param result_children: The expected children of the expression result
2583                                as a list of ValueChecks. None if the children shouldn't be checked.
2584        """
2585        self.assertTrue(expr.strip() == expr, "Expression contains trailing/leading whitespace: '" + expr + "'")
2586
2587        frame = self.frame()
2588        options = lldb.SBExpressionOptions()
2589
2590        # Disable fix-its that tests don't pass by accident.
2591        options.SetAutoApplyFixIts(False)
2592
2593        # Set the usual default options for normal expressions.
2594        options.SetIgnoreBreakpoints(True)
2595
2596        if self.frame().IsValid():
2597            options.SetLanguage(frame.GuessLanguage())
2598            eval_result = self.frame().EvaluateExpression(expr, options)
2599        else:
2600            target = self.target()
2601            # If there is no selected target, run the expression in the dummy
2602            # target.
2603            if not target.IsValid():
2604                target = self.dbg.GetDummyTarget()
2605            eval_result = target.EvaluateExpression(expr, options)
2606
2607        value_check = ValueCheck(type=result_type, value=result_value,
2608                                 summary=result_summary, children=result_children)
2609        value_check.check_value(self, eval_result, str(eval_result))
2610        return eval_result
2611
2612    def expect_var_path(
2613            self,
2614            var_path,
2615            summary=None,
2616            value=None,
2617            type=None,
2618            children=None
2619            ):
2620        """
2621        Evaluates the given variable path and verifies the result.
2622        See also 'frame variable' and SBFrame.GetValueForVariablePath.
2623        :param var_path: The variable path as a string.
2624        :param summary: The summary that the variable should have. None if the summary should not be checked.
2625        :param value: The value that the variable should have. None if the value should not be checked.
2626        :param type: The type that the variable result should have. None if the type should not be checked.
2627        :param children: The expected children of the variable  as a list of ValueChecks.
2628                         None if the children shouldn't be checked.
2629        """
2630        self.assertTrue(var_path.strip() == var_path,
2631                        "Expression contains trailing/leading whitespace: '" + var_path + "'")
2632
2633        frame = self.frame()
2634        eval_result = frame.GetValueForVariablePath(var_path)
2635
2636        value_check = ValueCheck(type=type, value=value,
2637                                 summary=summary, children=children)
2638        value_check.check_value(self, eval_result, str(eval_result))
2639        return eval_result
2640
2641    def build(
2642            self,
2643            architecture=None,
2644            compiler=None,
2645            dictionary=None):
2646        """Platform specific way to build the default binaries."""
2647        module = builder_module()
2648
2649        if not architecture and configuration.arch:
2650            architecture = configuration.arch
2651
2652        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
2653        if self.getDebugInfo() is None:
2654            return self.buildDefault(architecture, compiler, dictionary)
2655        elif self.getDebugInfo() == "dsym":
2656            return self.buildDsym(architecture, compiler, dictionary)
2657        elif self.getDebugInfo() == "dwarf":
2658            return self.buildDwarf(architecture, compiler, dictionary)
2659        elif self.getDebugInfo() == "dwo":
2660            return self.buildDwo(architecture, compiler, dictionary)
2661        elif self.getDebugInfo() == "gmodules":
2662            return self.buildGModules(architecture, compiler, dictionary)
2663        else:
2664            self.fail("Can't build for debug info: %s" % self.getDebugInfo())
2665
2666    """Assert that an lldb.SBError is in the "success" state."""
2667    def assertSuccess(self, obj, msg=None):
2668        if not obj.Success():
2669            error = obj.GetCString()
2670            self.fail(self._formatMessage(msg,
2671                "'{}' is not success".format(error)))
2672
2673    # =================================================
2674    # Misc. helper methods for debugging test execution
2675    # =================================================
2676
2677    def DebugSBValue(self, val):
2678        """Debug print a SBValue object, if traceAlways is True."""
2679        from .lldbutil import value_type_to_str
2680
2681        if not traceAlways:
2682            return
2683
2684        err = sys.stderr
2685        err.write(val.GetName() + ":\n")
2686        err.write('\t' + "TypeName         -> " + val.GetTypeName() + '\n')
2687        err.write('\t' + "ByteSize         -> " +
2688                  str(val.GetByteSize()) + '\n')
2689        err.write('\t' + "NumChildren      -> " +
2690                  str(val.GetNumChildren()) + '\n')
2691        err.write('\t' + "Value            -> " + str(val.GetValue()) + '\n')
2692        err.write('\t' + "ValueAsUnsigned  -> " +
2693                  str(val.GetValueAsUnsigned()) + '\n')
2694        err.write(
2695            '\t' +
2696            "ValueType        -> " +
2697            value_type_to_str(
2698                val.GetValueType()) +
2699            '\n')
2700        err.write('\t' + "Summary          -> " + str(val.GetSummary()) + '\n')
2701        err.write('\t' + "IsPointerType    -> " +
2702                  str(val.TypeIsPointerType()) + '\n')
2703        err.write('\t' + "Location         -> " + val.GetLocation() + '\n')
2704
2705    def DebugSBType(self, type):
2706        """Debug print a SBType object, if traceAlways is True."""
2707        if not traceAlways:
2708            return
2709
2710        err = sys.stderr
2711        err.write(type.GetName() + ":\n")
2712        err.write('\t' + "ByteSize        -> " +
2713                  str(type.GetByteSize()) + '\n')
2714        err.write('\t' + "IsPointerType   -> " +
2715                  str(type.IsPointerType()) + '\n')
2716        err.write('\t' + "IsReferenceType -> " +
2717                  str(type.IsReferenceType()) + '\n')
2718
2719    def DebugPExpect(self, child):
2720        """Debug the spwaned pexpect object."""
2721        if not traceAlways:
2722            return
2723
2724        print(child)
2725
2726    @classmethod
2727    def RemoveTempFile(cls, file):
2728        if os.path.exists(file):
2729            remove_file(file)
2730
2731# On Windows, the first attempt to delete a recently-touched file can fail
2732# because of a race with antimalware scanners.  This function will detect a
2733# failure and retry.
2734
2735
2736def remove_file(file, num_retries=1, sleep_duration=0.5):
2737    for i in range(num_retries + 1):
2738        try:
2739            os.remove(file)
2740            return True
2741        except:
2742            time.sleep(sleep_duration)
2743            continue
2744    return False
2745