"""
LLDB module which provides the abstract base class of lldb test case.

The concrete subclass can override lldbtest.TestBase in order to inherit the
common behavior for unitest.TestCase.setUp/tearDown implemented in this file.

The subclass should override the attribute mydir in order for the python runtime
to locate the individual test cases when running as part of a large test suite
or when running each test case as a separate python invocation.

./dotest.py provides a test driver which sets up the environment to run the
entire of part of the test suite .  Example:

# Exercises the test suite in the types directory....
/Volumes/data/lldb/svn/ToT/test $ ./dotest.py -A x86_64 types
...

Session logs for test failures/errors/unexpected successes will go into directory '2012-05-16-13_35_42'
Command invoked: python ./dotest.py -A x86_64 types
compilers=['clang']

Configuration: arch=x86_64 compiler=clang
----------------------------------------------------------------------
Collected 72 tests

........................................................................
----------------------------------------------------------------------
Ran 72 tests in 135.468s

OK
$
"""

from __future__ import absolute_import
from __future__ import print_function

# System modules
import abc
from distutils.version import LooseVersion
from functools import wraps
import gc
import glob
import io
import os.path
import re
import shutil
import signal
from subprocess import *
import sys
import time
import traceback
import distutils.spawn

# Third-party modules
import unittest2
from six import add_metaclass
from six import StringIO as SixStringIO
import six

# LLDB modules
import lldb
from . import configuration
from . import decorators
from . import lldbplatformutil
from . import lldbtest_config
from . import lldbutil
from . import test_categories
from lldbsuite.support import encoded_file
from lldbsuite.support import funcutils
from lldbsuite.test.builders import get_builder

# See also dotest.parseOptionsAndInitTestdirs(), where the environment variables
# LLDB_COMMAND_TRACE is set from '-t' option.

# By default, traceAlways is False.
if "LLDB_COMMAND_TRACE" in os.environ and os.environ[
        "LLDB_COMMAND_TRACE"] == "YES":
    traceAlways = True
else:
    traceAlways = False

# By default, doCleanup is True.
if "LLDB_DO_CLEANUP" in os.environ and os.environ["LLDB_DO_CLEANUP"] == "NO":
    doCleanup = False
else:
    doCleanup = True


#
# Some commonly used assert messages.
#

COMMAND_FAILED_AS_EXPECTED = "Command has failed as expected"

CURRENT_EXECUTABLE_SET = "Current executable set successfully"

PROCESS_IS_VALID = "Process is valid"

PROCESS_KILLED = "Process is killed successfully"

PROCESS_EXITED = "Process exited successfully"

PROCESS_STOPPED = "Process status should be stopped"

RUN_SUCCEEDED = "Process is launched successfully"

RUN_COMPLETED = "Process exited successfully"

BACKTRACE_DISPLAYED_CORRECTLY = "Backtrace displayed correctly"

BREAKPOINT_CREATED = "Breakpoint created successfully"

BREAKPOINT_STATE_CORRECT = "Breakpoint state is correct"

BREAKPOINT_PENDING_CREATED = "Pending breakpoint created successfully"

BREAKPOINT_HIT_ONCE = "Breakpoint resolved with hit count = 1"

BREAKPOINT_HIT_TWICE = "Breakpoint resolved with hit count = 2"

BREAKPOINT_HIT_THRICE = "Breakpoint resolved with hit count = 3"

MISSING_EXPECTED_REGISTERS = "At least one expected register is unavailable."

OBJECT_PRINTED_CORRECTLY = "Object printed correctly"

SOURCE_DISPLAYED_CORRECTLY = "Source code displayed correctly"

STEP_IN_SUCCEEDED = "Thread step-in succeeded"

STEP_OUT_SUCCEEDED = "Thread step-out succeeded"

STOPPED_DUE_TO_EXC_BAD_ACCESS = "Process should be stopped due to bad access exception"

STOPPED_DUE_TO_ASSERT = "Process should be stopped due to an assertion"

STOPPED_DUE_TO_BREAKPOINT = "Process should be stopped due to breakpoint"

STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS = "%s, %s" % (
    STOPPED_DUE_TO_BREAKPOINT, "instead, the actual stop reason is: '%s'")

STOPPED_DUE_TO_BREAKPOINT_CONDITION = "Stopped due to breakpoint condition"

STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT = "Stopped due to breakpoint and ignore count"

STOPPED_DUE_TO_BREAKPOINT_JITTED_CONDITION = "Stopped due to breakpoint jitted condition"

STOPPED_DUE_TO_SIGNAL = "Process state is stopped due to signal"

STOPPED_DUE_TO_STEP_IN = "Process state is stopped due to step in"

STOPPED_DUE_TO_WATCHPOINT = "Process should be stopped due to watchpoint"

DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly"

VALID_BREAKPOINT = "Got a valid breakpoint"

VALID_BREAKPOINT_LOCATION = "Got a valid breakpoint location"

VALID_COMMAND_INTERPRETER = "Got a valid command interpreter"

VALID_FILESPEC = "Got a valid filespec"

VALID_MODULE = "Got a valid module"

VALID_PROCESS = "Got a valid process"

VALID_SYMBOL = "Got a valid symbol"

VALID_TARGET = "Got a valid target"

VALID_PLATFORM = "Got a valid platform"

VALID_TYPE = "Got a valid type"

VALID_VARIABLE = "Got a valid variable"

VARIABLES_DISPLAYED_CORRECTLY = "Variable(s) displayed correctly"

WATCHPOINT_CREATED = "Watchpoint created successfully"


def CMD_MSG(str):
    '''A generic "Command '%s' did not return successfully" message generator.'''
    return "Command '%s' did not return successfully" % str


def COMPLETION_MSG(str_before, str_after, completions):
    '''A generic assertion failed message generator for the completion mechanism.'''
    return ("'%s' successfully completes to '%s', but completions were:\n%s"
           % (str_before, str_after, "\n".join(completions)))


def EXP_MSG(str, actual, exe):
    '''A generic "'%s' returned unexpected result" message generator if exe.
    Otherwise, it generates "'%s' does not match expected result" message.'''

    return "'%s' %s result, got '%s'" % (
        str, 'returned unexpected' if exe else 'does not match expected', actual.strip())


def SETTING_MSG(setting):
    '''A generic "Value of setting '%s' is not correct" message generator.'''
    return "Value of setting '%s' is not correct" % setting


def line_number(filename, string_to_match):
    """Helper function to return the line number of the first matched string."""
    with io.open(filename, mode='r', encoding="utf-8") as f:
        for i, line in enumerate(f):
            if line.find(string_to_match) != -1:
                # Found our match.
                return i + 1
    raise Exception(
        "Unable to find '%s' within file %s" %
        (string_to_match, filename))

def get_line(filename, line_number):
    """Return the text of the line at the 1-based line number."""
    with io.open(filename, mode='r', encoding="utf-8") as f:
        return f.readlines()[line_number - 1]

def pointer_size():
    """Return the pointer size of the host system."""
    import ctypes
    a_pointer = ctypes.c_void_p(0xffff)
    return 8 * ctypes.sizeof(a_pointer)


def is_exe(fpath):
    """Returns true if fpath is an executable."""
    return os.path.isfile(fpath) and os.access(fpath, os.X_OK)


def which(program):
    """Returns the full path to a program; None otherwise."""
    fpath, fname = os.path.split(program)
    if fpath:
        if is_exe(program):
            return program
    else:
        for path in os.environ["PATH"].split(os.pathsep):
            exe_file = os.path.join(path, program)
            if is_exe(exe_file):
                return exe_file
    return None

class ValueCheck:
    def __init__(self, name=None, value=None, type=None, summary=None,
                 children=None):
        """
        :param name: The name that the SBValue should have. None if the summary
                     should not be checked.
        :param summary: The summary that the SBValue should have. None if the
                        summary should not be checked.
        :param value: The value that the SBValue should have. None if the value
                      should not be checked.
        :param type: The type that the SBValue result should have. None if the
                     type should not be checked.
        :param children: A list of ValueChecks that need to match the children
                         of this SBValue. None if children shouldn't be checked.
                         The order of checks is the order of the checks in the
                         list. The number of checks has to match the number of
                         children.
        """
        self.expect_name = name
        self.expect_value = value
        self.expect_type = type
        self.expect_summary = summary
        self.children = children

    def check_value(self, test_base, val, error_msg=None):
        """
        Checks that the given value matches the currently set properties
        of this ValueCheck. If a match failed, the given TestBase will
        be used to emit an error. A custom error message can be specified
        that will be used to describe failed check for this SBValue (but
        not errors in the child values).
        """

        this_error_msg = error_msg if error_msg else ""
        this_error_msg += "\nChecking SBValue: " + str(val)

        test_base.assertSuccess(val.GetError())

        if self.expect_name:
            test_base.assertEqual(self.expect_name, val.GetName(),
                                  this_error_msg)
        if self.expect_value:
            test_base.assertEqual(self.expect_value, val.GetValue(),
                                  this_error_msg)
        if self.expect_type:
            test_base.assertEqual(self.expect_type, val.GetDisplayTypeName(),
                                  this_error_msg)
        if self.expect_summary:
            test_base.assertEqual(self.expect_summary, val.GetSummary(),
                                  this_error_msg)
        if self.children is not None:
            self.check_value_children(test_base, val, error_msg)

    def check_value_children(self, test_base, val, error_msg=None):
        """
        Checks that the children of a SBValue match a certain structure and
        have certain properties.

        :param test_base: The current test's TestBase object.
        :param val: The SBValue to check.
        """

        this_error_msg = error_msg if error_msg else ""
        this_error_msg += "\nChecking SBValue: " + str(val)

        test_base.assertEqual(len(self.children), val.GetNumChildren(), this_error_msg)

        for i in range(0, val.GetNumChildren()):
            expected_child = self.children[i]
            actual_child = val.GetChildAtIndex(i)
            expected_child.check_value(test_base, actual_child, error_msg)

class recording(SixStringIO):
    """
    A nice little context manager for recording the debugger interactions into
    our session object.  If trace flag is ON, it also emits the interactions
    into the stderr.
    """

    def __init__(self, test, trace):
        """Create a SixStringIO instance; record the session obj and trace flag."""
        SixStringIO.__init__(self)
        # The test might not have undergone the 'setUp(self)' phase yet, so that
        # the attribute 'session' might not even exist yet.
        self.session = getattr(test, "session", None) if test else None
        self.trace = trace

    def __enter__(self):
        """
        Context management protocol on entry to the body of the with statement.
        Just return the SixStringIO object.
        """
        return self

    def __exit__(self, type, value, tb):
        """
        Context management protocol on exit from the body of the with statement.
        If trace is ON, it emits the recordings into stderr.  Always add the
        recordings to our session object.  And close the SixStringIO object, too.
        """
        if self.trace:
            print(self.getvalue(), file=sys.stderr)
        if self.session:
            print(self.getvalue(), file=self.session)
        self.close()


@add_metaclass(abc.ABCMeta)
class _BaseProcess(object):

    @abc.abstractproperty
    def pid(self):
        """Returns process PID if has been launched already."""

    @abc.abstractmethod
    def launch(self, executable, args):
        """Launches new process with given executable and args."""

    @abc.abstractmethod
    def terminate(self):
        """Terminates previously launched process.."""


class _LocalProcess(_BaseProcess):

    def __init__(self, trace_on):
        self._proc = None
        self._trace_on = trace_on
        self._delayafterterminate = 0.1

    @property
    def pid(self):
        return self._proc.pid

    def launch(self, executable, args):
        self._proc = Popen(
            [executable] + args,
            stdout=open(
                os.devnull) if not self._trace_on else None,
            stdin=PIPE,
            preexec_fn=lldbplatformutil.enable_attach)

    def terminate(self):
        if self._proc.poll() is None:
            # Terminate _proc like it does the pexpect
            signals_to_try = [
                sig for sig in [
                    'SIGHUP',
                    'SIGCONT',
                    'SIGINT'] if sig in dir(signal)]
            for sig in signals_to_try:
                try:
                    self._proc.send_signal(getattr(signal, sig))
                    time.sleep(self._delayafterterminate)
                    if self._proc.poll() is not None:
                        return
                except ValueError:
                    pass  # Windows says SIGINT is not a valid signal to send
            self._proc.terminate()
            time.sleep(self._delayafterterminate)
            if self._proc.poll() is not None:
                return
            self._proc.kill()
            time.sleep(self._delayafterterminate)

    def poll(self):
        return self._proc.poll()


class _RemoteProcess(_BaseProcess):

    def __init__(self, install_remote):
        self._pid = None
        self._install_remote = install_remote

    @property
    def pid(self):
        return self._pid

    def launch(self, executable, args):
        if self._install_remote:
            src_path = executable
            dst_path = lldbutil.join_remote_paths(
                    lldb.remote_platform.GetWorkingDirectory(), os.path.basename(executable))

            dst_file_spec = lldb.SBFileSpec(dst_path, False)
            err = lldb.remote_platform.Install(
                lldb.SBFileSpec(src_path, True), dst_file_spec)
            if err.Fail():
                raise Exception(
                    "remote_platform.Install('%s', '%s') failed: %s" %
                    (src_path, dst_path, err))
        else:
            dst_path = executable
            dst_file_spec = lldb.SBFileSpec(executable, False)

        launch_info = lldb.SBLaunchInfo(args)
        launch_info.SetExecutableFile(dst_file_spec, True)
        launch_info.SetWorkingDirectory(
            lldb.remote_platform.GetWorkingDirectory())

        # Redirect stdout and stderr to /dev/null
        launch_info.AddSuppressFileAction(1, False, True)
        launch_info.AddSuppressFileAction(2, False, True)

        err = lldb.remote_platform.Launch(launch_info)
        if err.Fail():
            raise Exception(
                "remote_platform.Launch('%s', '%s') failed: %s" %
                (dst_path, args, err))
        self._pid = launch_info.GetProcessID()

    def terminate(self):
        lldb.remote_platform.Kill(self._pid)

# From 2.7's subprocess.check_output() convenience function.
# Return a tuple (stdoutdata, stderrdata).


def system(commands, **kwargs):
    r"""Run an os command with arguments and return its output as a byte string.

    If the exit code was non-zero it raises a CalledProcessError.  The
    CalledProcessError object will have the return code in the returncode
    attribute and output in the output attribute.

    The arguments are the same as for the Popen constructor.  Example:

    >>> check_output(["ls", "-l", "/dev/null"])
    'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'

    The stdout argument is not allowed as it is used internally.
    To capture standard error in the result, use stderr=STDOUT.

    >>> check_output(["/bin/sh", "-c",
    ...               "ls -l non_existent_file ; exit 0"],
    ...              stderr=STDOUT)
    'ls: non_existent_file: No such file or directory\n'
    """

    # Assign the sender object to variable 'test' and remove it from kwargs.
    test = kwargs.pop('sender', None)

    # [['make', 'clean', 'foo'], ['make', 'foo']] -> ['make clean foo', 'make foo']
    commandList = [' '.join(x) for x in commands]
    output = ""
    error = ""
    for shellCommand in commandList:
        if 'stdout' in kwargs:
            raise ValueError(
                'stdout argument not allowed, it will be overridden.')
        if 'shell' in kwargs and kwargs['shell'] == False:
            raise ValueError('shell=False not allowed')
        process = Popen(
            shellCommand,
            stdout=PIPE,
            stderr=STDOUT,
            shell=True,
            **kwargs)
        pid = process.pid
        this_output, this_error = process.communicate()
        retcode = process.poll()

        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = shellCommand
            cpe = CalledProcessError(retcode, cmd)
            # Ensure caller can access the stdout/stderr.
            cpe.lldb_extensions = {
                "combined_output": this_output,
                "command": shellCommand
            }
            raise cpe
        output = output + this_output.decode("utf-8", errors='ignore')
    return output


def getsource_if_available(obj):
    """
    Return the text of the source code for an object if available.  Otherwise,
    a print representation is returned.
    """
    import inspect
    try:
        return inspect.getsource(obj)
    except:
        return repr(obj)


def builder_module():
    return get_builder(sys.platform)


class Base(unittest2.TestCase):
    """
    Abstract base for performing lldb (see TestBase) or other generic tests (see
    BenchBase for one example).  lldbtest.Base works with the test driver to
    accomplish things.

    """

    # The concrete subclass should override this attribute.
    mydir = None

    # Keep track of the old current working directory.
    oldcwd = None

    @staticmethod
    def compute_mydir(test_file):
        '''Subclasses should call this function to correctly calculate the
           required "mydir" attribute as follows:

            mydir = TestBase.compute_mydir(__file__)
        '''
        # /abs/path/to/packages/group/subdir/mytest.py -> group/subdir
        lldb_test_src = configuration.test_src_root
        if not test_file.startswith(lldb_test_src):
          raise Exception(
              "Test file '%s' must reside within lldb_test_src "
              "(which is '%s')." % (test_file, lldb_test_src))
        return os.path.dirname(os.path.relpath(test_file, start=lldb_test_src))

    def TraceOn(self):
        """Returns True if we are in trace mode (tracing detailed test execution)."""
        return traceAlways

    def trace(self, *args,**kwargs):
        with recording(self, self.TraceOn()) as sbuf:
            print(*args, file=sbuf, **kwargs)

    @classmethod
    def setUpClass(cls):
        """
        Python unittest framework class setup fixture.
        Do current directory manipulation.
        """
        # Fail fast if 'mydir' attribute is not overridden.
        if not cls.mydir or len(cls.mydir) == 0:
            raise Exception("Subclasses must override the 'mydir' attribute.")

        # Save old working directory.
        cls.oldcwd = os.getcwd()

        full_dir = os.path.join(configuration.test_src_root, cls.mydir)
        if traceAlways:
            print("Change dir to:", full_dir, file=sys.stderr)
        os.chdir(full_dir)
        lldb.SBReproducer.SetWorkingDirectory(full_dir)

        # Set platform context.
        cls.platformContext = lldbplatformutil.createPlatformContext()

    @classmethod
    def tearDownClass(cls):
        """
        Python unittest framework class teardown fixture.
        Do class-wide cleanup.
        """

        if doCleanup:
            # First, let's do the platform-specific cleanup.
            module = builder_module()
            module.cleanup()

            # Subclass might have specific cleanup function defined.
            if getattr(cls, "classCleanup", None):
                if traceAlways:
                    print(
                        "Call class-specific cleanup function for class:",
                        cls,
                        file=sys.stderr)
                try:
                    cls.classCleanup()
                except:
                    exc_type, exc_value, exc_tb = sys.exc_info()
                    traceback.print_exception(exc_type, exc_value, exc_tb)

        # Restore old working directory.
        if traceAlways:
            print("Restore dir to:", cls.oldcwd, file=sys.stderr)
        os.chdir(cls.oldcwd)

    def enableLogChannelsForCurrentTest(self):
        if len(lldbtest_config.channels) == 0:
            return

        # if debug channels are specified in lldbtest_config.channels,
        # create a new set of log files for every test
        log_basename = self.getLogBasenameForCurrentTest()

        # confirm that the file is writeable
        host_log_path = "{}-host.log".format(log_basename)
        open(host_log_path, 'w').close()
        self.log_files.append(host_log_path)

        log_enable = "log enable -Tpn -f {} ".format(host_log_path)
        for channel_with_categories in lldbtest_config.channels:
            channel_then_categories = channel_with_categories.split(' ', 1)
            channel = channel_then_categories[0]
            if len(channel_then_categories) > 1:
                categories = channel_then_categories[1]
            else:
                categories = "default"

            if channel == "gdb-remote" and lldb.remote_platform is None:
                # communicate gdb-remote categories to debugserver
                os.environ["LLDB_DEBUGSERVER_LOG_FLAGS"] = categories

            self.ci.HandleCommand(
                log_enable + channel_with_categories, self.res)
            if not self.res.Succeeded():
                raise Exception(
                    'log enable failed (check LLDB_LOG_OPTION env variable)')

        # Communicate log path name to debugserver & lldb-server
        # For remote debugging, these variables need to be set when starting the platform
        # instance.
        if lldb.remote_platform is None:
            server_log_path = "{}-server.log".format(log_basename)
            open(server_log_path, 'w').close()
            self.log_files.append(server_log_path)
            os.environ["LLDB_DEBUGSERVER_LOG_FILE"] = server_log_path

            # Communicate channels to lldb-server
            os.environ["LLDB_SERVER_LOG_CHANNELS"] = ":".join(
                lldbtest_config.channels)

        self.addTearDownHook(self.disableLogChannelsForCurrentTest)

    def disableLogChannelsForCurrentTest(self):
        # close all log files that we opened
        for channel_and_categories in lldbtest_config.channels:
            # channel format - <channel-name> [<category0> [<category1> ...]]
            channel = channel_and_categories.split(' ', 1)[0]
            self.ci.HandleCommand("log disable " + channel, self.res)
            if not self.res.Succeeded():
                raise Exception(
                    'log disable failed (check LLDB_LOG_OPTION env variable)')

        # Retrieve the server log (if any) from the remote system. It is assumed the server log
        # is writing to the "server.log" file in the current test directory. This can be
        # achieved by setting LLDB_DEBUGSERVER_LOG_FILE="server.log" when starting remote
        # platform.
        if lldb.remote_platform:
            server_log_path = self.getLogBasenameForCurrentTest() + "-server.log"
            if lldb.remote_platform.Get(
                lldb.SBFileSpec("server.log"),
                lldb.SBFileSpec(server_log_path)).Success():
                self.log_files.append(server_log_path)

    def setPlatformWorkingDir(self):
        if not lldb.remote_platform or not configuration.lldb_platform_working_dir:
            return

        components = self.mydir.split(os.path.sep) + [str(self.test_number), self.getBuildDirBasename()]
        remote_test_dir = configuration.lldb_platform_working_dir
        for c in components:
            remote_test_dir = lldbutil.join_remote_paths(remote_test_dir, c)
            error = lldb.remote_platform.MakeDirectory(
                remote_test_dir, 448)  # 448 = 0o700
            if error.Fail():
                raise Exception("making remote directory '%s': %s" % (
                    remote_test_dir, error))

        lldb.remote_platform.SetWorkingDirectory(remote_test_dir)

        # This function removes all files from the current working directory while leaving
        # the directories in place. The cleanup is required to reduce the disk space required
        # by the test suite while leaving the directories untouched is neccessary because
        # sub-directories might belong to an other test
        def clean_working_directory():
            # TODO: Make it working on Windows when we need it for remote debugging support
            # TODO: Replace the heuristic to remove the files with a logic what collects the
            # list of files we have to remove during test runs.
            shell_cmd = lldb.SBPlatformShellCommand(
                "rm %s/*" % remote_test_dir)
            lldb.remote_platform.Run(shell_cmd)
        self.addTearDownHook(clean_working_directory)

    def getSourceDir(self):
        """Return the full path to the current test."""
        return os.path.join(configuration.test_src_root, self.mydir)

    def getBuildDirBasename(self):
        return self.__class__.__module__ + "." + self.testMethodName

    def getBuildDir(self):
        """Return the full path to the current test."""
        return os.path.join(configuration.test_build_dir, self.mydir,
                            self.getBuildDirBasename())

    def getReproducerDir(self):
        """Return the full path to the reproducer if enabled."""
        if configuration.capture_path:
            return configuration.capture_path
        if configuration.replay_path:
            return configuration.replay_path
        return None

    def makeBuildDir(self):
        """Create the test-specific working directory, deleting any previous
        contents."""
        bdir = self.getBuildDir()
        if os.path.isdir(bdir):
            shutil.rmtree(bdir)
        lldbutil.mkdir_p(bdir)

    def getBuildArtifact(self, name="a.out"):
        """Return absolute path to an artifact in the test's build directory."""
        return os.path.join(self.getBuildDir(), name)

    def getSourcePath(self, name):
        """Return absolute path to a file in the test's source directory."""
        return os.path.join(self.getSourceDir(), name)

    def getReproducerArtifact(self, name):
        lldbutil.mkdir_p(self.getReproducerDir())
        return os.path.join(self.getReproducerDir(), name)

    def getReproducerRemappedPath(self, path):
        assert configuration.replay_path
        assert os.path.isabs(path)
        path = os.path.relpath(path, '/')
        return os.path.join(configuration.replay_path, 'root', path)

    @classmethod
    def setUpCommands(cls):
        commands = [
            # First of all, clear all settings to have clean state of global properties.
            "settings clear -all",

            # Disable Spotlight lookup. The testsuite creates
            # different binaries with the same UUID, because they only
            # differ in the debug info, which is not being hashed.
            "settings set symbols.enable-external-lookup false",

            # Inherit the TCC permissions from the inferior's parent.
            "settings set target.inherit-tcc true",

            # Kill rather than detach from the inferior if something goes wrong.
            "settings set target.detach-on-error false",

            # Disable fix-its by default so that incorrect expressions in tests don't
            # pass just because Clang thinks it has a fix-it.
            "settings set target.auto-apply-fixits false",

            # Testsuite runs in parallel and the host can have also other load.
            "settings set plugin.process.gdb-remote.packet-timeout 60",

            'settings set symbols.clang-modules-cache-path "{}"'.format(
                configuration.lldb_module_cache_dir),
            "settings set use-color false",
        ]

        # Set any user-overridden settings.
        for setting, value in configuration.settings:
            commands.append('setting set %s %s'%(setting, value))

        # Make sure that a sanitizer LLDB's environment doesn't get passed on.
        if cls.platformContext and cls.platformContext.shlib_environment_var in os.environ:
            commands.append('settings set target.env-vars {}='.format(
                cls.platformContext.shlib_environment_var))

        # Set environment variables for the inferior.
        if lldbtest_config.inferior_env:
            commands.append('settings set target.env-vars {}'.format(
                lldbtest_config.inferior_env))
        return commands

    def setUp(self):
        """Fixture for unittest test case setup.

        It works with the test driver to conditionally skip tests and does other
        initializations."""
        #import traceback
        # traceback.print_stack()

        if "LIBCXX_PATH" in os.environ:
            self.libcxxPath = os.environ["LIBCXX_PATH"]
        else:
            self.libcxxPath = None

        if "LLDBVSCODE_EXEC" in os.environ:
            self.lldbVSCodeExec = os.environ["LLDBVSCODE_EXEC"]
        else:
            self.lldbVSCodeExec = None

        self.lldbOption = " ".join(
            "-o '" + s + "'" for s in self.setUpCommands())

        # If we spawn an lldb process for test (via pexpect), do not load the
        # init file unless told otherwise.
        if os.environ.get("NO_LLDBINIT") != "NO":
            self.lldbOption += " --no-lldbinit"

        # Assign the test method name to self.testMethodName.
        #
        # For an example of the use of this attribute, look at test/types dir.
        # There are a bunch of test cases under test/types and we don't want the
        # module cacheing subsystem to be confused with executable name "a.out"
        # used for all the test cases.
        self.testMethodName = self._testMethodName

        # This is for the case of directly spawning 'lldb'/'gdb' and interacting
        # with it using pexpect.
        self.child = None
        self.child_prompt = "(lldb) "
        # If the child is interacting with the embedded script interpreter,
        # there are two exits required during tear down, first to quit the
        # embedded script interpreter and second to quit the lldb command
        # interpreter.
        self.child_in_script_interpreter = False

        # These are for customized teardown cleanup.
        self.dict = None
        self.doTearDownCleanup = False
        # And in rare cases where there are multiple teardown cleanups.
        self.dicts = []
        self.doTearDownCleanups = False

        # List of spawned subproces.Popen objects
        self.subprocesses = []

        # List of log files produced by the current test.
        self.log_files = []

        # Create the build directory.
        # The logs are stored in the build directory, so we have to create it
        # before creating the first log file.
        self.makeBuildDir()

        session_file = self.getLogBasenameForCurrentTest()+".log"
        self.log_files.append(session_file)

        # Python 3 doesn't support unbuffered I/O in text mode.  Open buffered.
        self.session = encoded_file.open(session_file, "utf-8", mode="w")

        # Optimistically set __errored__, __failed__, __expected__ to False
        # initially.  If the test errored/failed, the session info
        # (self.session) is then dumped into a session specific file for
        # diagnosis.
        self.__cleanup_errored__ = False
        self.__errored__ = False
        self.__failed__ = False
        self.__expected__ = False
        # We are also interested in unexpected success.
        self.__unexpected__ = False
        # And skipped tests.
        self.__skipped__ = False

        # See addTearDownHook(self, hook) which allows the client to add a hook
        # function to be run during tearDown() time.
        self.hooks = []

        # See HideStdout(self).
        self.sys_stdout_hidden = False

        if self.platformContext:
            # set environment variable names for finding shared libraries
            self.dylibPath = self.platformContext.shlib_environment_var

        # Create the debugger instance.
        self.dbg = lldb.SBDebugger.Create()
        # Copy selected platform from a global instance if it exists.
        if lldb.selected_platform is not None:
            self.dbg.SetSelectedPlatform(lldb.selected_platform)

        if not self.dbg:
            raise Exception('Invalid debugger instance')

        # Retrieve the associated command interpreter instance.
        self.ci = self.dbg.GetCommandInterpreter()
        if not self.ci:
            raise Exception('Could not get the command interpreter')

        # And the result object.
        self.res = lldb.SBCommandReturnObject()

        self.setPlatformWorkingDir()
        self.enableLogChannelsForCurrentTest()

        self.lib_lldb = None
        self.framework_dir = None
        self.darwinWithFramework = False

        if sys.platform.startswith("darwin") and configuration.lldb_framework_path:
            framework = configuration.lldb_framework_path
            lib = os.path.join(framework, 'LLDB')
            if os.path.exists(lib):
                self.framework_dir = os.path.dirname(framework)
                self.lib_lldb = lib
                self.darwinWithFramework = self.platformIsDarwin()

    def setAsync(self, value):
        """ Sets async mode to True/False and ensures it is reset after the testcase completes."""
        old_async = self.dbg.GetAsync()
        self.dbg.SetAsync(value)
        self.addTearDownHook(lambda: self.dbg.SetAsync(old_async))

    def cleanupSubprocesses(self):
        # Terminate subprocesses in reverse order from how they were created.
        for p in reversed(self.subprocesses):
            p.terminate()
            del p
        del self.subprocesses[:]

    def spawnSubprocess(self, executable, args=[], install_remote=True):
        """ Creates a subprocess.Popen object with the specified executable and arguments,
            saves it in self.subprocesses, and returns the object.
        """
        proc = _RemoteProcess(
            install_remote) if lldb.remote_platform else _LocalProcess(self.TraceOn())
        proc.launch(executable, args)
        self.subprocesses.append(proc)
        return proc

    def HideStdout(self):
        """Hide output to stdout from the user.

        During test execution, there might be cases where we don't want to show the
        standard output to the user.  For example,

            self.runCmd(r'''sc print("\n\n\tHello!\n")''')

        tests whether command abbreviation for 'script' works or not.  There is no
        need to show the 'Hello' output to the user as long as the 'script' command
        succeeds and we are not in TraceOn() mode (see the '-t' option).

        In this case, the test method calls self.HideStdout(self) to redirect the
        sys.stdout to a null device, and restores the sys.stdout upon teardown.

        Note that you should only call this method at most once during a test case
        execution.  Any subsequent call has no effect at all."""
        if self.sys_stdout_hidden:
            return

        self.sys_stdout_hidden = True
        old_stdout = sys.stdout
        sys.stdout = open(os.devnull, 'w')

        def restore_stdout():
            sys.stdout = old_stdout
        self.addTearDownHook(restore_stdout)

    # =======================================================================
    # Methods for customized teardown cleanups as well as execution of hooks.
    # =======================================================================

    def setTearDownCleanup(self, dictionary=None):
        """Register a cleanup action at tearDown() time with a dictionary"""
        self.dict = dictionary
        self.doTearDownCleanup = True

    def addTearDownCleanup(self, dictionary):
        """Add a cleanup action at tearDown() time with a dictionary"""
        self.dicts.append(dictionary)
        self.doTearDownCleanups = True

    def addTearDownHook(self, hook):
        """
        Add a function to be run during tearDown() time.

        Hooks are executed in a first come first serve manner.
        """
        if six.callable(hook):
            with recording(self, traceAlways) as sbuf:
                print(
                    "Adding tearDown hook:",
                    getsource_if_available(hook),
                    file=sbuf)
            self.hooks.append(hook)

        return self

    def deletePexpectChild(self):
        # This is for the case of directly spawning 'lldb' and interacting with it
        # using pexpect.
        if self.child and self.child.isalive():
            import pexpect
            with recording(self, traceAlways) as sbuf:
                print("tearing down the child process....", file=sbuf)
            try:
                if self.child_in_script_interpreter:
                    self.child.sendline('quit()')
                    self.child.expect_exact(self.child_prompt)
                self.child.sendline(
                    'settings set interpreter.prompt-on-quit false')
                self.child.sendline('quit')
                self.child.expect(pexpect.EOF)
            except (ValueError, pexpect.ExceptionPexpect):
                # child is already terminated
                pass
            except OSError as exception:
                import errno
                if exception.errno != errno.EIO:
                    # unexpected error
                    raise
                # child is already terminated
            finally:
                # Give it one final blow to make sure the child is terminated.
                self.child.close()

    def tearDown(self):
        """Fixture for unittest test case teardown."""
        self.deletePexpectChild()

        # Check and run any hook functions.
        for hook in reversed(self.hooks):
            with recording(self, traceAlways) as sbuf:
                print(
                    "Executing tearDown hook:",
                    getsource_if_available(hook),
                    file=sbuf)
            if funcutils.requires_self(hook):
                hook(self)
            else:
                hook()  # try the plain call and hope it works

        del self.hooks

        # Perform registered teardown cleanup.
        if doCleanup and self.doTearDownCleanup:
            self.cleanup(dictionary=self.dict)

        # In rare cases where there are multiple teardown cleanups added.
        if doCleanup and self.doTearDownCleanups:
            if self.dicts:
                for dict in reversed(self.dicts):
                    self.cleanup(dictionary=dict)

        # Remove subprocesses created by the test.
        self.cleanupSubprocesses()

        # This must be the last statement, otherwise teardown hooks or other
        # lines might depend on this still being active.
        lldb.SBDebugger.Destroy(self.dbg)
        del self.dbg

        # All modules should be orphaned now so that they can be cleared from
        # the shared module cache.
        lldb.SBModule.GarbageCollectAllocatedModules()

        # Modules are not orphaned during reproducer replay because they're
        # leaked on purpose.
        if not configuration.is_reproducer():
            # Assert that the global module cache is empty.
            self.assertEqual(lldb.SBModule.GetNumberAllocatedModules(), 0)


    # =========================================================
    # Various callbacks to allow introspection of test progress
    # =========================================================

    def markError(self):
        """Callback invoked when an error (unexpected exception) errored."""
        self.__errored__ = True
        with recording(self, False) as sbuf:
            # False because there's no need to write "ERROR" to the stderr twice.
            # Once by the Python unittest framework, and a second time by us.
            print("ERROR", file=sbuf)

    def markCleanupError(self):
        """Callback invoked when an error occurs while a test is cleaning up."""
        self.__cleanup_errored__ = True
        with recording(self, False) as sbuf:
            # False because there's no need to write "CLEANUP_ERROR" to the stderr twice.
            # Once by the Python unittest framework, and a second time by us.
            print("CLEANUP_ERROR", file=sbuf)

    def markFailure(self):
        """Callback invoked when a failure (test assertion failure) occurred."""
        self.__failed__ = True
        with recording(self, False) as sbuf:
            # False because there's no need to write "FAIL" to the stderr twice.
            # Once by the Python unittest framework, and a second time by us.
            print("FAIL", file=sbuf)

    def markExpectedFailure(self, err, bugnumber):
        """Callback invoked when an expected failure/error occurred."""
        self.__expected__ = True
        with recording(self, False) as sbuf:
            # False because there's no need to write "expected failure" to the
            # stderr twice.
            # Once by the Python unittest framework, and a second time by us.
            if bugnumber is None:
                print("expected failure", file=sbuf)
            else:
                print(
                    "expected failure (problem id:" + str(bugnumber) + ")",
                    file=sbuf)

    def markSkippedTest(self):
        """Callback invoked when a test is skipped."""
        self.__skipped__ = True
        with recording(self, False) as sbuf:
            # False because there's no need to write "skipped test" to the
            # stderr twice.
            # Once by the Python unittest framework, and a second time by us.
            print("skipped test", file=sbuf)

    def markUnexpectedSuccess(self, bugnumber):
        """Callback invoked when an unexpected success occurred."""
        self.__unexpected__ = True
        with recording(self, False) as sbuf:
            # False because there's no need to write "unexpected success" to the
            # stderr twice.
            # Once by the Python unittest framework, and a second time by us.
            if bugnumber is None:
                print("unexpected success", file=sbuf)
            else:
                print(
                    "unexpected success (problem id:" + str(bugnumber) + ")",
                    file=sbuf)

    def getRerunArgs(self):
        return " -f %s.%s" % (self.__class__.__name__, self._testMethodName)

    def getLogBasenameForCurrentTest(self, prefix="Incomplete"):
        """
        returns a partial path that can be used as the beginning of the name of multiple
        log files pertaining to this test
        """
        return os.path.join(self.getBuildDir(), prefix)

    def dumpSessionInfo(self):
        """
        Dump the debugger interactions leading to a test error/failure.  This
        allows for more convenient postmortem analysis.

        See also LLDBTestResult (dotest.py) which is a singlton class derived
        from TextTestResult and overwrites addError, addFailure, and
        addExpectedFailure methods to allow us to to mark the test instance as
        such.
        """

        # We are here because self.tearDown() detected that this test instance
        # either errored or failed.  The lldb.test_result singleton contains
        # two lists (errors and failures) which get populated by the unittest
        # framework.  Look over there for stack trace information.
        #
        # The lists contain 2-tuples of TestCase instances and strings holding
        # formatted tracebacks.
        #
        # See http://docs.python.org/library/unittest.html#unittest.TestResult.

        # output tracebacks into session
        pairs = []
        if self.__errored__:
            pairs = configuration.test_result.errors
            prefix = 'Error'
        elif self.__cleanup_errored__:
            pairs = configuration.test_result.cleanup_errors
            prefix = 'CleanupError'
        elif self.__failed__:
            pairs = configuration.test_result.failures
            prefix = 'Failure'
        elif self.__expected__:
            pairs = configuration.test_result.expectedFailures
            prefix = 'ExpectedFailure'
        elif self.__skipped__:
            prefix = 'SkippedTest'
        elif self.__unexpected__:
            prefix = 'UnexpectedSuccess'
        else:
            prefix = 'Success'

        if not self.__unexpected__ and not self.__skipped__:
            for test, traceback in pairs:
                if test is self:
                    print(traceback, file=self.session)

        import datetime
        print(
            "Session info generated @",
            datetime.datetime.now().ctime(),
            file=self.session)
        self.session.close()
        del self.session

        # process the log files
        if prefix != 'Success' or lldbtest_config.log_success:
            # keep all log files, rename them to include prefix
            src_log_basename = self.getLogBasenameForCurrentTest()
            dst_log_basename = self.getLogBasenameForCurrentTest(prefix)
            for src in self.log_files:
                if os.path.isfile(src):
                    dst = src.replace(src_log_basename, dst_log_basename)
                    if os.name == "nt" and os.path.isfile(dst):
                        # On Windows, renaming a -> b will throw an exception if
                        # b exists.  On non-Windows platforms it silently
                        # replaces the destination.  Ultimately this means that
                        # atomic renames are not guaranteed to be possible on
                        # Windows, but we need this to work anyway, so just
                        # remove the destination first if it already exists.
                        remove_file(dst)

                    lldbutil.mkdir_p(os.path.dirname(dst))
                    os.rename(src, dst)
        else:
            # success!  (and we don't want log files) delete log files
            for log_file in self.log_files:
                if os.path.isfile(log_file):
                    remove_file(log_file)

    # ====================================================
    # Config. methods supported through a plugin interface
    # (enables reading of the current test configuration)
    # ====================================================

    def isMIPS(self):
        """Returns true if the architecture is MIPS."""
        arch = self.getArchitecture()
        if re.match("mips", arch):
            return True
        return False

    def isPPC64le(self):
        """Returns true if the architecture is PPC64LE."""
        arch = self.getArchitecture()
        if re.match("powerpc64le", arch):
            return True
        return False

    def isAArch64SVE(self):
        triple = self.dbg.GetSelectedPlatform().GetTriple()

        # TODO other platforms, please implement this function
        if not re.match(".*-.*-linux", triple):
            return False

        # Need to do something different for non-Linux/Android targets
        cpuinfo_path = self.getBuildArtifact("cpuinfo")
        if configuration.lldb_platform_name:
            self.runCmd('platform get-file "/proc/cpuinfo" ' + cpuinfo_path)
        else:
            cpuinfo_path = "/proc/cpuinfo"

        try:
            f = open(cpuinfo_path, 'r')
            cpuinfo = f.read()
            f.close()
        except:
            return False

        return " sve " in cpuinfo

    def hasLinuxVmFlags(self):
        """ Check that the target machine has "VmFlags" lines in
        its /proc/{pid}/smaps files."""

        triple = self.dbg.GetSelectedPlatform().GetTriple()
        if not re.match(".*-.*-linux", triple):
            return False

        self.runCmd('platform process list')
        pid = None
        for line in self.res.GetOutput().splitlines():
            if 'lldb-server' in line:
                pid = line.split(' ')[0]
                break

        if pid is None:
            return False

        smaps_path = self.getBuildArtifact('smaps')
        self.runCmd('platform get-file "/proc/{}/smaps" {}'.format(pid, smaps_path))

        with open(smaps_path, 'r') as f:
            return "VmFlags" in f.read()

    def getArchitecture(self):
        """Returns the architecture in effect the test suite is running with."""
        module = builder_module()
        arch = module.getArchitecture()
        if arch == 'amd64':
            arch = 'x86_64'
        if arch in ['armv7l', 'armv8l'] :
            arch = 'arm'
        return arch

    def getLldbArchitecture(self):
        """Returns the architecture of the lldb binary."""
        if not hasattr(self, 'lldbArchitecture'):

            # spawn local process
            command = [
                lldbtest_config.lldbExec,
                "-o",
                "file " + lldbtest_config.lldbExec,
                "-o",
                "quit"
            ]

            output = check_output(command)
            str = output.decode("utf-8")

            for line in str.splitlines():
                m = re.search(
                    "Current executable set to '.*' \\((.*)\\)\\.", line)
                if m:
                    self.lldbArchitecture = m.group(1)
                    break

        return self.lldbArchitecture

    def getCompiler(self):
        """Returns the compiler in effect the test suite is running with."""
        module = builder_module()
        return module.getCompiler()

    def getCompilerBinary(self):
        """Returns the compiler binary the test suite is running with."""
        return self.getCompiler().split()[0]

    def getCompilerVersion(self):
        """ Returns a string that represents the compiler version.
            Supports: llvm, clang.
        """
        compiler = self.getCompilerBinary()
        version_output = system([[compiler, "--version"]])
        for line in version_output.split(os.linesep):
            m = re.search('version ([0-9.]+)', line)
            if m:
                return m.group(1)
        return 'unknown'

    def getDwarfVersion(self):
        """ Returns the dwarf version generated by clang or '0'. """
        if configuration.dwarf_version:
            return str(configuration.dwarf_version)
        if 'clang' in self.getCompiler():
            try:
                driver_output = check_output(
                    [self.getCompiler()] + '-g -c -x c - -o - -###'.split(),
                    stderr=STDOUT)
                driver_output = driver_output.decode("utf-8")
                for line in driver_output.split(os.linesep):
                    m = re.search('dwarf-version=([0-9])', line)
                    if m:
                        return m.group(1)
            except: pass
        return '0'

    def platformIsDarwin(self):
        """Returns true if the OS triple for the selected platform is any valid apple OS"""
        return lldbplatformutil.platformIsDarwin()

    def hasDarwinFramework(self):
        return self.darwinWithFramework

    def getPlatform(self):
        """Returns the target platform the test suite is running on."""
        return lldbplatformutil.getPlatform()

    def isIntelCompiler(self):
        """ Returns true if using an Intel (ICC) compiler, false otherwise. """
        return any([x in self.getCompiler() for x in ["icc", "icpc", "icl"]])

    def expectedCompilerVersion(self, compiler_version):
        """Returns True iff compiler_version[1] matches the current compiler version.
           Use compiler_version[0] to specify the operator used to determine if a match has occurred.
           Any operator other than the following defaults to an equality test:
             '>', '>=', "=>", '<', '<=', '=<', '!=', "!" or 'not'

           If the current compiler version cannot be determined, we assume it is close to the top
           of trunk, so any less-than or equal-to comparisons will return False, and any
           greater-than or not-equal-to comparisons will return True.
        """
        if compiler_version is None:
            return True
        operator = str(compiler_version[0])
        version = compiler_version[1]

        if version is None:
            return True

        test_compiler_version = self.getCompilerVersion()
        if test_compiler_version == 'unknown':
            # Assume the compiler version is at or near the top of trunk.
            return operator in ['>', '>=', '!', '!=', 'not']

        if operator == '>':
            return LooseVersion(test_compiler_version) > LooseVersion(version)
        if operator == '>=' or operator == '=>':
            return LooseVersion(test_compiler_version) >= LooseVersion(version)
        if operator == '<':
            return LooseVersion(test_compiler_version) < LooseVersion(version)
        if operator == '<=' or operator == '=<':
            return LooseVersion(test_compiler_version) <= LooseVersion(version)
        if operator == '!=' or operator == '!' or operator == 'not':
            return str(version) not in str(test_compiler_version)
        return str(version) in str(test_compiler_version)

    def expectedCompiler(self, compilers):
        """Returns True iff any element of compilers is a sub-string of the current compiler."""
        if (compilers is None):
            return True

        for compiler in compilers:
            if compiler in self.getCompiler():
                return True

        return False

    def expectedArch(self, archs):
        """Returns True iff any element of archs is a sub-string of the current architecture."""
        if (archs is None):
            return True

        for arch in archs:
            if arch in self.getArchitecture():
                return True

        return False

    def getRunOptions(self):
        """Command line option for -A and -C to run this test again, called from
        self.dumpSessionInfo()."""
        arch = self.getArchitecture()
        comp = self.getCompiler()
        option_str = ""
        if arch:
            option_str = "-A " + arch
        if comp:
            option_str += " -C " + comp
        return option_str

    def getDebugInfo(self):
        method = getattr(self, self.testMethodName)
        return getattr(method, "debug_info", None)

    # ==================================================
    # Build methods supported through a plugin interface
    # ==================================================

    def getstdlibFlag(self):
        """ Returns the proper -stdlib flag, or empty if not required."""
        if self.platformIsDarwin() or self.getPlatform() == "freebsd" or self.getPlatform() == "openbsd":
            stdlibflag = "-stdlib=libc++"
        else:  # this includes NetBSD
            stdlibflag = ""
        return stdlibflag

    def getstdFlag(self):
        """ Returns the proper stdflag. """
        if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
            stdflag = "-std=c++0x"
        else:
            stdflag = "-std=c++11"
        return stdflag

    def buildDriver(self, sources, exe_name):
        """ Platform-specific way to build a program that links with LLDB (via the liblldb.so
            or LLDB.framework).
        """
        stdflag = self.getstdFlag()
        stdlibflag = self.getstdlibFlag()

        lib_dir = configuration.lldb_libs_dir
        if self.hasDarwinFramework():
            d = {'CXX_SOURCES': sources,
                 'EXE': exe_name,
                 'CFLAGS_EXTRAS': "%s %s" % (stdflag, stdlibflag),
                 'FRAMEWORK_INCLUDES': "-F%s" % self.framework_dir,
                 'LD_EXTRAS': "%s -Wl,-rpath,%s" % (self.lib_lldb, self.framework_dir),
                 }
        elif sys.platform.startswith('win'):
            d = {
                'CXX_SOURCES': sources,
                'EXE': exe_name,
                'CFLAGS_EXTRAS': "%s %s -I%s" % (stdflag,
                                                 stdlibflag,
                                                 os.path.join(
                                                     os.environ["LLDB_SRC"],
                                                     "include")),
                'LD_EXTRAS': "-L%s -lliblldb" % lib_dir}
        else:
            d = {
                'CXX_SOURCES': sources,
                'EXE': exe_name,
                'CFLAGS_EXTRAS': "%s %s -I%s" % (stdflag,
                                                 stdlibflag,
                                                 os.path.join(
                                                     os.environ["LLDB_SRC"],
                                                     "include")),
                'LD_EXTRAS': "-L%s -llldb -Wl,-rpath,%s" % (lib_dir, lib_dir)}
        if self.TraceOn():
            print(
                "Building LLDB Driver (%s) from sources %s" %
                (exe_name, sources))

        self.buildDefault(dictionary=d)

    def buildLibrary(self, sources, lib_name):
        """Platform specific way to build a default library. """

        stdflag = self.getstdFlag()

        lib_dir = configuration.lldb_libs_dir
        if self.hasDarwinFramework():
            d = {'DYLIB_CXX_SOURCES': sources,
                 'DYLIB_NAME': lib_name,
                 'CFLAGS_EXTRAS': "%s -stdlib=libc++" % stdflag,
                 'FRAMEWORK_INCLUDES': "-F%s" % self.framework_dir,
                 'LD_EXTRAS': "%s -Wl,-rpath,%s -dynamiclib" % (self.lib_lldb, self.framework_dir),
                 }
        elif self.getPlatform() == 'windows':
            d = {
                'DYLIB_CXX_SOURCES': sources,
                'DYLIB_NAME': lib_name,
                'CFLAGS_EXTRAS': "%s -I%s " % (stdflag,
                                               os.path.join(
                                                   os.environ["LLDB_SRC"],
                                                   "include")),
                'LD_EXTRAS': "-shared -l%s\liblldb.lib" % lib_dir}
        else:
            d = {
                'DYLIB_CXX_SOURCES': sources,
                'DYLIB_NAME': lib_name,
                'CFLAGS_EXTRAS': "%s -I%s -fPIC" % (stdflag,
                                                    os.path.join(
                                                        os.environ["LLDB_SRC"],
                                                        "include")),
                'LD_EXTRAS': "-shared -L%s -llldb -Wl,-rpath,%s" % (lib_dir, lib_dir)}
        if self.TraceOn():
            print(
                "Building LLDB Library (%s) from sources %s" %
                (lib_name, sources))

        self.buildDefault(dictionary=d)

    def buildProgram(self, sources, exe_name):
        """ Platform specific way to build an executable from C/C++ sources. """
        d = {'CXX_SOURCES': sources,
             'EXE': exe_name}
        self.buildDefault(dictionary=d)

    def buildDefault(
            self,
            architecture=None,
            compiler=None,
            dictionary=None):
        """Platform specific way to build the default binaries."""
        testdir = self.mydir
        testname = self.getBuildDirBasename()

        if not architecture and configuration.arch:
            architecture = configuration.arch

        if self.getDebugInfo():
            raise Exception("buildDefault tests must set NO_DEBUG_INFO_TESTCASE")
        module = builder_module()
        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
        if not module.buildDefault(self, architecture, compiler,
                                   dictionary, testdir, testname):
            raise Exception("Don't know how to build default binary")

    def buildDsym(
            self,
            architecture=None,
            compiler=None,
            dictionary=None):
        """Platform specific way to build binaries with dsym info."""
        testdir = self.mydir
        testname = self.getBuildDirBasename()
        if self.getDebugInfo() != "dsym":
            raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")

        module = builder_module()
        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
        if not module.buildDsym(self, architecture, compiler,
                                dictionary, testdir, testname):
            raise Exception("Don't know how to build binary with dsym")

    def buildDwarf(
            self,
            architecture=None,
            compiler=None,
            dictionary=None):
        """Platform specific way to build binaries with dwarf maps."""
        testdir = self.mydir
        testname = self.getBuildDirBasename()
        if self.getDebugInfo() != "dwarf":
            raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")

        module = builder_module()
        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
        if not module.buildDwarf(self, architecture, compiler,
                                   dictionary, testdir, testname):
            raise Exception("Don't know how to build binary with dwarf")

    def buildDwo(
            self,
            architecture=None,
            compiler=None,
            dictionary=None):
        """Platform specific way to build binaries with dwarf maps."""
        testdir = self.mydir
        testname = self.getBuildDirBasename()
        if self.getDebugInfo() != "dwo":
            raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")

        module = builder_module()
        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
        if not module.buildDwo(self, architecture, compiler,
                                   dictionary, testdir, testname):
            raise Exception("Don't know how to build binary with dwo")

    def buildGModules(
            self,
            architecture=None,
            compiler=None,
            dictionary=None):
        """Platform specific way to build binaries with gmodules info."""
        testdir = self.mydir
        testname = self.getBuildDirBasename()
        if self.getDebugInfo() != "gmodules":
            raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")

        module = builder_module()
        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
        if not module.buildGModules(self, architecture, compiler,
                                    dictionary, testdir, testname):
            raise Exception("Don't know how to build binary with gmodules")

    def signBinary(self, binary_path):
        if sys.platform.startswith("darwin"):
            codesign_cmd = "codesign --force --sign \"%s\" %s" % (
                lldbtest_config.codesign_identity, binary_path)
            call(codesign_cmd, shell=True)

    def findBuiltClang(self):
        """Tries to find and use Clang from the build directory as the compiler (instead of the system compiler)."""
        paths_to_try = [
            "llvm-build/Release+Asserts/x86_64/bin/clang",
            "llvm-build/Debug+Asserts/x86_64/bin/clang",
            "llvm-build/Release/x86_64/bin/clang",
            "llvm-build/Debug/x86_64/bin/clang",
        ]
        lldb_root_path = os.path.join(
            os.path.dirname(__file__), "..", "..", "..", "..")
        for p in paths_to_try:
            path = os.path.join(lldb_root_path, p)
            if os.path.exists(path):
                return path

        # Tries to find clang at the same folder as the lldb
        lldb_dir = os.path.dirname(lldbtest_config.lldbExec)
        path = distutils.spawn.find_executable("clang", lldb_dir)
        if path is not None:
            return path

        return os.environ["CC"]


    def yaml2obj(self, yaml_path, obj_path):
        """
        Create an object file at the given path from a yaml file.

        Throws subprocess.CalledProcessError if the object could not be created.
        """
        yaml2obj_bin = configuration.get_yaml2obj_path()
        if not yaml2obj_bin:
            self.assertTrue(False, "No valid yaml2obj executable specified")
        command = [yaml2obj_bin, "-o=%s" % obj_path, yaml_path]
        system([command])

    def getBuildFlags(
            self,
            use_cpp11=True,
            use_libcxx=False,
            use_libstdcxx=False):
        """ Returns a dictionary (which can be provided to build* functions above) which
            contains OS-specific build flags.
        """
        cflags = ""
        ldflags = ""

        # On Mac OS X, unless specifically requested to use libstdc++, use
        # libc++
        if not use_libstdcxx and self.platformIsDarwin():
            use_libcxx = True

        if use_libcxx and self.libcxxPath:
            cflags += "-stdlib=libc++ "
            if self.libcxxPath:
                libcxxInclude = os.path.join(self.libcxxPath, "include")
                libcxxLib = os.path.join(self.libcxxPath, "lib")
                if os.path.isdir(libcxxInclude) and os.path.isdir(libcxxLib):
                    cflags += "-nostdinc++ -I%s -L%s -Wl,-rpath,%s " % (
                        libcxxInclude, libcxxLib, libcxxLib)

        if use_cpp11:
            cflags += "-std="
            if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
                cflags += "c++0x"
            else:
                cflags += "c++11"
        if self.platformIsDarwin() or self.getPlatform() == "freebsd":
            cflags += " -stdlib=libc++"
        elif self.getPlatform() == "openbsd":
            cflags += " -stdlib=libc++"
        elif self.getPlatform() == "netbsd":
            # NetBSD defaults to libc++
            pass
        elif "clang" in self.getCompiler():
            cflags += " -stdlib=libstdc++"

        return {'CFLAGS_EXTRAS': cflags,
                'LD_EXTRAS': ldflags,
                }

    def cleanup(self, dictionary=None):
        """Platform specific way to do cleanup after build."""
        module = builder_module()
        if not module.cleanup(self, dictionary):
            raise Exception(
                "Don't know how to do cleanup with dictionary: " +
                dictionary)

    def invoke(self, obj, name, trace=False):
        """Use reflection to call a method dynamically with no argument."""
        trace = (True if traceAlways else trace)

        method = getattr(obj, name)
        import inspect
        self.assertTrue(inspect.ismethod(method),
                        name + "is a method name of object: " + str(obj))
        result = method()
        with recording(self, trace) as sbuf:
            print(str(method) + ":", result, file=sbuf)
        return result

    def getLLDBLibraryEnvVal(self):
        """ Returns the path that the OS-specific library search environment variable
            (self.dylibPath) should be set to in order for a program to find the LLDB
            library. If an environment variable named self.dylibPath is already set,
            the new path is appended to it and returned.
        """
        existing_library_path = os.environ[
            self.dylibPath] if self.dylibPath in os.environ else None
        if existing_library_path:
            return "%s:%s" % (existing_library_path, configuration.lldb_libs_dir)
        if sys.platform.startswith("darwin") and configuration.lldb_framework_path:
            return configuration.lldb_framework_path
        return configuration.lldb_libs_dir

    def getLibcPlusPlusLibs(self):
        if self.getPlatform() in ('freebsd', 'linux', 'netbsd', 'openbsd'):
            return ['libc++.so.1']
        else:
            return ['libc++.1.dylib', 'libc++abi.']

    def run_platform_command(self, cmd):
        platform = self.dbg.GetSelectedPlatform()
        shell_command = lldb.SBPlatformShellCommand(cmd)
        err = platform.Run(shell_command)
        return (err, shell_command.GetStatus(), shell_command.GetOutput())

# Metaclass for TestBase to change the list of test metods when a new TestCase is loaded.
# We change the test methods to create a new test method for each test for each debug info we are
# testing. The name of the new test method will be '<original-name>_<debug-info>' and with adding
# the new test method we remove the old method at the same time. This functionality can be
# supressed by at test case level setting the class attribute NO_DEBUG_INFO_TESTCASE or at test
# level by using the decorator @no_debug_info_test.


class LLDBTestCaseFactory(type):

    def __new__(cls, name, bases, attrs):
        original_testcase = super(
            LLDBTestCaseFactory, cls).__new__(
            cls, name, bases, attrs)
        if original_testcase.NO_DEBUG_INFO_TESTCASE:
            return original_testcase

        newattrs = {}
        for attrname, attrvalue in attrs.items():
            if attrname.startswith("test") and not getattr(
                    attrvalue, "__no_debug_info_test__", False):

                # If any debug info categories were explicitly tagged, assume that list to be
                # authoritative.  If none were specified, try with all debug
                # info formats.
                all_dbginfo_categories = set(test_categories.debug_info_categories)
                categories = set(
                    getattr(
                        attrvalue,
                        "categories",
                        [])) & all_dbginfo_categories
                if not categories:
                    categories = all_dbginfo_categories

                for cat in categories:
                    @decorators.add_test_categories([cat])
                    @wraps(attrvalue)
                    def test_method(self, attrvalue=attrvalue):
                        return attrvalue(self)

                    method_name = attrname + "_" + cat
                    test_method.__name__ = method_name
                    test_method.debug_info = cat
                    newattrs[method_name] = test_method

            else:
                newattrs[attrname] = attrvalue
        return super(
            LLDBTestCaseFactory,
            cls).__new__(
            cls,
            name,
            bases,
            newattrs)

# Setup the metaclass for this class to change the list of the test
# methods when a new class is loaded


@add_metaclass(LLDBTestCaseFactory)
class TestBase(Base):
    """
    This abstract base class is meant to be subclassed.  It provides default
    implementations for setUpClass(), tearDownClass(), setUp(), and tearDown(),
    among other things.

    Important things for test class writers:

        - Overwrite the mydir class attribute, otherwise your test class won't
          run.  It specifies the relative directory to the top level 'test' so
          the test harness can change to the correct working directory before
          running your test.

        - The setUp method sets up things to facilitate subsequent interactions
          with the debugger as part of the test.  These include:
              - populate the test method name
              - create/get a debugger set with synchronous mode (self.dbg)
              - get the command interpreter from with the debugger (self.ci)
              - create a result object for use with the command interpreter
                (self.res)
              - plus other stuffs

        - The tearDown method tries to perform some necessary cleanup on behalf
          of the test to return the debugger to a good state for the next test.
          These include:
              - execute any tearDown hooks registered by the test method with
                TestBase.addTearDownHook(); examples can be found in
                settings/TestSettings.py
              - kill the inferior process associated with each target, if any,
                and, then delete the target from the debugger's target list
              - perform build cleanup before running the next test method in the
                same test class; examples of registering for this service can be
                found in types/TestIntegerTypes.py with the call:
                    - self.setTearDownCleanup(dictionary=d)

        - Similarly setUpClass and tearDownClass perform classwise setup and
          teardown fixtures.  The tearDownClass method invokes a default build
          cleanup for the entire test class;  also, subclasses can implement the
          classmethod classCleanup(cls) to perform special class cleanup action.

        - The instance methods runCmd and expect are used heavily by existing
          test cases to send a command to the command interpreter and to perform
          string/pattern matching on the output of such command execution.  The
          expect method also provides a mode to peform string/pattern matching
          without running a command.

        - The build methods buildDefault, buildDsym, and buildDwarf are used to
          build the binaries used during a particular test scenario.  A plugin
          should be provided for the sys.platform running the test suite.  The
          Mac OS X implementation is located in builders/darwin.py.
    """

    # Subclasses can set this to true (if they don't depend on debug info) to avoid running the
    # test multiple times with various debug info types.
    NO_DEBUG_INFO_TESTCASE = False

    # Maximum allowed attempts when launching the inferior process.
    # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
    maxLaunchCount = 1

    # Time to wait before the next launching attempt in second(s).
    # Can be overridden by the LLDB_TIME_WAIT_NEXT_LAUNCH environment variable.
    timeWaitNextLaunch = 1.0

    def generateSource(self, source):
        template = source + '.template'
        temp = os.path.join(self.getSourceDir(), template)
        with open(temp, 'r') as f:
            content = f.read()

        public_api_dir = os.path.join(
            os.environ["LLDB_SRC"], "include", "lldb", "API")

        # Look under the include/lldb/API directory and add #include statements
        # for all the SB API headers.
        public_headers = os.listdir(public_api_dir)
        # For different platforms, the include statement can vary.
        if self.hasDarwinFramework():
            include_stmt = "'#include <%s>' % os.path.join('LLDB', header)"
        else:
            include_stmt = "'#include <%s>' % os.path.join('" + public_api_dir + "', header)"
        list = [eval(include_stmt) for header in public_headers if (
            header.startswith("SB") and header.endswith(".h"))]
        includes = '\n'.join(list)
        new_content = content.replace('%include_SB_APIs%', includes)
        new_content = new_content.replace('%SOURCE_DIR%', self.getSourceDir())
        src = os.path.join(self.getBuildDir(), source)
        with open(src, 'w') as f:
            f.write(new_content)

        self.addTearDownHook(lambda: os.remove(src))

    def setUp(self):
        # Works with the test driver to conditionally skip tests via
        # decorators.
        Base.setUp(self)

        for s in self.setUpCommands():
            self.runCmd(s)

        if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
            self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])

        if "LLDB_TIME_WAIT_NEXT_LAUNCH" in os.environ:
            self.timeWaitNextLaunch = float(
                os.environ["LLDB_TIME_WAIT_NEXT_LAUNCH"])

        # We want our debugger to be synchronous.
        self.dbg.SetAsync(False)

        # Retrieve the associated command interpreter instance.
        self.ci = self.dbg.GetCommandInterpreter()
        if not self.ci:
            raise Exception('Could not get the command interpreter')

        # And the result object.
        self.res = lldb.SBCommandReturnObject()

    def registerSharedLibrariesWithTarget(self, target, shlibs):
        '''If we are remotely running the test suite, register the shared libraries with the target so they get uploaded, otherwise do nothing

        Any modules in the target that have their remote install file specification set will
        get uploaded to the remote host. This function registers the local copies of the
        shared libraries with the target and sets their remote install locations so they will
        be uploaded when the target is run.
        '''
        if not shlibs or not self.platformContext:
            return None

        shlib_environment_var = self.platformContext.shlib_environment_var
        shlib_prefix = self.platformContext.shlib_prefix
        shlib_extension = '.' + self.platformContext.shlib_extension

        dirs = []
        # Add any shared libraries to our target if remote so they get
        # uploaded into the working directory on the remote side
        for name in shlibs:
            # The path can be a full path to a shared library, or a make file name like "Foo" for
            # "libFoo.dylib" or "libFoo.so", or "Foo.so" for "Foo.so" or "libFoo.so", or just a
            # basename like "libFoo.so". So figure out which one it is and resolve the local copy
            # of the shared library accordingly
            if os.path.isfile(name):
                local_shlib_path = name  # name is the full path to the local shared library
            else:
                # Check relative names
                local_shlib_path = os.path.join(
                    self.getBuildDir(), shlib_prefix + name + shlib_extension)
                if not os.path.exists(local_shlib_path):
                    local_shlib_path = os.path.join(
                        self.getBuildDir(), name + shlib_extension)
                    if not os.path.exists(local_shlib_path):
                        local_shlib_path = os.path.join(self.getBuildDir(), name)

                # Make sure we found the local shared library in the above code
                self.assertTrue(os.path.exists(local_shlib_path))


            # Add the shared library to our target
            shlib_module = target.AddModule(local_shlib_path, None, None, None)
            if lldb.remote_platform:
                # We must set the remote install location if we want the shared library
                # to get uploaded to the remote target
                remote_shlib_path = lldbutil.append_to_process_working_directory(self,
                    os.path.basename(local_shlib_path))
                shlib_module.SetRemoteInstallFileSpec(
                    lldb.SBFileSpec(remote_shlib_path, False))
                dir_to_add = self.get_process_working_directory()
            else:
                dir_to_add = os.path.dirname(local_shlib_path)

            if dir_to_add not in dirs:
                dirs.append(dir_to_add)

        env_value = self.platformContext.shlib_path_separator.join(dirs)
        return ['%s=%s' % (shlib_environment_var, env_value)]

    def registerSanitizerLibrariesWithTarget(self, target):
        runtimes = []
        for m in target.module_iter():
            libspec = m.GetFileSpec()
            if "clang_rt" in libspec.GetFilename():
                runtimes.append(os.path.join(libspec.GetDirectory(),
                                             libspec.GetFilename()))
        return self.registerSharedLibrariesWithTarget(target, runtimes)

    # utility methods that tests can use to access the current objects
    def target(self):
        if not self.dbg:
            raise Exception('Invalid debugger instance')
        return self.dbg.GetSelectedTarget()

    def process(self):
        if not self.dbg:
            raise Exception('Invalid debugger instance')
        return self.dbg.GetSelectedTarget().GetProcess()

    def thread(self):
        if not self.dbg:
            raise Exception('Invalid debugger instance')
        return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread()

    def frame(self):
        if not self.dbg:
            raise Exception('Invalid debugger instance')
        return self.dbg.GetSelectedTarget().GetProcess(
        ).GetSelectedThread().GetSelectedFrame()

    def get_process_working_directory(self):
        '''Get the working directory that should be used when launching processes for local or remote processes.'''
        if lldb.remote_platform:
            # Remote tests set the platform working directory up in
            # TestBase.setUp()
            return lldb.remote_platform.GetWorkingDirectory()
        else:
            # local tests change directory into each test subdirectory
            return self.getBuildDir()

    def tearDown(self):
        # Ensure all the references to SB objects have gone away so that we can
        # be sure that all test-specific resources have been freed before we
        # attempt to delete the targets.
        gc.collect()

        # Delete the target(s) from the debugger as a general cleanup step.
        # This includes terminating the process for each target, if any.
        # We'd like to reuse the debugger for our next test without incurring
        # the initialization overhead.
        targets = []
        for target in self.dbg:
            if target:
                targets.append(target)
                process = target.GetProcess()
                if process:
                    rc = self.invoke(process, "Kill")
                    assert rc.Success()
        for target in targets:
            self.dbg.DeleteTarget(target)

        if not configuration.is_reproducer():
            # Assert that all targets are deleted.
            self.assertEqual(self.dbg.GetNumTargets(), 0)

        # Do this last, to make sure it's in reverse order from how we setup.
        Base.tearDown(self)

    def switch_to_thread_with_stop_reason(self, stop_reason):
        """
        Run the 'thread list' command, and select the thread with stop reason as
        'stop_reason'.  If no such thread exists, no select action is done.
        """
        from .lldbutil import stop_reason_to_str
        self.runCmd('thread list')
        output = self.res.GetOutput()
        thread_line_pattern = re.compile(
            "^[ *] thread #([0-9]+):.*stop reason = %s" %
            stop_reason_to_str(stop_reason))
        for line in output.splitlines():
            matched = thread_line_pattern.match(line)
            if matched:
                self.runCmd('thread select %s' % matched.group(1))

    def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False):
        """
        Ask the command interpreter to handle the command and then check its
        return status.
        """
        # Fail fast if 'cmd' is not meaningful.
        if cmd is None:
            raise Exception("Bad 'cmd' parameter encountered")

        trace = (True if traceAlways else trace)

        if cmd.startswith("target create "):
            cmd = cmd.replace("target create ", "file ")

        running = (cmd.startswith("run") or cmd.startswith("process launch"))

        for i in range(self.maxLaunchCount if running else 1):
            self.ci.HandleCommand(cmd, self.res, inHistory)

            with recording(self, trace) as sbuf:
                print("runCmd:", cmd, file=sbuf)
                if not check:
                    print("check of return status not required", file=sbuf)
                if self.res.Succeeded():
                    print("output:", self.res.GetOutput(), file=sbuf)
                else:
                    print("runCmd failed!", file=sbuf)
                    print(self.res.GetError(), file=sbuf)

            if self.res.Succeeded():
                break
            elif running:
                # For process launch, wait some time before possible next try.
                time.sleep(self.timeWaitNextLaunch)
                with recording(self, trace) as sbuf:
                    print("Command '" + cmd + "' failed!", file=sbuf)

        if check:
            output = ""
            if self.res.GetOutput():
                output += "\nCommand output:\n" + self.res.GetOutput()
            if self.res.GetError():
                output += "\nError output:\n" + self.res.GetError()
            if msg:
                msg += output
            if cmd:
                cmd += output
            self.assertTrue(self.res.Succeeded(),
                            msg if (msg) else CMD_MSG(cmd))

    def match(
            self,
            str,
            patterns,
            msg=None,
            trace=False,
            error=False,
            matching=True,
            exe=True):
        """run command in str, and match the result against regexp in patterns returning the match object for the first matching pattern

        Otherwise, all the arguments have the same meanings as for the expect function"""

        trace = (True if traceAlways else trace)

        if exe:
            # First run the command.  If we are expecting error, set check=False.
            # Pass the assert message along since it provides more semantic
            # info.
            self.runCmd(
                str,
                msg=msg,
                trace=(
                    True if trace else False),
                check=not error)

            # Then compare the output against expected strings.
            output = self.res.GetError() if error else self.res.GetOutput()

            # If error is True, the API client expects the command to fail!
            if error:
                self.assertFalse(self.res.Succeeded(),
                                 "Command '" + str + "' is expected to fail!")
        else:
            # No execution required, just compare str against the golden input.
            output = str
            with recording(self, trace) as sbuf:
                print("looking at:", output, file=sbuf)

        # The heading says either "Expecting" or "Not expecting".
        heading = "Expecting" if matching else "Not expecting"

        for pattern in patterns:
            # Match Objects always have a boolean value of True.
            match_object = re.search(pattern, output)
            matched = bool(match_object)
            with recording(self, trace) as sbuf:
                print("%s pattern: %s" % (heading, pattern), file=sbuf)
                print("Matched" if matched else "Not matched", file=sbuf)
            if matched:
                break

        self.assertTrue(matched if matching else not matched,
                        msg if msg else EXP_MSG(str, output, exe))

        return match_object

    def check_completion_with_desc(self, str_input, match_desc_pairs, enforce_order=False):
        """
        Checks that when the given input is completed at the given list of
        completions and descriptions is returned.
        :param str_input: The input that should be completed. The completion happens at the end of the string.
        :param match_desc_pairs: A list of pairs that indicate what completions have to be in the list of
                                 completions returned by LLDB. The first element of the pair is the completion
                                 string that LLDB should generate and the second element the description.
        :param enforce_order: True iff the order in which the completions are returned by LLDB
                              should match the order of the match_desc_pairs pairs.
        """
        interp = self.dbg.GetCommandInterpreter()
        match_strings = lldb.SBStringList()
        description_strings = lldb.SBStringList()
        num_matches = interp.HandleCompletionWithDescriptions(str_input, len(str_input), 0, -1, match_strings, description_strings)
        self.assertEqual(len(description_strings), len(match_strings))

        # The index of the last matched description in description_strings or
        # -1 if no description has been matched yet.
        last_found_index = -1
        out_of_order_errors = ""
        missing_pairs = []
        for pair in match_desc_pairs:
            found_pair = False
            for i in range(num_matches + 1):
                match_candidate = match_strings.GetStringAtIndex(i)
                description_candidate = description_strings.GetStringAtIndex(i)
                if match_candidate == pair[0] and description_candidate == pair[1]:
                    found_pair = True
                    if enforce_order and last_found_index > i:
                        new_err = ("Found completion " + pair[0] + " at index " +
                                  str(i) + " in returned completion list but " +
                                  "should have been after completion " +
                                  match_strings.GetStringAtIndex(last_found_index) +
                                  " (index:" + str(last_found_index) + ")\n")
                        out_of_order_errors += new_err
                    last_found_index = i
                    break
            if not found_pair:
                missing_pairs.append(pair)

        error_msg = ""
        got_failure = False
        if len(missing_pairs):
            got_failure = True
            error_msg += "Missing pairs:\n"
            for pair in missing_pairs:
                error_msg += " [" + pair[0] + ":" + pair[1] + "]\n"
        if len(out_of_order_errors):
            got_failure = True
            error_msg += out_of_order_errors
        if got_failure:
            error_msg += "Got the following " + str(num_matches) + " completions back:\n"
            for i in range(num_matches + 1):
                match_candidate = match_strings.GetStringAtIndex(i)
                description_candidate = description_strings.GetStringAtIndex(i)
                error_msg += "[" + match_candidate + ":" + description_candidate + "] index " + str(i) + "\n"
            self.assertFalse(got_failure, error_msg)

    def complete_exactly(self, str_input, patterns):
        self.complete_from_to(str_input, patterns, True)

    def complete_from_to(self, str_input, patterns, turn_off_re_match=False):
        """Test that the completion mechanism completes str_input to patterns,
        where patterns could be a pattern-string or a list of pattern-strings"""
        # Patterns should not be None in order to proceed.
        self.assertFalse(patterns is None)
        # And should be either a string or list of strings.  Check for list type
        # below, if not, make a list out of the singleton string.  If patterns
        # is not a string or not a list of strings, there'll be runtime errors
        # later on.
        if not isinstance(patterns, list):
            patterns = [patterns]

        interp = self.dbg.GetCommandInterpreter()
        match_strings = lldb.SBStringList()
        num_matches = interp.HandleCompletion(str_input, len(str_input), 0, -1, match_strings)
        common_match = match_strings.GetStringAtIndex(0)
        if num_matches == 0:
            compare_string = str_input
        else:
            if common_match != None and len(common_match) > 0:
                compare_string = str_input + common_match
            else:
                compare_string = ""
                for idx in range(1, num_matches+1):
                    compare_string += match_strings.GetStringAtIndex(idx) + "\n"

        for p in patterns:
            if turn_off_re_match:
                self.expect(
                    compare_string, msg=COMPLETION_MSG(
                        str_input, p, match_strings), exe=False, substrs=[p])
            else:
                self.expect(
                    compare_string, msg=COMPLETION_MSG(
                        str_input, p, match_strings), exe=False, patterns=[p])

    def completions_match(self, command, completions):
        """Checks that the completions for the given command are equal to the
        given list of completions"""
        interp = self.dbg.GetCommandInterpreter()
        match_strings = lldb.SBStringList()
        interp.HandleCompletion(command, len(command), 0, -1, match_strings)
        # match_strings is a 1-indexed list, so we have to slice...
        self.assertItemsEqual(completions, list(match_strings)[1:],
                              "List of returned completion is wrong")

    def completions_contain(self, command, completions):
        """Checks that the completions for the given command contain the given
        list of completions."""
        interp = self.dbg.GetCommandInterpreter()
        match_strings = lldb.SBStringList()
        interp.HandleCompletion(command, len(command), 0, -1, match_strings)
        for completion in completions:
            # match_strings is a 1-indexed list, so we have to slice...
            self.assertIn(completion, list(match_strings)[1:],
                          "Couldn't find expected completion")

    def filecheck(
            self,
            command,
            check_file,
            filecheck_options = '',
            expect_cmd_failure = False):
        # Run the command.
        self.runCmd(
                command,
                check=(not expect_cmd_failure),
                msg="FileCheck'ing result of `{0}`".format(command))

        self.assertTrue((not expect_cmd_failure) == self.res.Succeeded())

        # Get the error text if there was an error, and the regular text if not.
        output = self.res.GetOutput() if self.res.Succeeded() \
                else self.res.GetError()

        # Assemble the absolute path to the check file. As a convenience for
        # LLDB inline tests, assume that the check file is a relative path to
        # a file within the inline test directory.
        if check_file.endswith('.pyc'):
            check_file = check_file[:-1]
        check_file_abs = os.path.abspath(check_file)

        # Run FileCheck.
        filecheck_bin = configuration.get_filecheck_path()
        if not filecheck_bin:
            self.assertTrue(False, "No valid FileCheck executable specified")
        filecheck_args = [filecheck_bin, check_file_abs]
        if filecheck_options:
            filecheck_args.append(filecheck_options)
        subproc = Popen(filecheck_args, stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines = True)
        cmd_stdout, cmd_stderr = subproc.communicate(input=output)
        cmd_status = subproc.returncode

        filecheck_cmd = " ".join(filecheck_args)
        filecheck_trace = """
--- FileCheck trace (code={0}) ---
{1}

FileCheck input:
{2}

FileCheck output:
{3}
{4}
""".format(cmd_status, filecheck_cmd, output, cmd_stdout, cmd_stderr)

        trace = cmd_status != 0 or traceAlways
        with recording(self, trace) as sbuf:
            print(filecheck_trace, file=sbuf)

        self.assertTrue(cmd_status == 0)

    def expect(
            self,
            str,
            msg=None,
            patterns=None,
            startstr=None,
            endstr=None,
            substrs=None,
            trace=False,
            error=False,
            ordered=True,
            matching=True,
            exe=True,
            inHistory=False):
        """
        Similar to runCmd; with additional expect style output matching ability.

        Ask the command interpreter to handle the command and then check its
        return status.  The 'msg' parameter specifies an informational assert
        message.  We expect the output from running the command to start with
        'startstr', matches the substrings contained in 'substrs', and regexp
        matches the patterns contained in 'patterns'.

        When matching is true and ordered is true, which are both the default,
        the strings in the substrs array have to appear in the command output
        in the order in which they appear in the array.

        If the keyword argument error is set to True, it signifies that the API
        client is expecting the command to fail.  In this case, the error stream
        from running the command is retrieved and compared against the golden
        input, instead.

        If the keyword argument matching is set to False, it signifies that the API
        client is expecting the output of the command not to match the golden
        input.

        Finally, the required argument 'str' represents the lldb command to be
        sent to the command interpreter.  In case the keyword argument 'exe' is
        set to False, the 'str' is treated as a string to be matched/not-matched
        against the golden input.
        """
        # Catch cases where `expect` has been miscalled. Specifically, prevent
        # this easy to make mistake:
        #     self.expect("lldb command", "some substr")
        # The `msg` parameter is used only when a failed match occurs. A failed
        # match can only occur when one of `patterns`, `startstr`, `endstr`, or
        # `substrs` has been given. Thus, if a `msg` is given, it's an error to
        # not also provide one of the matcher parameters.
        if msg and not (patterns or startstr or endstr or substrs or error):
            assert False, "expect() missing a matcher argument"

        # Check `patterns` and `substrs` are not accidentally given as strings.
        assert not isinstance(patterns, six.string_types), \
            "patterns must be a collection of strings"
        assert not isinstance(substrs, six.string_types), \
            "substrs must be a collection of strings"

        trace = (True if traceAlways else trace)

        if exe:
            # First run the command.  If we are expecting error, set check=False.
            # Pass the assert message along since it provides more semantic
            # info.
            self.runCmd(
                str,
                msg=msg,
                trace=(
                    True if trace else False),
                check=not error,
                inHistory=inHistory)

            # Then compare the output against expected strings.
            output = self.res.GetError() if error else self.res.GetOutput()

            # If error is True, the API client expects the command to fail!
            if error:
                self.assertFalse(self.res.Succeeded(),
                                 "Command '" + str + "' is expected to fail!")
        else:
            # No execution required, just compare str against the golden input.
            if isinstance(str, lldb.SBCommandReturnObject):
                output = str.GetOutput()
            else:
                output = str
            with recording(self, trace) as sbuf:
                print("looking at:", output, file=sbuf)

        expecting_str = "Expecting" if matching else "Not expecting"
        def found_str(matched):
            return "was found" if matched else "was not found"

        # To be used as assert fail message and/or trace content
        log_lines = [
                "{}:".format("Ran command" if exe else "Checking string"),
                "\"{}\"".format(str),
                # Space out command and output
                "",
        ]
        if exe:
            # Newline before output to make large strings more readable
            log_lines.append("Got output:\n{}".format(output))

        # Assume that we start matched if we want a match
        # Meaning if you have no conditions, matching or
        # not matching will always pass
        matched = matching

        # We will stop checking on first failure
        if startstr:
            matched = output.startswith(startstr)
            log_lines.append("{} start string: \"{}\" ({})".format(
                    expecting_str, startstr, found_str(matched)))

        if endstr and matched == matching:
            matched = output.endswith(endstr)
            log_lines.append("{} end string: \"{}\" ({})".format(
                    expecting_str, endstr, found_str(matched)))

        if substrs and matched == matching:
            start = 0
            for substr in substrs:
                index = output[start:].find(substr)
                start = start + index if ordered and matching else 0
                matched = index != -1
                log_lines.append("{} sub string: \"{}\" ({})".format(
                        expecting_str, substr, found_str(matched)))

                if matched != matching:
                    break

        if patterns and matched == matching:
            for pattern in patterns:
                matched = re.search(pattern, output)

                pattern_line = "{} regex pattern: \"{}\" ({}".format(
                        expecting_str, pattern, found_str(matched))
                if matched:
                    pattern_line += ", matched \"{}\"".format(
                            matched.group(0))
                pattern_line += ")"
                log_lines.append(pattern_line)

                # Convert to bool because match objects
                # are True-ish but != True itself
                matched = bool(matched)
                if matched != matching:
                    break

        # If a check failed, add any extra assert message
        if msg is not None and matched != matching:
            log_lines.append(msg)

        log_msg = "\n".join(log_lines)
        with recording(self, trace) as sbuf:
            print(log_msg, file=sbuf)
        if matched != matching:
            self.fail(log_msg)

    def expect_expr(
            self,
            expr,
            result_summary=None,
            result_value=None,
            result_type=None,
            result_children=None
            ):
        """
        Evaluates the given expression and verifies the result.
        :param expr: The expression as a string.
        :param result_summary: The summary that the expression should have. None if the summary should not be checked.
        :param result_value: The value that the expression should have. None if the value should not be checked.
        :param result_type: The type that the expression result should have. None if the type should not be checked.
        :param result_children: The expected children of the expression result
                                as a list of ValueChecks. None if the children shouldn't be checked.
        """
        self.assertTrue(expr.strip() == expr, "Expression contains trailing/leading whitespace: '" + expr + "'")

        frame = self.frame()
        options = lldb.SBExpressionOptions()

        # Disable fix-its that tests don't pass by accident.
        options.SetAutoApplyFixIts(False)

        # Set the usual default options for normal expressions.
        options.SetIgnoreBreakpoints(True)

        if self.frame().IsValid():
            options.SetLanguage(frame.GuessLanguage())
            eval_result = self.frame().EvaluateExpression(expr, options)
        else:
            target = self.target()
            # If there is no selected target, run the expression in the dummy
            # target.
            if not target.IsValid():
                target = self.dbg.GetDummyTarget()
            eval_result = target.EvaluateExpression(expr, options)

        value_check = ValueCheck(type=result_type, value=result_value,
                                 summary=result_summary, children=result_children)
        value_check.check_value(self, eval_result, str(eval_result))
        return eval_result

    def expect_var_path(
            self,
            var_path,
            summary=None,
            value=None,
            type=None,
            children=None
            ):
        """
        Evaluates the given variable path and verifies the result.
        See also 'frame variable' and SBFrame.GetValueForVariablePath.
        :param var_path: The variable path as a string.
        :param summary: The summary that the variable should have. None if the summary should not be checked.
        :param value: The value that the variable should have. None if the value should not be checked.
        :param type: The type that the variable result should have. None if the type should not be checked.
        :param children: The expected children of the variable  as a list of ValueChecks.
                         None if the children shouldn't be checked.
        """
        self.assertTrue(var_path.strip() == var_path,
                        "Expression contains trailing/leading whitespace: '" + var_path + "'")

        frame = self.frame()
        eval_result = frame.GetValueForVariablePath(var_path)

        value_check = ValueCheck(type=type, value=value,
                                 summary=summary, children=children)
        value_check.check_value(self, eval_result, str(eval_result))
        return eval_result

    def build(
            self,
            architecture=None,
            compiler=None,
            dictionary=None):
        """Platform specific way to build the default binaries."""
        module = builder_module()

        if not architecture and configuration.arch:
            architecture = configuration.arch

        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
        if self.getDebugInfo() is None:
            return self.buildDefault(architecture, compiler, dictionary)
        elif self.getDebugInfo() == "dsym":
            return self.buildDsym(architecture, compiler, dictionary)
        elif self.getDebugInfo() == "dwarf":
            return self.buildDwarf(architecture, compiler, dictionary)
        elif self.getDebugInfo() == "dwo":
            return self.buildDwo(architecture, compiler, dictionary)
        elif self.getDebugInfo() == "gmodules":
            return self.buildGModules(architecture, compiler, dictionary)
        else:
            self.fail("Can't build for debug info: %s" % self.getDebugInfo())

    """Assert that an lldb.SBError is in the "success" state."""
    def assertSuccess(self, obj, msg=None):
        if not obj.Success():
            error = obj.GetCString()
            self.fail(self._formatMessage(msg,
                "'{}' is not success".format(error)))

    # =================================================
    # Misc. helper methods for debugging test execution
    # =================================================

    def DebugSBValue(self, val):
        """Debug print a SBValue object, if traceAlways is True."""
        from .lldbutil import value_type_to_str

        if not traceAlways:
            return

        err = sys.stderr
        err.write(val.GetName() + ":\n")
        err.write('\t' + "TypeName         -> " + val.GetTypeName() + '\n')
        err.write('\t' + "ByteSize         -> " +
                  str(val.GetByteSize()) + '\n')
        err.write('\t' + "NumChildren      -> " +
                  str(val.GetNumChildren()) + '\n')
        err.write('\t' + "Value            -> " + str(val.GetValue()) + '\n')
        err.write('\t' + "ValueAsUnsigned  -> " +
                  str(val.GetValueAsUnsigned()) + '\n')
        err.write(
            '\t' +
            "ValueType        -> " +
            value_type_to_str(
                val.GetValueType()) +
            '\n')
        err.write('\t' + "Summary          -> " + str(val.GetSummary()) + '\n')
        err.write('\t' + "IsPointerType    -> " +
                  str(val.TypeIsPointerType()) + '\n')
        err.write('\t' + "Location         -> " + val.GetLocation() + '\n')

    def DebugSBType(self, type):
        """Debug print a SBType object, if traceAlways is True."""
        if not traceAlways:
            return

        err = sys.stderr
        err.write(type.GetName() + ":\n")
        err.write('\t' + "ByteSize        -> " +
                  str(type.GetByteSize()) + '\n')
        err.write('\t' + "IsPointerType   -> " +
                  str(type.IsPointerType()) + '\n')
        err.write('\t' + "IsReferenceType -> " +
                  str(type.IsReferenceType()) + '\n')

    def DebugPExpect(self, child):
        """Debug the spwaned pexpect object."""
        if not traceAlways:
            return

        print(child)

    @classmethod
    def RemoveTempFile(cls, file):
        if os.path.exists(file):
            remove_file(file)

# On Windows, the first attempt to delete a recently-touched file can fail
# because of a race with antimalware scanners.  This function will detect a
# failure and retry.


def remove_file(file, num_retries=1, sleep_duration=0.5):
    for i in range(num_retries + 1):
        try:
            os.remove(file)
            return True
        except:
            time.sleep(sleep_duration)
            continue
    return False
