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