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