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