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