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' did not return successfully" message generator.'''
183    return "Command '%s' did not return successfully" % str
184
185
186def COMPLETION_MSG(str_before, str_after, completions):
187    '''A generic assertion failed 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' returned unexpected result" message generator if exe.
194    Otherwise, it generates "'%s' does not match expected result" message.'''
195
196    return "'%s' %s result, got '%s'" % (
197        str, 'returned unexpected' if exe else 'does not match expected', actual.strip())
198
199
200def SETTING_MSG(setting):
201    '''A generic "Value of setting '%s' is not correct" message generator.'''
202    return "Value of setting '%s' is not 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", errors='ignore')
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        self.lib_lldb = None
920        self.framework_dir = None
921        self.darwinWithFramework = False
922
923        if sys.platform.startswith("darwin") and configuration.lldb_framework_path:
924            framework = configuration.lldb_framework_path
925            lib = os.path.join(framework, 'LLDB')
926            if os.path.exists(lib):
927                self.framework_dir = os.path.dirname(framework)
928                self.lib_lldb = lib
929                self.darwinWithFramework = self.platformIsDarwin()
930
931        self.makeBuildDir()
932
933    def setAsync(self, value):
934        """ Sets async mode to True/False and ensures it is reset after the testcase completes."""
935        old_async = self.dbg.GetAsync()
936        self.dbg.SetAsync(value)
937        self.addTearDownHook(lambda: self.dbg.SetAsync(old_async))
938
939    def cleanupSubprocesses(self):
940        # Terminate subprocesses in reverse order from how they were created.
941        for p in reversed(self.subprocesses):
942            p.terminate()
943            del p
944        del self.subprocesses[:]
945
946    def spawnSubprocess(self, executable, args=[], install_remote=True):
947        """ Creates a subprocess.Popen object with the specified executable and arguments,
948            saves it in self.subprocesses, and returns the object.
949        """
950        proc = _RemoteProcess(
951            install_remote) if lldb.remote_platform else _LocalProcess(self.TraceOn())
952        proc.launch(executable, args)
953        self.subprocesses.append(proc)
954        return proc
955
956    def HideStdout(self):
957        """Hide output to stdout from the user.
958
959        During test execution, there might be cases where we don't want to show the
960        standard output to the user.  For example,
961
962            self.runCmd(r'''sc print("\n\n\tHello!\n")''')
963
964        tests whether command abbreviation for 'script' works or not.  There is no
965        need to show the 'Hello' output to the user as long as the 'script' command
966        succeeds and we are not in TraceOn() mode (see the '-t' option).
967
968        In this case, the test method calls self.HideStdout(self) to redirect the
969        sys.stdout to a null device, and restores the sys.stdout upon teardown.
970
971        Note that you should only call this method at most once during a test case
972        execution.  Any subsequent call has no effect at all."""
973        if self.sys_stdout_hidden:
974            return
975
976        self.sys_stdout_hidden = True
977        old_stdout = sys.stdout
978        sys.stdout = open(os.devnull, 'w')
979
980        def restore_stdout():
981            sys.stdout = old_stdout
982        self.addTearDownHook(restore_stdout)
983
984    # =======================================================================
985    # Methods for customized teardown cleanups as well as execution of hooks.
986    # =======================================================================
987
988    def setTearDownCleanup(self, dictionary=None):
989        """Register a cleanup action at tearDown() time with a dictionary"""
990        self.dict = dictionary
991        self.doTearDownCleanup = True
992
993    def addTearDownCleanup(self, dictionary):
994        """Add a cleanup action at tearDown() time with a dictionary"""
995        self.dicts.append(dictionary)
996        self.doTearDownCleanups = True
997
998    def addTearDownHook(self, hook):
999        """
1000        Add a function to be run during tearDown() time.
1001
1002        Hooks are executed in a first come first serve manner.
1003        """
1004        if six.callable(hook):
1005            with recording(self, traceAlways) as sbuf:
1006                print(
1007                    "Adding tearDown hook:",
1008                    getsource_if_available(hook),
1009                    file=sbuf)
1010            self.hooks.append(hook)
1011
1012        return self
1013
1014    def deletePexpectChild(self):
1015        # This is for the case of directly spawning 'lldb' and interacting with it
1016        # using pexpect.
1017        if self.child and self.child.isalive():
1018            import pexpect
1019            with recording(self, traceAlways) as sbuf:
1020                print("tearing down the child process....", file=sbuf)
1021            try:
1022                if self.child_in_script_interpreter:
1023                    self.child.sendline('quit()')
1024                    self.child.expect_exact(self.child_prompt)
1025                self.child.sendline(
1026                    'settings set interpreter.prompt-on-quit false')
1027                self.child.sendline('quit')
1028                self.child.expect(pexpect.EOF)
1029            except (ValueError, pexpect.ExceptionPexpect):
1030                # child is already terminated
1031                pass
1032            except OSError as exception:
1033                import errno
1034                if exception.errno != errno.EIO:
1035                    # unexpected error
1036                    raise
1037                # child is already terminated
1038            finally:
1039                # Give it one final blow to make sure the child is terminated.
1040                self.child.close()
1041
1042    def tearDown(self):
1043        """Fixture for unittest test case teardown."""
1044        self.deletePexpectChild()
1045
1046        # Check and run any hook functions.
1047        for hook in reversed(self.hooks):
1048            with recording(self, traceAlways) as sbuf:
1049                print(
1050                    "Executing tearDown hook:",
1051                    getsource_if_available(hook),
1052                    file=sbuf)
1053            if funcutils.requires_self(hook):
1054                hook(self)
1055            else:
1056                hook()  # try the plain call and hope it works
1057
1058        del self.hooks
1059
1060        # Perform registered teardown cleanup.
1061        if doCleanup and self.doTearDownCleanup:
1062            self.cleanup(dictionary=self.dict)
1063
1064        # In rare cases where there are multiple teardown cleanups added.
1065        if doCleanup and self.doTearDownCleanups:
1066            if self.dicts:
1067                for dict in reversed(self.dicts):
1068                    self.cleanup(dictionary=dict)
1069
1070        # Remove subprocesses created by the test.
1071        self.cleanupSubprocesses()
1072
1073        # This must be the last statement, otherwise teardown hooks or other
1074        # lines might depend on this still being active.
1075        lldb.SBDebugger.Destroy(self.dbg)
1076        del self.dbg
1077
1078        # All modules should be orphaned now so that they can be cleared from
1079        # the shared module cache.
1080        lldb.SBModule.GarbageCollectAllocatedModules()
1081
1082        # Modules are not orphaned during reproducer replay because they're
1083        # leaked on purpose.
1084        if not configuration.is_reproducer():
1085            # Assert that the global module cache is empty.
1086            self.assertEqual(lldb.SBModule.GetNumberAllocatedModules(), 0)
1087
1088
1089    # =========================================================
1090    # Various callbacks to allow introspection of test progress
1091    # =========================================================
1092
1093    def markError(self):
1094        """Callback invoked when an error (unexpected exception) errored."""
1095        self.__errored__ = True
1096        with recording(self, False) as sbuf:
1097            # False because there's no need to write "ERROR" to the stderr twice.
1098            # Once by the Python unittest framework, and a second time by us.
1099            print("ERROR", file=sbuf)
1100
1101    def markCleanupError(self):
1102        """Callback invoked when an error occurs while a test is cleaning up."""
1103        self.__cleanup_errored__ = True
1104        with recording(self, False) as sbuf:
1105            # False because there's no need to write "CLEANUP_ERROR" to the stderr twice.
1106            # Once by the Python unittest framework, and a second time by us.
1107            print("CLEANUP_ERROR", file=sbuf)
1108
1109    def markFailure(self):
1110        """Callback invoked when a failure (test assertion failure) occurred."""
1111        self.__failed__ = True
1112        with recording(self, False) as sbuf:
1113            # False because there's no need to write "FAIL" to the stderr twice.
1114            # Once by the Python unittest framework, and a second time by us.
1115            print("FAIL", file=sbuf)
1116
1117    def markExpectedFailure(self, err, bugnumber):
1118        """Callback invoked when an expected failure/error occurred."""
1119        self.__expected__ = True
1120        with recording(self, False) as sbuf:
1121            # False because there's no need to write "expected failure" to the
1122            # stderr twice.
1123            # Once by the Python unittest framework, and a second time by us.
1124            if bugnumber is None:
1125                print("expected failure", file=sbuf)
1126            else:
1127                print(
1128                    "expected failure (problem id:" + str(bugnumber) + ")",
1129                    file=sbuf)
1130
1131    def markSkippedTest(self):
1132        """Callback invoked when a test is skipped."""
1133        self.__skipped__ = True
1134        with recording(self, False) as sbuf:
1135            # False because there's no need to write "skipped test" to the
1136            # stderr twice.
1137            # Once by the Python unittest framework, and a second time by us.
1138            print("skipped test", file=sbuf)
1139
1140    def markUnexpectedSuccess(self, bugnumber):
1141        """Callback invoked when an unexpected success occurred."""
1142        self.__unexpected__ = True
1143        with recording(self, False) as sbuf:
1144            # False because there's no need to write "unexpected success" to the
1145            # stderr twice.
1146            # Once by the Python unittest framework, and a second time by us.
1147            if bugnumber is None:
1148                print("unexpected success", file=sbuf)
1149            else:
1150                print(
1151                    "unexpected success (problem id:" + str(bugnumber) + ")",
1152                    file=sbuf)
1153
1154    def getRerunArgs(self):
1155        return " -f %s.%s" % (self.__class__.__name__, self._testMethodName)
1156
1157    def getLogBasenameForCurrentTest(self, prefix=None):
1158        """
1159        returns a partial path that can be used as the beginning of the name of multiple
1160        log files pertaining to this test
1161
1162        <session-dir>/<arch>-<compiler>-<test-file>.<test-class>.<test-method>
1163        """
1164        dname = os.path.join(configuration.test_src_root,
1165                             os.environ["LLDB_SESSION_DIRNAME"])
1166        if not os.path.isdir(dname):
1167            os.mkdir(dname)
1168
1169        components = []
1170        if prefix is not None:
1171            components.append(prefix)
1172        for c in configuration.session_file_format:
1173            if c == 'f':
1174                components.append(self.__class__.__module__)
1175            elif c == 'n':
1176                components.append(self.__class__.__name__)
1177            elif c == 'c':
1178                compiler = self.getCompiler()
1179
1180                if compiler[1] == ':':
1181                    compiler = compiler[2:]
1182                if os.path.altsep is not None:
1183                    compiler = compiler.replace(os.path.altsep, os.path.sep)
1184                path_components = [x for x in compiler.split(os.path.sep) if x != ""]
1185
1186                # Add at most 4 path components to avoid generating very long
1187                # filenames
1188                components.extend(path_components[-4:])
1189            elif c == 'a':
1190                components.append(self.getArchitecture())
1191            elif c == 'm':
1192                components.append(self.testMethodName)
1193        fname = "-".join(components)
1194
1195        return os.path.join(dname, fname)
1196
1197    def dumpSessionInfo(self):
1198        """
1199        Dump the debugger interactions leading to a test error/failure.  This
1200        allows for more convenient postmortem analysis.
1201
1202        See also LLDBTestResult (dotest.py) which is a singlton class derived
1203        from TextTestResult and overwrites addError, addFailure, and
1204        addExpectedFailure methods to allow us to to mark the test instance as
1205        such.
1206        """
1207
1208        # We are here because self.tearDown() detected that this test instance
1209        # either errored or failed.  The lldb.test_result singleton contains
1210        # two lists (errors and failures) which get populated by the unittest
1211        # framework.  Look over there for stack trace information.
1212        #
1213        # The lists contain 2-tuples of TestCase instances and strings holding
1214        # formatted tracebacks.
1215        #
1216        # See http://docs.python.org/library/unittest.html#unittest.TestResult.
1217
1218        # output tracebacks into session
1219        pairs = []
1220        if self.__errored__:
1221            pairs = configuration.test_result.errors
1222            prefix = 'Error'
1223        elif self.__cleanup_errored__:
1224            pairs = configuration.test_result.cleanup_errors
1225            prefix = 'CleanupError'
1226        elif self.__failed__:
1227            pairs = configuration.test_result.failures
1228            prefix = 'Failure'
1229        elif self.__expected__:
1230            pairs = configuration.test_result.expectedFailures
1231            prefix = 'ExpectedFailure'
1232        elif self.__skipped__:
1233            prefix = 'SkippedTest'
1234        elif self.__unexpected__:
1235            prefix = 'UnexpectedSuccess'
1236        else:
1237            prefix = 'Success'
1238
1239        if not self.__unexpected__ and not self.__skipped__:
1240            for test, traceback in pairs:
1241                if test is self:
1242                    print(traceback, file=self.session)
1243
1244        import datetime
1245        print(
1246            "Session info generated @",
1247            datetime.datetime.now().ctime(),
1248            file=self.session)
1249        self.session.close()
1250        del self.session
1251
1252        # process the log files
1253        if prefix != 'Success' or lldbtest_config.log_success:
1254            # keep all log files, rename them to include prefix
1255            src_log_basename = self.getLogBasenameForCurrentTest(None)
1256            dst_log_basename = self.getLogBasenameForCurrentTest(prefix)
1257            for src in self.log_files:
1258                if os.path.isfile(src):
1259                    dst = src.replace(src_log_basename, dst_log_basename)
1260                    if os.name == "nt" and os.path.isfile(dst):
1261                        # On Windows, renaming a -> b will throw an exception if
1262                        # b exists.  On non-Windows platforms it silently
1263                        # replaces the destination.  Ultimately this means that
1264                        # atomic renames are not guaranteed to be possible on
1265                        # Windows, but we need this to work anyway, so just
1266                        # remove the destination first if it already exists.
1267                        remove_file(dst)
1268
1269                    lldbutil.mkdir_p(os.path.dirname(dst))
1270                    os.rename(src, dst)
1271        else:
1272            # success!  (and we don't want log files) delete log files
1273            for log_file in self.log_files:
1274                if os.path.isfile(log_file):
1275                    remove_file(log_file)
1276
1277    # ====================================================
1278    # Config. methods supported through a plugin interface
1279    # (enables reading of the current test configuration)
1280    # ====================================================
1281
1282    def isMIPS(self):
1283        """Returns true if the architecture is MIPS."""
1284        arch = self.getArchitecture()
1285        if re.match("mips", arch):
1286            return True
1287        return False
1288
1289    def isPPC64le(self):
1290        """Returns true if the architecture is PPC64LE."""
1291        arch = self.getArchitecture()
1292        if re.match("powerpc64le", arch):
1293            return True
1294        return False
1295
1296    def isAArch64SVE(self):
1297        triple = self.dbg.GetSelectedPlatform().GetTriple()
1298
1299        # TODO other platforms, please implement this function
1300        if not re.match(".*-.*-linux", triple):
1301            return False
1302
1303        # Need to do something different for non-Linux/Android targets
1304        cpuinfo_path = self.getBuildArtifact("cpuinfo")
1305        if configuration.lldb_platform_name:
1306            self.runCmd('platform get-file "/proc/cpuinfo" ' + cpuinfo_path)
1307        else:
1308            cpuinfo_path = "/proc/cpuinfo"
1309
1310        try:
1311            f = open(cpuinfo_path, 'r')
1312            cpuinfo = f.read()
1313            f.close()
1314        except:
1315            return False
1316
1317        return " sve " in cpuinfo
1318
1319    def getArchitecture(self):
1320        """Returns the architecture in effect the test suite is running with."""
1321        module = builder_module()
1322        arch = module.getArchitecture()
1323        if arch == 'amd64':
1324            arch = 'x86_64'
1325        if arch in ['armv7l', 'armv8l'] :
1326            arch = 'arm'
1327        return arch
1328
1329    def getLldbArchitecture(self):
1330        """Returns the architecture of the lldb binary."""
1331        if not hasattr(self, 'lldbArchitecture'):
1332
1333            # spawn local process
1334            command = [
1335                lldbtest_config.lldbExec,
1336                "-o",
1337                "file " + lldbtest_config.lldbExec,
1338                "-o",
1339                "quit"
1340            ]
1341
1342            output = check_output(command)
1343            str = output.decode("utf-8")
1344
1345            for line in str.splitlines():
1346                m = re.search(
1347                    "Current executable set to '.*' \\((.*)\\)\\.", line)
1348                if m:
1349                    self.lldbArchitecture = m.group(1)
1350                    break
1351
1352        return self.lldbArchitecture
1353
1354    def getCompiler(self):
1355        """Returns the compiler in effect the test suite is running with."""
1356        module = builder_module()
1357        return module.getCompiler()
1358
1359    def getCompilerBinary(self):
1360        """Returns the compiler binary the test suite is running with."""
1361        return self.getCompiler().split()[0]
1362
1363    def getCompilerVersion(self):
1364        """ Returns a string that represents the compiler version.
1365            Supports: llvm, clang.
1366        """
1367        compiler = self.getCompilerBinary()
1368        version_output = system([[compiler, "--version"]])
1369        for line in version_output.split(os.linesep):
1370            m = re.search('version ([0-9.]+)', line)
1371            if m:
1372                return m.group(1)
1373        return 'unknown'
1374
1375    def getDwarfVersion(self):
1376        """ Returns the dwarf version generated by clang or '0'. """
1377        if configuration.dwarf_version:
1378            return str(configuration.dwarf_version)
1379        if 'clang' in self.getCompiler():
1380            try:
1381                driver_output = check_output(
1382                    [self.getCompiler()] + '-g -c -x c - -o - -###'.split(),
1383                    stderr=STDOUT)
1384                driver_output = driver_output.decode("utf-8")
1385                for line in driver_output.split(os.linesep):
1386                    m = re.search('dwarf-version=([0-9])', line)
1387                    if m:
1388                        return m.group(1)
1389            except: pass
1390        return '0'
1391
1392    def platformIsDarwin(self):
1393        """Returns true if the OS triple for the selected platform is any valid apple OS"""
1394        return lldbplatformutil.platformIsDarwin()
1395
1396    def hasDarwinFramework(self):
1397        return self.darwinWithFramework
1398
1399    def getPlatform(self):
1400        """Returns the target platform the test suite is running on."""
1401        return lldbplatformutil.getPlatform()
1402
1403    def isIntelCompiler(self):
1404        """ Returns true if using an Intel (ICC) compiler, false otherwise. """
1405        return any([x in self.getCompiler() for x in ["icc", "icpc", "icl"]])
1406
1407    def expectedCompilerVersion(self, compiler_version):
1408        """Returns True iff compiler_version[1] matches the current compiler version.
1409           Use compiler_version[0] to specify the operator used to determine if a match has occurred.
1410           Any operator other than the following defaults to an equality test:
1411             '>', '>=', "=>", '<', '<=', '=<', '!=', "!" or 'not'
1412
1413           If the current compiler version cannot be determined, we assume it is close to the top
1414           of trunk, so any less-than or equal-to comparisons will return False, and any
1415           greater-than or not-equal-to comparisons will return True.
1416        """
1417        if compiler_version is None:
1418            return True
1419        operator = str(compiler_version[0])
1420        version = compiler_version[1]
1421
1422        if version is None:
1423            return True
1424
1425        test_compiler_version = self.getCompilerVersion()
1426        if test_compiler_version == 'unknown':
1427            # Assume the compiler version is at or near the top of trunk.
1428            return operator in ['>', '>=', '!', '!=', 'not']
1429
1430        if operator == '>':
1431            return LooseVersion(test_compiler_version) > LooseVersion(version)
1432        if operator == '>=' or operator == '=>':
1433            return LooseVersion(test_compiler_version) >= LooseVersion(version)
1434        if operator == '<':
1435            return LooseVersion(test_compiler_version) < LooseVersion(version)
1436        if operator == '<=' or operator == '=<':
1437            return LooseVersion(test_compiler_version) <= LooseVersion(version)
1438        if operator == '!=' or operator == '!' or operator == 'not':
1439            return str(version) not in str(test_compiler_version)
1440        return str(version) in str(test_compiler_version)
1441
1442    def expectedCompiler(self, compilers):
1443        """Returns True iff any element of compilers is a sub-string of the current compiler."""
1444        if (compilers is None):
1445            return True
1446
1447        for compiler in compilers:
1448            if compiler in self.getCompiler():
1449                return True
1450
1451        return False
1452
1453    def expectedArch(self, archs):
1454        """Returns True iff any element of archs is a sub-string of the current architecture."""
1455        if (archs is None):
1456            return True
1457
1458        for arch in archs:
1459            if arch in self.getArchitecture():
1460                return True
1461
1462        return False
1463
1464    def getRunOptions(self):
1465        """Command line option for -A and -C to run this test again, called from
1466        self.dumpSessionInfo()."""
1467        arch = self.getArchitecture()
1468        comp = self.getCompiler()
1469        option_str = ""
1470        if arch:
1471            option_str = "-A " + arch
1472        if comp:
1473            option_str += " -C " + comp
1474        return option_str
1475
1476    def getDebugInfo(self):
1477        method = getattr(self, self.testMethodName)
1478        return getattr(method, "debug_info", None)
1479
1480    # ==================================================
1481    # Build methods supported through a plugin interface
1482    # ==================================================
1483
1484    def getstdlibFlag(self):
1485        """ Returns the proper -stdlib flag, or empty if not required."""
1486        if self.platformIsDarwin() or self.getPlatform() == "freebsd" or self.getPlatform() == "openbsd":
1487            stdlibflag = "-stdlib=libc++"
1488        else:  # this includes NetBSD
1489            stdlibflag = ""
1490        return stdlibflag
1491
1492    def getstdFlag(self):
1493        """ Returns the proper stdflag. """
1494        if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
1495            stdflag = "-std=c++0x"
1496        else:
1497            stdflag = "-std=c++11"
1498        return stdflag
1499
1500    def buildDriver(self, sources, exe_name):
1501        """ Platform-specific way to build a program that links with LLDB (via the liblldb.so
1502            or LLDB.framework).
1503        """
1504        stdflag = self.getstdFlag()
1505        stdlibflag = self.getstdlibFlag()
1506
1507        lib_dir = configuration.lldb_libs_dir
1508        if self.hasDarwinFramework():
1509            d = {'CXX_SOURCES': sources,
1510                 'EXE': exe_name,
1511                 'CFLAGS_EXTRAS': "%s %s" % (stdflag, stdlibflag),
1512                 'FRAMEWORK_INCLUDES': "-F%s" % self.framework_dir,
1513                 'LD_EXTRAS': "%s -Wl,-rpath,%s" % (self.lib_lldb, self.framework_dir),
1514                 }
1515        elif sys.platform.startswith('win'):
1516            d = {
1517                'CXX_SOURCES': sources,
1518                'EXE': exe_name,
1519                'CFLAGS_EXTRAS': "%s %s -I%s" % (stdflag,
1520                                                 stdlibflag,
1521                                                 os.path.join(
1522                                                     os.environ["LLDB_SRC"],
1523                                                     "include")),
1524                'LD_EXTRAS': "-L%s -lliblldb" % lib_dir}
1525        else:
1526            d = {
1527                'CXX_SOURCES': sources,
1528                'EXE': exe_name,
1529                'CFLAGS_EXTRAS': "%s %s -I%s" % (stdflag,
1530                                                 stdlibflag,
1531                                                 os.path.join(
1532                                                     os.environ["LLDB_SRC"],
1533                                                     "include")),
1534                'LD_EXTRAS': "-L%s -llldb -Wl,-rpath,%s" % (lib_dir, lib_dir)}
1535        if self.TraceOn():
1536            print(
1537                "Building LLDB Driver (%s) from sources %s" %
1538                (exe_name, sources))
1539
1540        self.buildDefault(dictionary=d)
1541
1542    def buildLibrary(self, sources, lib_name):
1543        """Platform specific way to build a default library. """
1544
1545        stdflag = self.getstdFlag()
1546
1547        lib_dir = configuration.lldb_libs_dir
1548        if self.hasDarwinFramework():
1549            d = {'DYLIB_CXX_SOURCES': sources,
1550                 'DYLIB_NAME': lib_name,
1551                 'CFLAGS_EXTRAS': "%s -stdlib=libc++" % stdflag,
1552                 'FRAMEWORK_INCLUDES': "-F%s" % self.framework_dir,
1553                 'LD_EXTRAS': "%s -Wl,-rpath,%s -dynamiclib" % (self.lib_lldb, self.framework_dir),
1554                 }
1555        elif self.getPlatform() == 'windows':
1556            d = {
1557                'DYLIB_CXX_SOURCES': sources,
1558                'DYLIB_NAME': lib_name,
1559                'CFLAGS_EXTRAS': "%s -I%s " % (stdflag,
1560                                               os.path.join(
1561                                                   os.environ["LLDB_SRC"],
1562                                                   "include")),
1563                'LD_EXTRAS': "-shared -l%s\liblldb.lib" % lib_dir}
1564        else:
1565            d = {
1566                'DYLIB_CXX_SOURCES': sources,
1567                'DYLIB_NAME': lib_name,
1568                'CFLAGS_EXTRAS': "%s -I%s -fPIC" % (stdflag,
1569                                                    os.path.join(
1570                                                        os.environ["LLDB_SRC"],
1571                                                        "include")),
1572                'LD_EXTRAS': "-shared -L%s -llldb -Wl,-rpath,%s" % (lib_dir, lib_dir)}
1573        if self.TraceOn():
1574            print(
1575                "Building LLDB Library (%s) from sources %s" %
1576                (lib_name, sources))
1577
1578        self.buildDefault(dictionary=d)
1579
1580    def buildProgram(self, sources, exe_name):
1581        """ Platform specific way to build an executable from C/C++ sources. """
1582        d = {'CXX_SOURCES': sources,
1583             'EXE': exe_name}
1584        self.buildDefault(dictionary=d)
1585
1586    def buildDefault(
1587            self,
1588            architecture=None,
1589            compiler=None,
1590            dictionary=None):
1591        """Platform specific way to build the default binaries."""
1592        testdir = self.mydir
1593        testname = self.getBuildDirBasename()
1594        if self.getDebugInfo():
1595            raise Exception("buildDefault tests must set NO_DEBUG_INFO_TESTCASE")
1596        module = builder_module()
1597        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1598        if not module.buildDefault(self, architecture, compiler,
1599                                   dictionary, testdir, testname):
1600            raise Exception("Don't know how to build default binary")
1601
1602    def buildDsym(
1603            self,
1604            architecture=None,
1605            compiler=None,
1606            dictionary=None):
1607        """Platform specific way to build binaries with dsym info."""
1608        testdir = self.mydir
1609        testname = self.getBuildDirBasename()
1610        if self.getDebugInfo() != "dsym":
1611            raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")
1612
1613        module = builder_module()
1614        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1615        if not module.buildDsym(self, architecture, compiler,
1616                                dictionary, testdir, testname):
1617            raise Exception("Don't know how to build binary with dsym")
1618
1619    def buildDwarf(
1620            self,
1621            architecture=None,
1622            compiler=None,
1623            dictionary=None):
1624        """Platform specific way to build binaries with dwarf maps."""
1625        testdir = self.mydir
1626        testname = self.getBuildDirBasename()
1627        if self.getDebugInfo() != "dwarf":
1628            raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")
1629
1630        module = builder_module()
1631        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1632        if not module.buildDwarf(self, architecture, compiler,
1633                                   dictionary, testdir, testname):
1634            raise Exception("Don't know how to build binary with dwarf")
1635
1636    def buildDwo(
1637            self,
1638            architecture=None,
1639            compiler=None,
1640            dictionary=None):
1641        """Platform specific way to build binaries with dwarf maps."""
1642        testdir = self.mydir
1643        testname = self.getBuildDirBasename()
1644        if self.getDebugInfo() != "dwo":
1645            raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")
1646
1647        module = builder_module()
1648        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1649        if not module.buildDwo(self, architecture, compiler,
1650                                   dictionary, testdir, testname):
1651            raise Exception("Don't know how to build binary with dwo")
1652
1653    def buildGModules(
1654            self,
1655            architecture=None,
1656            compiler=None,
1657            dictionary=None):
1658        """Platform specific way to build binaries with gmodules info."""
1659        testdir = self.mydir
1660        testname = self.getBuildDirBasename()
1661        if self.getDebugInfo() != "gmodules":
1662            raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")
1663
1664        module = builder_module()
1665        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1666        if not module.buildGModules(self, architecture, compiler,
1667                                    dictionary, testdir, testname):
1668            raise Exception("Don't know how to build binary with gmodules")
1669
1670    def signBinary(self, binary_path):
1671        if sys.platform.startswith("darwin"):
1672            codesign_cmd = "codesign --force --sign \"%s\" %s" % (
1673                lldbtest_config.codesign_identity, binary_path)
1674            call(codesign_cmd, shell=True)
1675
1676    def findBuiltClang(self):
1677        """Tries to find and use Clang from the build directory as the compiler (instead of the system compiler)."""
1678        paths_to_try = [
1679            "llvm-build/Release+Asserts/x86_64/bin/clang",
1680            "llvm-build/Debug+Asserts/x86_64/bin/clang",
1681            "llvm-build/Release/x86_64/bin/clang",
1682            "llvm-build/Debug/x86_64/bin/clang",
1683        ]
1684        lldb_root_path = os.path.join(
1685            os.path.dirname(__file__), "..", "..", "..", "..")
1686        for p in paths_to_try:
1687            path = os.path.join(lldb_root_path, p)
1688            if os.path.exists(path):
1689                return path
1690
1691        # Tries to find clang at the same folder as the lldb
1692        lldb_dir = os.path.dirname(lldbtest_config.lldbExec)
1693        path = distutils.spawn.find_executable("clang", lldb_dir)
1694        if path is not None:
1695            return path
1696
1697        return os.environ["CC"]
1698
1699
1700    def yaml2obj(self, yaml_path, obj_path):
1701        """
1702        Create an object file at the given path from a yaml file.
1703
1704        Throws subprocess.CalledProcessError if the object could not be created.
1705        """
1706        yaml2obj_bin = configuration.get_yaml2obj_path()
1707        if not yaml2obj_bin:
1708            self.assertTrue(False, "No valid yaml2obj executable specified")
1709        command = [yaml2obj_bin, "-o=%s" % obj_path, yaml_path]
1710        system([command])
1711
1712    def getBuildFlags(
1713            self,
1714            use_cpp11=True,
1715            use_libcxx=False,
1716            use_libstdcxx=False):
1717        """ Returns a dictionary (which can be provided to build* functions above) which
1718            contains OS-specific build flags.
1719        """
1720        cflags = ""
1721        ldflags = ""
1722
1723        # On Mac OS X, unless specifically requested to use libstdc++, use
1724        # libc++
1725        if not use_libstdcxx and self.platformIsDarwin():
1726            use_libcxx = True
1727
1728        if use_libcxx and self.libcxxPath:
1729            cflags += "-stdlib=libc++ "
1730            if self.libcxxPath:
1731                libcxxInclude = os.path.join(self.libcxxPath, "include")
1732                libcxxLib = os.path.join(self.libcxxPath, "lib")
1733                if os.path.isdir(libcxxInclude) and os.path.isdir(libcxxLib):
1734                    cflags += "-nostdinc++ -I%s -L%s -Wl,-rpath,%s " % (
1735                        libcxxInclude, libcxxLib, libcxxLib)
1736
1737        if use_cpp11:
1738            cflags += "-std="
1739            if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
1740                cflags += "c++0x"
1741            else:
1742                cflags += "c++11"
1743        if self.platformIsDarwin() or self.getPlatform() == "freebsd":
1744            cflags += " -stdlib=libc++"
1745        elif self.getPlatform() == "openbsd":
1746            cflags += " -stdlib=libc++"
1747        elif self.getPlatform() == "netbsd":
1748            # NetBSD defaults to libc++
1749            pass
1750        elif "clang" in self.getCompiler():
1751            cflags += " -stdlib=libstdc++"
1752
1753        return {'CFLAGS_EXTRAS': cflags,
1754                'LD_EXTRAS': ldflags,
1755                }
1756
1757    def cleanup(self, dictionary=None):
1758        """Platform specific way to do cleanup after build."""
1759        module = builder_module()
1760        if not module.cleanup(self, dictionary):
1761            raise Exception(
1762                "Don't know how to do cleanup with dictionary: " +
1763                dictionary)
1764
1765    def getLLDBLibraryEnvVal(self):
1766        """ Returns the path that the OS-specific library search environment variable
1767            (self.dylibPath) should be set to in order for a program to find the LLDB
1768            library. If an environment variable named self.dylibPath is already set,
1769            the new path is appended to it and returned.
1770        """
1771        existing_library_path = os.environ[
1772            self.dylibPath] if self.dylibPath in os.environ else None
1773        if existing_library_path:
1774            return "%s:%s" % (existing_library_path, configuration.lldb_libs_dir)
1775        if sys.platform.startswith("darwin") and configuration.lldb_framework_path:
1776            return configuration.lldb_framework_path
1777        return configuration.lldb_libs_dir
1778
1779    def getLibcPlusPlusLibs(self):
1780        if self.getPlatform() in ('freebsd', 'linux', 'netbsd', 'openbsd'):
1781            return ['libc++.so.1']
1782        else:
1783            return ['libc++.1.dylib', 'libc++abi.']
1784
1785# Metaclass for TestBase to change the list of test metods when a new TestCase is loaded.
1786# We change the test methods to create a new test method for each test for each debug info we are
1787# testing. The name of the new test method will be '<original-name>_<debug-info>' and with adding
1788# the new test method we remove the old method at the same time. This functionality can be
1789# supressed by at test case level setting the class attribute NO_DEBUG_INFO_TESTCASE or at test
1790# level by using the decorator @no_debug_info_test.
1791
1792
1793class LLDBTestCaseFactory(type):
1794
1795    def __new__(cls, name, bases, attrs):
1796        original_testcase = super(
1797            LLDBTestCaseFactory, cls).__new__(
1798            cls, name, bases, attrs)
1799        if original_testcase.NO_DEBUG_INFO_TESTCASE:
1800            return original_testcase
1801
1802        newattrs = {}
1803        for attrname, attrvalue in attrs.items():
1804            if attrname.startswith("test") and not getattr(
1805                    attrvalue, "__no_debug_info_test__", False):
1806
1807                # If any debug info categories were explicitly tagged, assume that list to be
1808                # authoritative.  If none were specified, try with all debug
1809                # info formats.
1810                all_dbginfo_categories = set(test_categories.debug_info_categories)
1811                categories = set(
1812                    getattr(
1813                        attrvalue,
1814                        "categories",
1815                        [])) & all_dbginfo_categories
1816                if not categories:
1817                    categories = all_dbginfo_categories
1818
1819                for cat in categories:
1820                    @decorators.add_test_categories([cat])
1821                    @wraps(attrvalue)
1822                    def test_method(self, attrvalue=attrvalue):
1823                        return attrvalue(self)
1824
1825                    method_name = attrname + "_" + cat
1826                    test_method.__name__ = method_name
1827                    test_method.debug_info = cat
1828                    newattrs[method_name] = test_method
1829
1830            else:
1831                newattrs[attrname] = attrvalue
1832        return super(
1833            LLDBTestCaseFactory,
1834            cls).__new__(
1835            cls,
1836            name,
1837            bases,
1838            newattrs)
1839
1840# Setup the metaclass for this class to change the list of the test
1841# methods when a new class is loaded
1842
1843
1844@add_metaclass(LLDBTestCaseFactory)
1845class TestBase(Base):
1846    """
1847    This abstract base class is meant to be subclassed.  It provides default
1848    implementations for setUpClass(), tearDownClass(), setUp(), and tearDown(),
1849    among other things.
1850
1851    Important things for test class writers:
1852
1853        - Overwrite the mydir class attribute, otherwise your test class won't
1854          run.  It specifies the relative directory to the top level 'test' so
1855          the test harness can change to the correct working directory before
1856          running your test.
1857
1858        - The setUp method sets up things to facilitate subsequent interactions
1859          with the debugger as part of the test.  These include:
1860              - populate the test method name
1861              - create/get a debugger set with synchronous mode (self.dbg)
1862              - get the command interpreter from with the debugger (self.ci)
1863              - create a result object for use with the command interpreter
1864                (self.res)
1865              - plus other stuffs
1866
1867        - The tearDown method tries to perform some necessary cleanup on behalf
1868          of the test to return the debugger to a good state for the next test.
1869          These include:
1870              - execute any tearDown hooks registered by the test method with
1871                TestBase.addTearDownHook(); examples can be found in
1872                settings/TestSettings.py
1873              - kill the inferior process associated with each target, if any,
1874                and, then delete the target from the debugger's target list
1875              - perform build cleanup before running the next test method in the
1876                same test class; examples of registering for this service can be
1877                found in types/TestIntegerTypes.py with the call:
1878                    - self.setTearDownCleanup(dictionary=d)
1879
1880        - Similarly setUpClass and tearDownClass perform classwise setup and
1881          teardown fixtures.  The tearDownClass method invokes a default build
1882          cleanup for the entire test class;  also, subclasses can implement the
1883          classmethod classCleanup(cls) to perform special class cleanup action.
1884
1885        - The instance methods runCmd and expect are used heavily by existing
1886          test cases to send a command to the command interpreter and to perform
1887          string/pattern matching on the output of such command execution.  The
1888          expect method also provides a mode to peform string/pattern matching
1889          without running a command.
1890
1891        - The build methods buildDefault, buildDsym, and buildDwarf are used to
1892          build the binaries used during a particular test scenario.  A plugin
1893          should be provided for the sys.platform running the test suite.  The
1894          Mac OS X implementation is located in builders/darwin.py.
1895    """
1896
1897    # Subclasses can set this to true (if they don't depend on debug info) to avoid running the
1898    # test multiple times with various debug info types.
1899    NO_DEBUG_INFO_TESTCASE = False
1900
1901    # Maximum allowed attempts when launching the inferior process.
1902    # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
1903    maxLaunchCount = 1
1904
1905    # Time to wait before the next launching attempt in second(s).
1906    # Can be overridden by the LLDB_TIME_WAIT_NEXT_LAUNCH environment variable.
1907    timeWaitNextLaunch = 1.0
1908
1909    def generateSource(self, source):
1910        template = source + '.template'
1911        temp = os.path.join(self.getSourceDir(), template)
1912        with open(temp, 'r') as f:
1913            content = f.read()
1914
1915        public_api_dir = os.path.join(
1916            os.environ["LLDB_SRC"], "include", "lldb", "API")
1917
1918        # Look under the include/lldb/API directory and add #include statements
1919        # for all the SB API headers.
1920        public_headers = os.listdir(public_api_dir)
1921        # For different platforms, the include statement can vary.
1922        if self.hasDarwinFramework():
1923            include_stmt = "'#include <%s>' % os.path.join('LLDB', header)"
1924        else:
1925            include_stmt = "'#include <%s>' % os.path.join('" + public_api_dir + "', header)"
1926        list = [eval(include_stmt) for header in public_headers if (
1927            header.startswith("SB") and header.endswith(".h"))]
1928        includes = '\n'.join(list)
1929        new_content = content.replace('%include_SB_APIs%', includes)
1930        src = os.path.join(self.getBuildDir(), source)
1931        with open(src, 'w') as f:
1932            f.write(new_content)
1933
1934        self.addTearDownHook(lambda: os.remove(src))
1935
1936    def setUp(self):
1937        # Works with the test driver to conditionally skip tests via
1938        # decorators.
1939        Base.setUp(self)
1940
1941        for s in self.setUpCommands():
1942            self.runCmd(s)
1943
1944        if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
1945            self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])
1946
1947        if "LLDB_TIME_WAIT_NEXT_LAUNCH" in os.environ:
1948            self.timeWaitNextLaunch = float(
1949                os.environ["LLDB_TIME_WAIT_NEXT_LAUNCH"])
1950
1951        # We want our debugger to be synchronous.
1952        self.dbg.SetAsync(False)
1953
1954        # Retrieve the associated command interpreter instance.
1955        self.ci = self.dbg.GetCommandInterpreter()
1956        if not self.ci:
1957            raise Exception('Could not get the command interpreter')
1958
1959        # And the result object.
1960        self.res = lldb.SBCommandReturnObject()
1961
1962    def registerSharedLibrariesWithTarget(self, target, shlibs):
1963        '''If we are remotely running the test suite, register the shared libraries with the target so they get uploaded, otherwise do nothing
1964
1965        Any modules in the target that have their remote install file specification set will
1966        get uploaded to the remote host. This function registers the local copies of the
1967        shared libraries with the target and sets their remote install locations so they will
1968        be uploaded when the target is run.
1969        '''
1970        if not shlibs or not self.platformContext:
1971            return None
1972
1973        shlib_environment_var = self.platformContext.shlib_environment_var
1974        shlib_prefix = self.platformContext.shlib_prefix
1975        shlib_extension = '.' + self.platformContext.shlib_extension
1976
1977        dirs = []
1978        # Add any shared libraries to our target if remote so they get
1979        # uploaded into the working directory on the remote side
1980        for name in shlibs:
1981            # The path can be a full path to a shared library, or a make file name like "Foo" for
1982            # "libFoo.dylib" or "libFoo.so", or "Foo.so" for "Foo.so" or "libFoo.so", or just a
1983            # basename like "libFoo.so". So figure out which one it is and resolve the local copy
1984            # of the shared library accordingly
1985            if os.path.isfile(name):
1986                local_shlib_path = name  # name is the full path to the local shared library
1987            else:
1988                # Check relative names
1989                local_shlib_path = os.path.join(
1990                    self.getBuildDir(), shlib_prefix + name + shlib_extension)
1991                if not os.path.exists(local_shlib_path):
1992                    local_shlib_path = os.path.join(
1993                        self.getBuildDir(), name + shlib_extension)
1994                    if not os.path.exists(local_shlib_path):
1995                        local_shlib_path = os.path.join(self.getBuildDir(), name)
1996
1997                # Make sure we found the local shared library in the above code
1998                self.assertTrue(os.path.exists(local_shlib_path))
1999
2000
2001            # Add the shared library to our target
2002            shlib_module = target.AddModule(local_shlib_path, None, None, None)
2003            if lldb.remote_platform:
2004                # We must set the remote install location if we want the shared library
2005                # to get uploaded to the remote target
2006                remote_shlib_path = lldbutil.append_to_process_working_directory(self,
2007                    os.path.basename(local_shlib_path))
2008                shlib_module.SetRemoteInstallFileSpec(
2009                    lldb.SBFileSpec(remote_shlib_path, False))
2010                dir_to_add = self.get_process_working_directory()
2011            else:
2012                dir_to_add = os.path.dirname(local_shlib_path)
2013
2014            if dir_to_add not in dirs:
2015                dirs.append(dir_to_add)
2016
2017        env_value = self.platformContext.shlib_path_separator.join(dirs)
2018        return ['%s=%s' % (shlib_environment_var, env_value)]
2019
2020    def registerSanitizerLibrariesWithTarget(self, target):
2021        runtimes = []
2022        for m in target.module_iter():
2023            libspec = m.GetFileSpec()
2024            if "clang_rt" in libspec.GetFilename():
2025                runtimes.append(os.path.join(libspec.GetDirectory(),
2026                                             libspec.GetFilename()))
2027        return self.registerSharedLibrariesWithTarget(target, runtimes)
2028
2029    # utility methods that tests can use to access the current objects
2030    def target(self):
2031        if not self.dbg:
2032            raise Exception('Invalid debugger instance')
2033        return self.dbg.GetSelectedTarget()
2034
2035    def process(self):
2036        if not self.dbg:
2037            raise Exception('Invalid debugger instance')
2038        return self.dbg.GetSelectedTarget().GetProcess()
2039
2040    def thread(self):
2041        if not self.dbg:
2042            raise Exception('Invalid debugger instance')
2043        return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread()
2044
2045    def frame(self):
2046        if not self.dbg:
2047            raise Exception('Invalid debugger instance')
2048        return self.dbg.GetSelectedTarget().GetProcess(
2049        ).GetSelectedThread().GetSelectedFrame()
2050
2051    def get_process_working_directory(self):
2052        '''Get the working directory that should be used when launching processes for local or remote processes.'''
2053        if lldb.remote_platform:
2054            # Remote tests set the platform working directory up in
2055            # TestBase.setUp()
2056            return lldb.remote_platform.GetWorkingDirectory()
2057        else:
2058            # local tests change directory into each test subdirectory
2059            return self.getBuildDir()
2060
2061    def tearDown(self):
2062        # Ensure all the references to SB objects have gone away so that we can
2063        # be sure that all test-specific resources have been freed before we
2064        # attempt to delete the targets.
2065        gc.collect()
2066
2067        # Delete the target(s) from the debugger as a general cleanup step.
2068        # This includes terminating the process for each target, if any.
2069        # We'd like to reuse the debugger for our next test without incurring
2070        # the initialization overhead.
2071        targets = []
2072        for target in self.dbg:
2073            if target:
2074                targets.append(target)
2075                process = target.GetProcess()
2076                if process:
2077                    rc = self.invoke(process, "Kill")
2078                    assert rc.Success()
2079        for target in targets:
2080            self.dbg.DeleteTarget(target)
2081
2082        if not configuration.is_reproducer():
2083            # Assert that all targets are deleted.
2084            self.assertEqual(self.dbg.GetNumTargets(), 0)
2085
2086        # Do this last, to make sure it's in reverse order from how we setup.
2087        Base.tearDown(self)
2088
2089    def switch_to_thread_with_stop_reason(self, stop_reason):
2090        """
2091        Run the 'thread list' command, and select the thread with stop reason as
2092        'stop_reason'.  If no such thread exists, no select action is done.
2093        """
2094        from .lldbutil import stop_reason_to_str
2095        self.runCmd('thread list')
2096        output = self.res.GetOutput()
2097        thread_line_pattern = re.compile(
2098            "^[ *] thread #([0-9]+):.*stop reason = %s" %
2099            stop_reason_to_str(stop_reason))
2100        for line in output.splitlines():
2101            matched = thread_line_pattern.match(line)
2102            if matched:
2103                self.runCmd('thread select %s' % matched.group(1))
2104
2105    def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False):
2106        """
2107        Ask the command interpreter to handle the command and then check its
2108        return status.
2109        """
2110        # Fail fast if 'cmd' is not meaningful.
2111        if not cmd or len(cmd) == 0:
2112            raise Exception("Bad 'cmd' parameter encountered")
2113
2114        trace = (True if traceAlways else trace)
2115
2116        if cmd.startswith("target create "):
2117            cmd = cmd.replace("target create ", "file ")
2118
2119        running = (cmd.startswith("run") or cmd.startswith("process launch"))
2120
2121        for i in range(self.maxLaunchCount if running else 1):
2122            self.ci.HandleCommand(cmd, self.res, inHistory)
2123
2124            with recording(self, trace) as sbuf:
2125                print("runCmd:", cmd, file=sbuf)
2126                if not check:
2127                    print("check of return status not required", file=sbuf)
2128                if self.res.Succeeded():
2129                    print("output:", self.res.GetOutput(), file=sbuf)
2130                else:
2131                    print("runCmd failed!", file=sbuf)
2132                    print(self.res.GetError(), file=sbuf)
2133
2134            if self.res.Succeeded():
2135                break
2136            elif running:
2137                # For process launch, wait some time before possible next try.
2138                time.sleep(self.timeWaitNextLaunch)
2139                with recording(self, trace) as sbuf:
2140                    print("Command '" + cmd + "' failed!", file=sbuf)
2141
2142        if check:
2143            output = ""
2144            if self.res.GetOutput():
2145                output += "\nCommand output:\n" + self.res.GetOutput()
2146            if self.res.GetError():
2147                output += "\nError output:\n" + self.res.GetError()
2148            if msg:
2149                msg += output
2150            if cmd:
2151                cmd += output
2152            self.assertTrue(self.res.Succeeded(),
2153                            msg if (msg) else CMD_MSG(cmd))
2154
2155    def match(
2156            self,
2157            str,
2158            patterns,
2159            msg=None,
2160            trace=False,
2161            error=False,
2162            matching=True,
2163            exe=True):
2164        """run command in str, and match the result against regexp in patterns returning the match object for the first matching pattern
2165
2166        Otherwise, all the arguments have the same meanings as for the expect function"""
2167
2168        trace = (True if traceAlways else trace)
2169
2170        if exe:
2171            # First run the command.  If we are expecting error, set check=False.
2172            # Pass the assert message along since it provides more semantic
2173            # info.
2174            self.runCmd(
2175                str,
2176                msg=msg,
2177                trace=(
2178                    True if trace else False),
2179                check=not error)
2180
2181            # Then compare the output against expected strings.
2182            output = self.res.GetError() if error else self.res.GetOutput()
2183
2184            # If error is True, the API client expects the command to fail!
2185            if error:
2186                self.assertFalse(self.res.Succeeded(),
2187                                 "Command '" + str + "' is expected to fail!")
2188        else:
2189            # No execution required, just compare str against the golden input.
2190            output = str
2191            with recording(self, trace) as sbuf:
2192                print("looking at:", output, file=sbuf)
2193
2194        # The heading says either "Expecting" or "Not expecting".
2195        heading = "Expecting" if matching else "Not expecting"
2196
2197        for pattern in patterns:
2198            # Match Objects always have a boolean value of True.
2199            match_object = re.search(pattern, output)
2200            matched = bool(match_object)
2201            with recording(self, trace) as sbuf:
2202                print("%s pattern: %s" % (heading, pattern), file=sbuf)
2203                print("Matched" if matched else "Not matched", file=sbuf)
2204            if matched:
2205                break
2206
2207        self.assertTrue(matched if matching else not matched,
2208                        msg if msg else EXP_MSG(str, output, exe))
2209
2210        return match_object
2211
2212    def check_completion_with_desc(self, str_input, match_desc_pairs, enforce_order=False):
2213        """
2214        Checks that when the given input is completed at the given list of
2215        completions and descriptions is returned.
2216        :param str_input: The input that should be completed. The completion happens at the end of the string.
2217        :param match_desc_pairs: A list of pairs that indicate what completions have to be in the list of
2218                                 completions returned by LLDB. The first element of the pair is the completion
2219                                 string that LLDB should generate and the second element the description.
2220        :param enforce_order: True iff the order in which the completions are returned by LLDB
2221                              should match the order of the match_desc_pairs pairs.
2222        """
2223        interp = self.dbg.GetCommandInterpreter()
2224        match_strings = lldb.SBStringList()
2225        description_strings = lldb.SBStringList()
2226        num_matches = interp.HandleCompletionWithDescriptions(str_input, len(str_input), 0, -1, match_strings, description_strings)
2227        self.assertEqual(len(description_strings), len(match_strings))
2228
2229        # The index of the last matched description in description_strings or
2230        # -1 if no description has been matched yet.
2231        last_found_index = -1
2232        out_of_order_errors = ""
2233        missing_pairs = []
2234        for pair in match_desc_pairs:
2235            found_pair = False
2236            for i in range(num_matches + 1):
2237                match_candidate = match_strings.GetStringAtIndex(i)
2238                description_candidate = description_strings.GetStringAtIndex(i)
2239                if match_candidate == pair[0] and description_candidate == pair[1]:
2240                    found_pair = True
2241                    if enforce_order and last_found_index > i:
2242                        new_err = ("Found completion " + pair[0] + " at index " +
2243                                  str(i) + " in returned completion list but " +
2244                                  "should have been after completion " +
2245                                  match_strings.GetStringAtIndex(last_found_index) +
2246                                  " (index:" + str(last_found_index) + ")\n")
2247                        out_of_order_errors += new_err
2248                    last_found_index = i
2249                    break
2250            if not found_pair:
2251                missing_pairs.append(pair)
2252
2253        error_msg = ""
2254        got_failure = False
2255        if len(missing_pairs):
2256            got_failure = True
2257            error_msg += "Missing pairs:\n"
2258            for pair in missing_pairs:
2259                error_msg += " [" + pair[0] + ":" + pair[1] + "]\n"
2260        if len(out_of_order_errors):
2261            got_failure = True
2262            error_msg += out_of_order_errors
2263        if got_failure:
2264            error_msg += "Got the following " + str(num_matches) + " completions back:\n"
2265            for i in range(num_matches + 1):
2266                match_candidate = match_strings.GetStringAtIndex(i)
2267                description_candidate = description_strings.GetStringAtIndex(i)
2268                error_msg += "[" + match_candidate + ":" + description_candidate + "] index " + str(i) + "\n"
2269            self.assertFalse(got_failure, error_msg)
2270
2271    def complete_exactly(self, str_input, patterns):
2272        self.complete_from_to(str_input, patterns, True)
2273
2274    def complete_from_to(self, str_input, patterns, turn_off_re_match=False):
2275        """Test that the completion mechanism completes str_input to patterns,
2276        where patterns could be a pattern-string or a list of pattern-strings"""
2277        # Patterns should not be None in order to proceed.
2278        self.assertFalse(patterns is None)
2279        # And should be either a string or list of strings.  Check for list type
2280        # below, if not, make a list out of the singleton string.  If patterns
2281        # is not a string or not a list of strings, there'll be runtime errors
2282        # later on.
2283        if not isinstance(patterns, list):
2284            patterns = [patterns]
2285
2286        interp = self.dbg.GetCommandInterpreter()
2287        match_strings = lldb.SBStringList()
2288        num_matches = interp.HandleCompletion(str_input, len(str_input), 0, -1, match_strings)
2289        common_match = match_strings.GetStringAtIndex(0)
2290        if num_matches == 0:
2291            compare_string = str_input
2292        else:
2293            if common_match != None and len(common_match) > 0:
2294                compare_string = str_input + common_match
2295            else:
2296                compare_string = ""
2297                for idx in range(1, num_matches+1):
2298                    compare_string += match_strings.GetStringAtIndex(idx) + "\n"
2299
2300        for p in patterns:
2301            if turn_off_re_match:
2302                self.expect(
2303                    compare_string, msg=COMPLETION_MSG(
2304                        str_input, p, match_strings), exe=False, substrs=[p])
2305            else:
2306                self.expect(
2307                    compare_string, msg=COMPLETION_MSG(
2308                        str_input, p, match_strings), exe=False, patterns=[p])
2309
2310    def completions_match(self, command, completions):
2311        """Checks that the completions for the given command are equal to the
2312        given list of completions"""
2313        interp = self.dbg.GetCommandInterpreter()
2314        match_strings = lldb.SBStringList()
2315        interp.HandleCompletion(command, len(command), 0, -1, match_strings)
2316        # match_strings is a 1-indexed list, so we have to slice...
2317        self.assertItemsEqual(completions, list(match_strings)[1:],
2318                              "List of returned completion is wrong")
2319
2320    def completions_contain(self, command, completions):
2321        """Checks that the completions for the given command contain the given
2322        list of completions."""
2323        interp = self.dbg.GetCommandInterpreter()
2324        match_strings = lldb.SBStringList()
2325        interp.HandleCompletion(command, len(command), 0, -1, match_strings)
2326        for completion in completions:
2327            # match_strings is a 1-indexed list, so we have to slice...
2328            self.assertIn(completion, list(match_strings)[1:],
2329                          "Couldn't find expected completion")
2330
2331    def filecheck(
2332            self,
2333            command,
2334            check_file,
2335            filecheck_options = '',
2336            expect_cmd_failure = False):
2337        # Run the command.
2338        self.runCmd(
2339                command,
2340                check=(not expect_cmd_failure),
2341                msg="FileCheck'ing result of `{0}`".format(command))
2342
2343        self.assertTrue((not expect_cmd_failure) == self.res.Succeeded())
2344
2345        # Get the error text if there was an error, and the regular text if not.
2346        output = self.res.GetOutput() if self.res.Succeeded() \
2347                else self.res.GetError()
2348
2349        # Assemble the absolute path to the check file. As a convenience for
2350        # LLDB inline tests, assume that the check file is a relative path to
2351        # a file within the inline test directory.
2352        if check_file.endswith('.pyc'):
2353            check_file = check_file[:-1]
2354        check_file_abs = os.path.abspath(check_file)
2355
2356        # Run FileCheck.
2357        filecheck_bin = configuration.get_filecheck_path()
2358        if not filecheck_bin:
2359            self.assertTrue(False, "No valid FileCheck executable specified")
2360        filecheck_args = [filecheck_bin, check_file_abs]
2361        if filecheck_options:
2362            filecheck_args.append(filecheck_options)
2363        subproc = Popen(filecheck_args, stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines = True)
2364        cmd_stdout, cmd_stderr = subproc.communicate(input=output)
2365        cmd_status = subproc.returncode
2366
2367        filecheck_cmd = " ".join(filecheck_args)
2368        filecheck_trace = """
2369--- FileCheck trace (code={0}) ---
2370{1}
2371
2372FileCheck input:
2373{2}
2374
2375FileCheck output:
2376{3}
2377{4}
2378""".format(cmd_status, filecheck_cmd, output, cmd_stdout, cmd_stderr)
2379
2380        trace = cmd_status != 0 or traceAlways
2381        with recording(self, trace) as sbuf:
2382            print(filecheck_trace, file=sbuf)
2383
2384        self.assertTrue(cmd_status == 0)
2385
2386    def expect(
2387            self,
2388            str,
2389            msg=None,
2390            patterns=None,
2391            startstr=None,
2392            endstr=None,
2393            substrs=None,
2394            trace=False,
2395            error=False,
2396            ordered=True,
2397            matching=True,
2398            exe=True,
2399            inHistory=False):
2400        """
2401        Similar to runCmd; with additional expect style output matching ability.
2402
2403        Ask the command interpreter to handle the command and then check its
2404        return status.  The 'msg' parameter specifies an informational assert
2405        message.  We expect the output from running the command to start with
2406        'startstr', matches the substrings contained in 'substrs', and regexp
2407        matches the patterns contained in 'patterns'.
2408
2409        When matching is true and ordered is true, which are both the default,
2410        the strings in the substrs array have to appear in the command output
2411        in the order in which they appear in the array.
2412
2413        If the keyword argument error is set to True, it signifies that the API
2414        client is expecting the command to fail.  In this case, the error stream
2415        from running the command is retrieved and compared against the golden
2416        input, instead.
2417
2418        If the keyword argument matching is set to False, it signifies that the API
2419        client is expecting the output of the command not to match the golden
2420        input.
2421
2422        Finally, the required argument 'str' represents the lldb command to be
2423        sent to the command interpreter.  In case the keyword argument 'exe' is
2424        set to False, the 'str' is treated as a string to be matched/not-matched
2425        against the golden input.
2426        """
2427        # Catch cases where `expect` has been miscalled. Specifically, prevent
2428        # this easy to make mistake:
2429        #     self.expect("lldb command", "some substr")
2430        # The `msg` parameter is used only when a failed match occurs. A failed
2431        # match can only occur when one of `patterns`, `startstr`, `endstr`, or
2432        # `substrs` has been given. Thus, if a `msg` is given, it's an error to
2433        # not also provide one of the matcher parameters.
2434        if msg and not (patterns or startstr or endstr or substrs or error):
2435            assert False, "expect() missing a matcher argument"
2436
2437        # Check `patterns` and `substrs` are not accidentally given as strings.
2438        assert not isinstance(patterns, six.string_types), \
2439            "patterns must be a collection of strings"
2440        assert not isinstance(substrs, six.string_types), \
2441            "substrs must be a collection of strings"
2442
2443        trace = (True if traceAlways else trace)
2444
2445        if exe:
2446            # First run the command.  If we are expecting error, set check=False.
2447            # Pass the assert message along since it provides more semantic
2448            # info.
2449            self.runCmd(
2450                str,
2451                msg=msg,
2452                trace=(
2453                    True if trace else False),
2454                check=not error,
2455                inHistory=inHistory)
2456
2457            # Then compare the output against expected strings.
2458            output = self.res.GetError() if error else self.res.GetOutput()
2459
2460            # If error is True, the API client expects the command to fail!
2461            if error:
2462                self.assertFalse(self.res.Succeeded(),
2463                                 "Command '" + str + "' is expected to fail!")
2464        else:
2465            # No execution required, just compare str against the golden input.
2466            if isinstance(str, lldb.SBCommandReturnObject):
2467                output = str.GetOutput()
2468            else:
2469                output = str
2470            with recording(self, trace) as sbuf:
2471                print("looking at:", output, file=sbuf)
2472
2473        expecting_str = "Expecting" if matching else "Not expecting"
2474        def found_str(matched):
2475            return "was found" if matched else "was not found"
2476
2477        # To be used as assert fail message and/or trace content
2478        log_lines = [
2479                "{}:".format("Ran command" if exe else "Checking string"),
2480                "\"{}\"".format(str),
2481                # Space out command and output
2482                "",
2483        ]
2484        if exe:
2485            # Newline before output to make large strings more readable
2486            log_lines.append("Got output:\n{}".format(output))
2487
2488        # Assume that we start matched if we want a match
2489        # Meaning if you have no conditions, matching or
2490        # not matching will always pass
2491        matched = matching
2492
2493        # We will stop checking on first failure
2494        if startstr:
2495            matched = output.startswith(startstr)
2496            log_lines.append("{} start string: \"{}\" ({})".format(
2497                    expecting_str, startstr, found_str(matched)))
2498
2499        if endstr and matched == matching:
2500            matched = output.endswith(endstr)
2501            log_lines.append("{} end string: \"{}\" ({})".format(
2502                    expecting_str, endstr, found_str(matched)))
2503
2504        if substrs and matched == matching:
2505            start = 0
2506            for substr in substrs:
2507                index = output[start:].find(substr)
2508                start = start + index if ordered and matching else 0
2509                matched = index != -1
2510                log_lines.append("{} sub string: \"{}\" ({})".format(
2511                        expecting_str, substr, found_str(matched)))
2512
2513                if matched != matching:
2514                    break
2515
2516        if patterns and matched == matching:
2517            for pattern in patterns:
2518                matched = re.search(pattern, output)
2519
2520                pattern_line = "{} regex pattern: \"{}\" ({}".format(
2521                        expecting_str, pattern, found_str(matched))
2522                if matched:
2523                    pattern_line += ", matched \"{}\"".format(
2524                            matched.group(0))
2525                pattern_line += ")"
2526                log_lines.append(pattern_line)
2527
2528                # Convert to bool because match objects
2529                # are True-ish but != True itself
2530                matched = bool(matched)
2531                if matched != matching:
2532                    break
2533
2534        # If a check failed, add any extra assert message
2535        if msg is not None and matched != matching:
2536            log_lines.append(msg)
2537
2538        log_msg = "\n".join(log_lines)
2539        with recording(self, trace) as sbuf:
2540            print(log_msg, file=sbuf)
2541        if matched != matching:
2542            self.fail(log_msg)
2543
2544    def expect_expr(
2545            self,
2546            expr,
2547            result_summary=None,
2548            result_value=None,
2549            result_type=None,
2550            result_children=None
2551            ):
2552        """
2553        Evaluates the given expression and verifies the result.
2554        :param expr: The expression as a string.
2555        :param result_summary: The summary that the expression should have. None if the summary should not be checked.
2556        :param result_value: The value that the expression should have. None if the value should not be checked.
2557        :param result_type: The type that the expression result should have. None if the type should not be checked.
2558        :param result_children: The expected children of the expression result
2559                                as a list of ValueChecks. None if the children shouldn't be checked.
2560        """
2561        self.assertTrue(expr.strip() == expr, "Expression contains trailing/leading whitespace: '" + expr + "'")
2562
2563        frame = self.frame()
2564        options = lldb.SBExpressionOptions()
2565
2566        # Disable fix-its that tests don't pass by accident.
2567        options.SetAutoApplyFixIts(False)
2568
2569        # Set the usual default options for normal expressions.
2570        options.SetIgnoreBreakpoints(True)
2571
2572        if self.frame().IsValid():
2573            options.SetLanguage(frame.GuessLanguage())
2574            eval_result = self.frame().EvaluateExpression(expr, options)
2575        else:
2576            target = self.target()
2577            # If there is no selected target, run the expression in the dummy
2578            # target.
2579            if not target.IsValid():
2580                target = self.dbg.GetDummyTarget()
2581            eval_result = target.EvaluateExpression(expr, options)
2582
2583        value_check = ValueCheck(type=result_type, value=result_value,
2584                                 summary=result_summary, children=result_children)
2585        value_check.check_value(self, eval_result, str(eval_result))
2586        return eval_result
2587
2588    def invoke(self, obj, name, trace=False):
2589        """Use reflection to call a method dynamically with no argument."""
2590        trace = (True if traceAlways else trace)
2591
2592        method = getattr(obj, name)
2593        import inspect
2594        self.assertTrue(inspect.ismethod(method),
2595                        name + "is a method name of object: " + str(obj))
2596        result = method()
2597        with recording(self, trace) as sbuf:
2598            print(str(method) + ":", result, file=sbuf)
2599        return result
2600
2601    def build(
2602            self,
2603            architecture=None,
2604            compiler=None,
2605            dictionary=None):
2606        """Platform specific way to build the default binaries."""
2607        module = builder_module()
2608
2609        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
2610        if self.getDebugInfo() is None:
2611            return self.buildDefault(architecture, compiler, dictionary)
2612        elif self.getDebugInfo() == "dsym":
2613            return self.buildDsym(architecture, compiler, dictionary)
2614        elif self.getDebugInfo() == "dwarf":
2615            return self.buildDwarf(architecture, compiler, dictionary)
2616        elif self.getDebugInfo() == "dwo":
2617            return self.buildDwo(architecture, compiler, dictionary)
2618        elif self.getDebugInfo() == "gmodules":
2619            return self.buildGModules(architecture, compiler, dictionary)
2620        else:
2621            self.fail("Can't build for debug info: %s" % self.getDebugInfo())
2622
2623    def run_platform_command(self, cmd):
2624        platform = self.dbg.GetSelectedPlatform()
2625        shell_command = lldb.SBPlatformShellCommand(cmd)
2626        err = platform.Run(shell_command)
2627        return (err, shell_command.GetStatus(), shell_command.GetOutput())
2628
2629    """Assert that an lldb.SBError is in the "success" state."""
2630    def assertSuccess(self, obj, msg=None):
2631        if not obj.Success():
2632            error = obj.GetCString()
2633            self.fail(self._formatMessage(msg,
2634                "'{}' is not success".format(error)))
2635
2636    # =================================================
2637    # Misc. helper methods for debugging test execution
2638    # =================================================
2639
2640    def DebugSBValue(self, val):
2641        """Debug print a SBValue object, if traceAlways is True."""
2642        from .lldbutil import value_type_to_str
2643
2644        if not traceAlways:
2645            return
2646
2647        err = sys.stderr
2648        err.write(val.GetName() + ":\n")
2649        err.write('\t' + "TypeName         -> " + val.GetTypeName() + '\n')
2650        err.write('\t' + "ByteSize         -> " +
2651                  str(val.GetByteSize()) + '\n')
2652        err.write('\t' + "NumChildren      -> " +
2653                  str(val.GetNumChildren()) + '\n')
2654        err.write('\t' + "Value            -> " + str(val.GetValue()) + '\n')
2655        err.write('\t' + "ValueAsUnsigned  -> " +
2656                  str(val.GetValueAsUnsigned()) + '\n')
2657        err.write(
2658            '\t' +
2659            "ValueType        -> " +
2660            value_type_to_str(
2661                val.GetValueType()) +
2662            '\n')
2663        err.write('\t' + "Summary          -> " + str(val.GetSummary()) + '\n')
2664        err.write('\t' + "IsPointerType    -> " +
2665                  str(val.TypeIsPointerType()) + '\n')
2666        err.write('\t' + "Location         -> " + val.GetLocation() + '\n')
2667
2668    def DebugSBType(self, type):
2669        """Debug print a SBType object, if traceAlways is True."""
2670        if not traceAlways:
2671            return
2672
2673        err = sys.stderr
2674        err.write(type.GetName() + ":\n")
2675        err.write('\t' + "ByteSize        -> " +
2676                  str(type.GetByteSize()) + '\n')
2677        err.write('\t' + "IsPointerType   -> " +
2678                  str(type.IsPointerType()) + '\n')
2679        err.write('\t' + "IsReferenceType -> " +
2680                  str(type.IsReferenceType()) + '\n')
2681
2682    def DebugPExpect(self, child):
2683        """Debug the spwaned pexpect object."""
2684        if not traceAlways:
2685            return
2686
2687        print(child)
2688
2689    @classmethod
2690    def RemoveTempFile(cls, file):
2691        if os.path.exists(file):
2692            remove_file(file)
2693
2694# On Windows, the first attempt to delete a recently-touched file can fail
2695# because of a race with antimalware scanners.  This function will detect a
2696# failure and retry.
2697
2698
2699def remove_file(file, num_retries=1, sleep_duration=0.5):
2700    for i in range(num_retries + 1):
2701        try:
2702            os.remove(file)
2703            return True
2704        except:
2705            time.sleep(sleep_duration)
2706            continue
2707    return False
2708