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