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