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