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 isAArch64(self):
1295        """Returns true if the architecture is AArch64."""
1296        return self.getArchitecture().lower() == "aarch64"
1297
1298    def isAArch64SVE(self):
1299        return self.isAArch64() and "sve" in self.getCPUInfo()
1300
1301    def isAArch64MTE(self):
1302        return self.isAArch64() and "mte" in self.getCPUInfo()
1303
1304    def isAArch64PAuth(self):
1305        return self.isAArch64() and "paca" in self.getCPUInfo()
1306
1307    def getArchitecture(self):
1308        """Returns the architecture in effect the test suite is running with."""
1309        module = builder_module()
1310        arch = module.getArchitecture()
1311        if arch == 'amd64':
1312            arch = 'x86_64'
1313        if arch in ['armv7l', 'armv8l'] :
1314            arch = 'arm'
1315        return arch
1316
1317    def getLldbArchitecture(self):
1318        """Returns the architecture of the lldb binary."""
1319        if not hasattr(self, 'lldbArchitecture'):
1320
1321            # spawn local process
1322            command = [
1323                lldbtest_config.lldbExec,
1324                "-o",
1325                "file " + lldbtest_config.lldbExec,
1326                "-o",
1327                "quit"
1328            ]
1329
1330            output = check_output(command)
1331            str = output.decode("utf-8")
1332
1333            for line in str.splitlines():
1334                m = re.search(
1335                    "Current executable set to '.*' \\((.*)\\)\\.", line)
1336                if m:
1337                    self.lldbArchitecture = m.group(1)
1338                    break
1339
1340        return self.lldbArchitecture
1341
1342    def getCompiler(self):
1343        """Returns the compiler in effect the test suite is running with."""
1344        module = builder_module()
1345        return module.getCompiler()
1346
1347    def getCompilerBinary(self):
1348        """Returns the compiler binary the test suite is running with."""
1349        return self.getCompiler().split()[0]
1350
1351    def getCompilerVersion(self):
1352        """ Returns a string that represents the compiler version.
1353            Supports: llvm, clang.
1354        """
1355        compiler = self.getCompilerBinary()
1356        version_output = system([[compiler, "--version"]])
1357        for line in version_output.split(os.linesep):
1358            m = re.search('version ([0-9.]+)', line)
1359            if m:
1360                return m.group(1)
1361        return 'unknown'
1362
1363    def getDwarfVersion(self):
1364        """ Returns the dwarf version generated by clang or '0'. """
1365        if configuration.dwarf_version:
1366            return str(configuration.dwarf_version)
1367        if 'clang' in self.getCompiler():
1368            try:
1369                driver_output = check_output(
1370                    [self.getCompiler()] + '-g -c -x c - -o - -###'.split(),
1371                    stderr=STDOUT)
1372                driver_output = driver_output.decode("utf-8")
1373                for line in driver_output.split(os.linesep):
1374                    m = re.search('dwarf-version=([0-9])', line)
1375                    if m:
1376                        return m.group(1)
1377            except: pass
1378        return '0'
1379
1380    def platformIsDarwin(self):
1381        """Returns true if the OS triple for the selected platform is any valid apple OS"""
1382        return lldbplatformutil.platformIsDarwin()
1383
1384    def hasDarwinFramework(self):
1385        return self.darwinWithFramework
1386
1387    def getPlatform(self):
1388        """Returns the target platform the test suite is running on."""
1389        return lldbplatformutil.getPlatform()
1390
1391    def isIntelCompiler(self):
1392        """ Returns true if using an Intel (ICC) compiler, false otherwise. """
1393        return any([x in self.getCompiler() for x in ["icc", "icpc", "icl"]])
1394
1395    def expectedCompilerVersion(self, compiler_version):
1396        """Returns True iff compiler_version[1] matches the current compiler version.
1397           Use compiler_version[0] to specify the operator used to determine if a match has occurred.
1398           Any operator other than the following defaults to an equality test:
1399             '>', '>=', "=>", '<', '<=', '=<', '!=', "!" or 'not'
1400
1401           If the current compiler version cannot be determined, we assume it is close to the top
1402           of trunk, so any less-than or equal-to comparisons will return False, and any
1403           greater-than or not-equal-to comparisons will return True.
1404        """
1405        if compiler_version is None:
1406            return True
1407        operator = str(compiler_version[0])
1408        version = compiler_version[1]
1409
1410        if version is None:
1411            return True
1412
1413        test_compiler_version = self.getCompilerVersion()
1414        if test_compiler_version == 'unknown':
1415            # Assume the compiler version is at or near the top of trunk.
1416            return operator in ['>', '>=', '!', '!=', 'not']
1417
1418        if operator == '>':
1419            return LooseVersion(test_compiler_version) > LooseVersion(version)
1420        if operator == '>=' or operator == '=>':
1421            return LooseVersion(test_compiler_version) >= LooseVersion(version)
1422        if operator == '<':
1423            return LooseVersion(test_compiler_version) < LooseVersion(version)
1424        if operator == '<=' or operator == '=<':
1425            return LooseVersion(test_compiler_version) <= LooseVersion(version)
1426        if operator == '!=' or operator == '!' or operator == 'not':
1427            return str(version) not in str(test_compiler_version)
1428        return str(version) in str(test_compiler_version)
1429
1430    def expectedCompiler(self, compilers):
1431        """Returns True iff any element of compilers is a sub-string of the current compiler."""
1432        if (compilers is None):
1433            return True
1434
1435        for compiler in compilers:
1436            if compiler in self.getCompiler():
1437                return True
1438
1439        return False
1440
1441    def expectedArch(self, archs):
1442        """Returns True iff any element of archs is a sub-string of the current architecture."""
1443        if (archs is None):
1444            return True
1445
1446        for arch in archs:
1447            if arch in self.getArchitecture():
1448                return True
1449
1450        return False
1451
1452    def getRunOptions(self):
1453        """Command line option for -A and -C to run this test again, called from
1454        self.dumpSessionInfo()."""
1455        arch = self.getArchitecture()
1456        comp = self.getCompiler()
1457        option_str = ""
1458        if arch:
1459            option_str = "-A " + arch
1460        if comp:
1461            option_str += " -C " + comp
1462        return option_str
1463
1464    def getDebugInfo(self):
1465        method = getattr(self, self.testMethodName)
1466        return getattr(method, "debug_info", None)
1467
1468    # ==================================================
1469    # Build methods supported through a plugin interface
1470    # ==================================================
1471
1472    def getstdlibFlag(self):
1473        """ Returns the proper -stdlib flag, or empty if not required."""
1474        if self.platformIsDarwin() or self.getPlatform() == "freebsd" or self.getPlatform() == "openbsd":
1475            stdlibflag = "-stdlib=libc++"
1476        else:  # this includes NetBSD
1477            stdlibflag = ""
1478        return stdlibflag
1479
1480    def getstdFlag(self):
1481        """ Returns the proper stdflag. """
1482        if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
1483            stdflag = "-std=c++0x"
1484        else:
1485            stdflag = "-std=c++11"
1486        return stdflag
1487
1488    def buildDriver(self, sources, exe_name):
1489        """ Platform-specific way to build a program that links with LLDB (via the liblldb.so
1490            or LLDB.framework).
1491        """
1492        stdflag = self.getstdFlag()
1493        stdlibflag = self.getstdlibFlag()
1494
1495        lib_dir = configuration.lldb_libs_dir
1496        if self.hasDarwinFramework():
1497            d = {'CXX_SOURCES': sources,
1498                 'EXE': exe_name,
1499                 'CFLAGS_EXTRAS': "%s %s" % (stdflag, stdlibflag),
1500                 'FRAMEWORK_INCLUDES': "-F%s" % self.framework_dir,
1501                 'LD_EXTRAS': "%s -Wl,-rpath,%s" % (self.lib_lldb, self.framework_dir),
1502                 }
1503        elif sys.platform.startswith('win'):
1504            d = {
1505                'CXX_SOURCES': sources,
1506                'EXE': exe_name,
1507                'CFLAGS_EXTRAS': "%s %s -I%s" % (stdflag,
1508                                                 stdlibflag,
1509                                                 os.path.join(
1510                                                     os.environ["LLDB_SRC"],
1511                                                     "include")),
1512                'LD_EXTRAS': "-L%s -lliblldb" % lib_dir}
1513        else:
1514            d = {
1515                'CXX_SOURCES': sources,
1516                'EXE': exe_name,
1517                'CFLAGS_EXTRAS': "%s %s -I%s" % (stdflag,
1518                                                 stdlibflag,
1519                                                 os.path.join(
1520                                                     os.environ["LLDB_SRC"],
1521                                                     "include")),
1522                'LD_EXTRAS': "-L%s -llldb -Wl,-rpath,%s" % (lib_dir, lib_dir)}
1523        if self.TraceOn():
1524            print(
1525                "Building LLDB Driver (%s) from sources %s" %
1526                (exe_name, sources))
1527
1528        self.buildDefault(dictionary=d)
1529
1530    def buildLibrary(self, sources, lib_name):
1531        """Platform specific way to build a default library. """
1532
1533        stdflag = self.getstdFlag()
1534
1535        lib_dir = configuration.lldb_libs_dir
1536        if self.hasDarwinFramework():
1537            d = {'DYLIB_CXX_SOURCES': sources,
1538                 'DYLIB_NAME': lib_name,
1539                 'CFLAGS_EXTRAS': "%s -stdlib=libc++" % stdflag,
1540                 'FRAMEWORK_INCLUDES': "-F%s" % self.framework_dir,
1541                 'LD_EXTRAS': "%s -Wl,-rpath,%s -dynamiclib" % (self.lib_lldb, self.framework_dir),
1542                 }
1543        elif self.getPlatform() == 'windows':
1544            d = {
1545                'DYLIB_CXX_SOURCES': sources,
1546                'DYLIB_NAME': lib_name,
1547                'CFLAGS_EXTRAS': "%s -I%s " % (stdflag,
1548                                               os.path.join(
1549                                                   os.environ["LLDB_SRC"],
1550                                                   "include")),
1551                'LD_EXTRAS': "-shared -l%s\liblldb.lib" % lib_dir}
1552        else:
1553            d = {
1554                'DYLIB_CXX_SOURCES': sources,
1555                'DYLIB_NAME': lib_name,
1556                'CFLAGS_EXTRAS': "%s -I%s -fPIC" % (stdflag,
1557                                                    os.path.join(
1558                                                        os.environ["LLDB_SRC"],
1559                                                        "include")),
1560                'LD_EXTRAS': "-shared -L%s -llldb -Wl,-rpath,%s" % (lib_dir, lib_dir)}
1561        if self.TraceOn():
1562            print(
1563                "Building LLDB Library (%s) from sources %s" %
1564                (lib_name, sources))
1565
1566        self.buildDefault(dictionary=d)
1567
1568    def buildProgram(self, sources, exe_name):
1569        """ Platform specific way to build an executable from C/C++ sources. """
1570        d = {'CXX_SOURCES': sources,
1571             'EXE': exe_name}
1572        self.buildDefault(dictionary=d)
1573
1574    def buildDefault(
1575            self,
1576            architecture=None,
1577            compiler=None,
1578            dictionary=None):
1579        """Platform specific way to build the default binaries."""
1580        testdir = self.mydir
1581        testname = self.getBuildDirBasename()
1582
1583        if not architecture and configuration.arch:
1584            architecture = configuration.arch
1585
1586        if self.getDebugInfo():
1587            raise Exception("buildDefault tests must set NO_DEBUG_INFO_TESTCASE")
1588        module = builder_module()
1589        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1590        if not module.buildDefault(self, architecture, compiler,
1591                                   dictionary, testdir, testname):
1592            raise Exception("Don't know how to build default binary")
1593
1594    def buildDsym(
1595            self,
1596            architecture=None,
1597            compiler=None,
1598            dictionary=None):
1599        """Platform specific way to build binaries with dsym info."""
1600        testdir = self.mydir
1601        testname = self.getBuildDirBasename()
1602        if self.getDebugInfo() != "dsym":
1603            raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")
1604
1605        module = builder_module()
1606        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1607        if not module.buildDsym(self, architecture, compiler,
1608                                dictionary, testdir, testname):
1609            raise Exception("Don't know how to build binary with dsym")
1610
1611    def buildDwarf(
1612            self,
1613            architecture=None,
1614            compiler=None,
1615            dictionary=None):
1616        """Platform specific way to build binaries with dwarf maps."""
1617        testdir = self.mydir
1618        testname = self.getBuildDirBasename()
1619        if self.getDebugInfo() != "dwarf":
1620            raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")
1621
1622        module = builder_module()
1623        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1624        if not module.buildDwarf(self, architecture, compiler,
1625                                   dictionary, testdir, testname):
1626            raise Exception("Don't know how to build binary with dwarf")
1627
1628    def buildDwo(
1629            self,
1630            architecture=None,
1631            compiler=None,
1632            dictionary=None):
1633        """Platform specific way to build binaries with dwarf maps."""
1634        testdir = self.mydir
1635        testname = self.getBuildDirBasename()
1636        if self.getDebugInfo() != "dwo":
1637            raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")
1638
1639        module = builder_module()
1640        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1641        if not module.buildDwo(self, architecture, compiler,
1642                                   dictionary, testdir, testname):
1643            raise Exception("Don't know how to build binary with dwo")
1644
1645    def buildGModules(
1646            self,
1647            architecture=None,
1648            compiler=None,
1649            dictionary=None):
1650        """Platform specific way to build binaries with gmodules info."""
1651        testdir = self.mydir
1652        testname = self.getBuildDirBasename()
1653        if self.getDebugInfo() != "gmodules":
1654            raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")
1655
1656        module = builder_module()
1657        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1658        if not module.buildGModules(self, architecture, compiler,
1659                                    dictionary, testdir, testname):
1660            raise Exception("Don't know how to build binary with gmodules")
1661
1662    def signBinary(self, binary_path):
1663        if sys.platform.startswith("darwin"):
1664            codesign_cmd = "codesign --force --sign \"%s\" %s" % (
1665                lldbtest_config.codesign_identity, binary_path)
1666            call(codesign_cmd, shell=True)
1667
1668    def findBuiltClang(self):
1669        """Tries to find and use Clang from the build directory as the compiler (instead of the system compiler)."""
1670        paths_to_try = [
1671            "llvm-build/Release+Asserts/x86_64/bin/clang",
1672            "llvm-build/Debug+Asserts/x86_64/bin/clang",
1673            "llvm-build/Release/x86_64/bin/clang",
1674            "llvm-build/Debug/x86_64/bin/clang",
1675        ]
1676        lldb_root_path = os.path.join(
1677            os.path.dirname(__file__), "..", "..", "..", "..")
1678        for p in paths_to_try:
1679            path = os.path.join(lldb_root_path, p)
1680            if os.path.exists(path):
1681                return path
1682
1683        # Tries to find clang at the same folder as the lldb
1684        lldb_dir = os.path.dirname(lldbtest_config.lldbExec)
1685        path = distutils.spawn.find_executable("clang", lldb_dir)
1686        if path is not None:
1687            return path
1688
1689        return os.environ["CC"]
1690
1691
1692    def yaml2obj(self, yaml_path, obj_path):
1693        """
1694        Create an object file at the given path from a yaml file.
1695
1696        Throws subprocess.CalledProcessError if the object could not be created.
1697        """
1698        yaml2obj_bin = configuration.get_yaml2obj_path()
1699        if not yaml2obj_bin:
1700            self.assertTrue(False, "No valid yaml2obj executable specified")
1701        command = [yaml2obj_bin, "-o=%s" % obj_path, yaml_path]
1702        system([command])
1703
1704    def getBuildFlags(
1705            self,
1706            use_cpp11=True,
1707            use_libcxx=False,
1708            use_libstdcxx=False):
1709        """ Returns a dictionary (which can be provided to build* functions above) which
1710            contains OS-specific build flags.
1711        """
1712        cflags = ""
1713        ldflags = ""
1714
1715        # On Mac OS X, unless specifically requested to use libstdc++, use
1716        # libc++
1717        if not use_libstdcxx and self.platformIsDarwin():
1718            use_libcxx = True
1719
1720        if use_libcxx and self.libcxxPath:
1721            cflags += "-stdlib=libc++ "
1722            if self.libcxxPath:
1723                libcxxInclude = os.path.join(self.libcxxPath, "include")
1724                libcxxLib = os.path.join(self.libcxxPath, "lib")
1725                if os.path.isdir(libcxxInclude) and os.path.isdir(libcxxLib):
1726                    cflags += "-nostdinc++ -I%s -L%s -Wl,-rpath,%s " % (
1727                        libcxxInclude, libcxxLib, libcxxLib)
1728
1729        if use_cpp11:
1730            cflags += "-std="
1731            if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
1732                cflags += "c++0x"
1733            else:
1734                cflags += "c++11"
1735        if self.platformIsDarwin() or self.getPlatform() == "freebsd":
1736            cflags += " -stdlib=libc++"
1737        elif self.getPlatform() == "openbsd":
1738            cflags += " -stdlib=libc++"
1739        elif self.getPlatform() == "netbsd":
1740            # NetBSD defaults to libc++
1741            pass
1742        elif "clang" in self.getCompiler():
1743            cflags += " -stdlib=libstdc++"
1744
1745        return {'CFLAGS_EXTRAS': cflags,
1746                'LD_EXTRAS': ldflags,
1747                }
1748
1749    def cleanup(self, dictionary=None):
1750        """Platform specific way to do cleanup after build."""
1751        module = builder_module()
1752        if not module.cleanup(self, dictionary):
1753            raise Exception(
1754                "Don't know how to do cleanup with dictionary: " +
1755                dictionary)
1756
1757    def invoke(self, obj, name, trace=False):
1758        """Use reflection to call a method dynamically with no argument."""
1759        trace = (True if traceAlways else trace)
1760
1761        method = getattr(obj, name)
1762        import inspect
1763        self.assertTrue(inspect.ismethod(method),
1764                        name + "is a method name of object: " + str(obj))
1765        result = method()
1766        with recording(self, trace) as sbuf:
1767            print(str(method) + ":", result, file=sbuf)
1768        return result
1769
1770    def getLLDBLibraryEnvVal(self):
1771        """ Returns the path that the OS-specific library search environment variable
1772            (self.dylibPath) should be set to in order for a program to find the LLDB
1773            library. If an environment variable named self.dylibPath is already set,
1774            the new path is appended to it and returned.
1775        """
1776        existing_library_path = os.environ[
1777            self.dylibPath] if self.dylibPath in os.environ else None
1778        if existing_library_path:
1779            return "%s:%s" % (existing_library_path, configuration.lldb_libs_dir)
1780        if sys.platform.startswith("darwin") and configuration.lldb_framework_path:
1781            return configuration.lldb_framework_path
1782        return configuration.lldb_libs_dir
1783
1784    def getLibcPlusPlusLibs(self):
1785        if self.getPlatform() in ('freebsd', 'linux', 'netbsd', 'openbsd'):
1786            return ['libc++.so.1']
1787        else:
1788            return ['libc++.1.dylib', 'libc++abi.']
1789
1790    def run_platform_command(self, cmd):
1791        platform = self.dbg.GetSelectedPlatform()
1792        shell_command = lldb.SBPlatformShellCommand(cmd)
1793        err = platform.Run(shell_command)
1794        return (err, shell_command.GetStatus(), shell_command.GetOutput())
1795
1796# Metaclass for TestBase to change the list of test metods when a new TestCase is loaded.
1797# We change the test methods to create a new test method for each test for each debug info we are
1798# testing. The name of the new test method will be '<original-name>_<debug-info>' and with adding
1799# the new test method we remove the old method at the same time. This functionality can be
1800# supressed by at test case level setting the class attribute NO_DEBUG_INFO_TESTCASE or at test
1801# level by using the decorator @no_debug_info_test.
1802
1803
1804class LLDBTestCaseFactory(type):
1805
1806    def __new__(cls, name, bases, attrs):
1807        original_testcase = super(
1808            LLDBTestCaseFactory, cls).__new__(
1809            cls, name, bases, attrs)
1810        if original_testcase.NO_DEBUG_INFO_TESTCASE:
1811            return original_testcase
1812
1813        newattrs = {}
1814        for attrname, attrvalue in attrs.items():
1815            if attrname.startswith("test") and not getattr(
1816                    attrvalue, "__no_debug_info_test__", False):
1817
1818                # If any debug info categories were explicitly tagged, assume that list to be
1819                # authoritative.  If none were specified, try with all debug
1820                # info formats.
1821                all_dbginfo_categories = set(test_categories.debug_info_categories)
1822                categories = set(
1823                    getattr(
1824                        attrvalue,
1825                        "categories",
1826                        [])) & all_dbginfo_categories
1827                if not categories:
1828                    categories = all_dbginfo_categories
1829
1830                for cat in categories:
1831                    @decorators.add_test_categories([cat])
1832                    @wraps(attrvalue)
1833                    def test_method(self, attrvalue=attrvalue):
1834                        return attrvalue(self)
1835
1836                    method_name = attrname + "_" + cat
1837                    test_method.__name__ = method_name
1838                    test_method.debug_info = cat
1839                    newattrs[method_name] = test_method
1840
1841            else:
1842                newattrs[attrname] = attrvalue
1843        return super(
1844            LLDBTestCaseFactory,
1845            cls).__new__(
1846            cls,
1847            name,
1848            bases,
1849            newattrs)
1850
1851# Setup the metaclass for this class to change the list of the test
1852# methods when a new class is loaded
1853
1854
1855@add_metaclass(LLDBTestCaseFactory)
1856class TestBase(Base):
1857    """
1858    This abstract base class is meant to be subclassed.  It provides default
1859    implementations for setUpClass(), tearDownClass(), setUp(), and tearDown(),
1860    among other things.
1861
1862    Important things for test class writers:
1863
1864        - Overwrite the mydir class attribute, otherwise your test class won't
1865          run.  It specifies the relative directory to the top level 'test' so
1866          the test harness can change to the correct working directory before
1867          running your test.
1868
1869        - The setUp method sets up things to facilitate subsequent interactions
1870          with the debugger as part of the test.  These include:
1871              - populate the test method name
1872              - create/get a debugger set with synchronous mode (self.dbg)
1873              - get the command interpreter from with the debugger (self.ci)
1874              - create a result object for use with the command interpreter
1875                (self.res)
1876              - plus other stuffs
1877
1878        - The tearDown method tries to perform some necessary cleanup on behalf
1879          of the test to return the debugger to a good state for the next test.
1880          These include:
1881              - execute any tearDown hooks registered by the test method with
1882                TestBase.addTearDownHook(); examples can be found in
1883                settings/TestSettings.py
1884              - kill the inferior process associated with each target, if any,
1885                and, then delete the target from the debugger's target list
1886              - perform build cleanup before running the next test method in the
1887                same test class; examples of registering for this service can be
1888                found in types/TestIntegerTypes.py with the call:
1889                    - self.setTearDownCleanup(dictionary=d)
1890
1891        - Similarly setUpClass and tearDownClass perform classwise setup and
1892          teardown fixtures.  The tearDownClass method invokes a default build
1893          cleanup for the entire test class;  also, subclasses can implement the
1894          classmethod classCleanup(cls) to perform special class cleanup action.
1895
1896        - The instance methods runCmd and expect are used heavily by existing
1897          test cases to send a command to the command interpreter and to perform
1898          string/pattern matching on the output of such command execution.  The
1899          expect method also provides a mode to peform string/pattern matching
1900          without running a command.
1901
1902        - The build methods buildDefault, buildDsym, and buildDwarf are used to
1903          build the binaries used during a particular test scenario.  A plugin
1904          should be provided for the sys.platform running the test suite.  The
1905          Mac OS X implementation is located in builders/darwin.py.
1906    """
1907
1908    # Subclasses can set this to true (if they don't depend on debug info) to avoid running the
1909    # test multiple times with various debug info types.
1910    NO_DEBUG_INFO_TESTCASE = False
1911
1912    # Maximum allowed attempts when launching the inferior process.
1913    # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
1914    maxLaunchCount = 1
1915
1916    # Time to wait before the next launching attempt in second(s).
1917    # Can be overridden by the LLDB_TIME_WAIT_NEXT_LAUNCH environment variable.
1918    timeWaitNextLaunch = 1.0
1919
1920    def generateSource(self, source):
1921        template = source + '.template'
1922        temp = os.path.join(self.getSourceDir(), template)
1923        with open(temp, 'r') as f:
1924            content = f.read()
1925
1926        public_api_dir = os.path.join(
1927            os.environ["LLDB_SRC"], "include", "lldb", "API")
1928
1929        # Look under the include/lldb/API directory and add #include statements
1930        # for all the SB API headers.
1931        public_headers = os.listdir(public_api_dir)
1932        # For different platforms, the include statement can vary.
1933        if self.hasDarwinFramework():
1934            include_stmt = "'#include <%s>' % os.path.join('LLDB', header)"
1935        else:
1936            include_stmt = "'#include <%s>' % os.path.join('" + public_api_dir + "', header)"
1937        list = [eval(include_stmt) for header in public_headers if (
1938            header.startswith("SB") and header.endswith(".h"))]
1939        includes = '\n'.join(list)
1940        new_content = content.replace('%include_SB_APIs%', includes)
1941        new_content = new_content.replace('%SOURCE_DIR%', self.getSourceDir())
1942        src = os.path.join(self.getBuildDir(), source)
1943        with open(src, 'w') as f:
1944            f.write(new_content)
1945
1946        self.addTearDownHook(lambda: os.remove(src))
1947
1948    def setUp(self):
1949        # Works with the test driver to conditionally skip tests via
1950        # decorators.
1951        Base.setUp(self)
1952
1953        for s in self.setUpCommands():
1954            self.runCmd(s)
1955
1956        if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
1957            self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])
1958
1959        if "LLDB_TIME_WAIT_NEXT_LAUNCH" in os.environ:
1960            self.timeWaitNextLaunch = float(
1961                os.environ["LLDB_TIME_WAIT_NEXT_LAUNCH"])
1962
1963        # We want our debugger to be synchronous.
1964        self.dbg.SetAsync(False)
1965
1966        # Retrieve the associated command interpreter instance.
1967        self.ci = self.dbg.GetCommandInterpreter()
1968        if not self.ci:
1969            raise Exception('Could not get the command interpreter')
1970
1971        # And the result object.
1972        self.res = lldb.SBCommandReturnObject()
1973
1974    def registerSharedLibrariesWithTarget(self, target, shlibs):
1975        '''If we are remotely running the test suite, register the shared libraries with the target so they get uploaded, otherwise do nothing
1976
1977        Any modules in the target that have their remote install file specification set will
1978        get uploaded to the remote host. This function registers the local copies of the
1979        shared libraries with the target and sets their remote install locations so they will
1980        be uploaded when the target is run.
1981        '''
1982        if not shlibs or not self.platformContext:
1983            return None
1984
1985        shlib_environment_var = self.platformContext.shlib_environment_var
1986        shlib_prefix = self.platformContext.shlib_prefix
1987        shlib_extension = '.' + self.platformContext.shlib_extension
1988
1989        dirs = []
1990        # Add any shared libraries to our target if remote so they get
1991        # uploaded into the working directory on the remote side
1992        for name in shlibs:
1993            # The path can be a full path to a shared library, or a make file name like "Foo" for
1994            # "libFoo.dylib" or "libFoo.so", or "Foo.so" for "Foo.so" or "libFoo.so", or just a
1995            # basename like "libFoo.so". So figure out which one it is and resolve the local copy
1996            # of the shared library accordingly
1997            if os.path.isfile(name):
1998                local_shlib_path = name  # name is the full path to the local shared library
1999            else:
2000                # Check relative names
2001                local_shlib_path = os.path.join(
2002                    self.getBuildDir(), shlib_prefix + name + shlib_extension)
2003                if not os.path.exists(local_shlib_path):
2004                    local_shlib_path = os.path.join(
2005                        self.getBuildDir(), name + shlib_extension)
2006                    if not os.path.exists(local_shlib_path):
2007                        local_shlib_path = os.path.join(self.getBuildDir(), name)
2008
2009                # Make sure we found the local shared library in the above code
2010                self.assertTrue(os.path.exists(local_shlib_path))
2011
2012
2013            # Add the shared library to our target
2014            shlib_module = target.AddModule(local_shlib_path, None, None, None)
2015            if lldb.remote_platform:
2016                # We must set the remote install location if we want the shared library
2017                # to get uploaded to the remote target
2018                remote_shlib_path = lldbutil.append_to_process_working_directory(self,
2019                    os.path.basename(local_shlib_path))
2020                shlib_module.SetRemoteInstallFileSpec(
2021                    lldb.SBFileSpec(remote_shlib_path, False))
2022                dir_to_add = self.get_process_working_directory()
2023            else:
2024                dir_to_add = os.path.dirname(local_shlib_path)
2025
2026            if dir_to_add not in dirs:
2027                dirs.append(dir_to_add)
2028
2029        env_value = self.platformContext.shlib_path_separator.join(dirs)
2030        return ['%s=%s' % (shlib_environment_var, env_value)]
2031
2032    def registerSanitizerLibrariesWithTarget(self, target):
2033        runtimes = []
2034        for m in target.module_iter():
2035            libspec = m.GetFileSpec()
2036            if "clang_rt" in libspec.GetFilename():
2037                runtimes.append(os.path.join(libspec.GetDirectory(),
2038                                             libspec.GetFilename()))
2039        return self.registerSharedLibrariesWithTarget(target, runtimes)
2040
2041    # utility methods that tests can use to access the current objects
2042    def target(self):
2043        if not self.dbg:
2044            raise Exception('Invalid debugger instance')
2045        return self.dbg.GetSelectedTarget()
2046
2047    def process(self):
2048        if not self.dbg:
2049            raise Exception('Invalid debugger instance')
2050        return self.dbg.GetSelectedTarget().GetProcess()
2051
2052    def thread(self):
2053        if not self.dbg:
2054            raise Exception('Invalid debugger instance')
2055        return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread()
2056
2057    def frame(self):
2058        if not self.dbg:
2059            raise Exception('Invalid debugger instance')
2060        return self.dbg.GetSelectedTarget().GetProcess(
2061        ).GetSelectedThread().GetSelectedFrame()
2062
2063    def get_process_working_directory(self):
2064        '''Get the working directory that should be used when launching processes for local or remote processes.'''
2065        if lldb.remote_platform:
2066            # Remote tests set the platform working directory up in
2067            # TestBase.setUp()
2068            return lldb.remote_platform.GetWorkingDirectory()
2069        else:
2070            # local tests change directory into each test subdirectory
2071            return self.getBuildDir()
2072
2073    def tearDown(self):
2074        # Ensure all the references to SB objects have gone away so that we can
2075        # be sure that all test-specific resources have been freed before we
2076        # attempt to delete the targets.
2077        gc.collect()
2078
2079        # Delete the target(s) from the debugger as a general cleanup step.
2080        # This includes terminating the process for each target, if any.
2081        # We'd like to reuse the debugger for our next test without incurring
2082        # the initialization overhead.
2083        targets = []
2084        for target in self.dbg:
2085            if target:
2086                targets.append(target)
2087                process = target.GetProcess()
2088                if process:
2089                    rc = self.invoke(process, "Kill")
2090                    assert rc.Success()
2091        for target in targets:
2092            self.dbg.DeleteTarget(target)
2093
2094        if not configuration.is_reproducer():
2095            # Assert that all targets are deleted.
2096            self.assertEqual(self.dbg.GetNumTargets(), 0)
2097
2098        # Do this last, to make sure it's in reverse order from how we setup.
2099        Base.tearDown(self)
2100
2101    def switch_to_thread_with_stop_reason(self, stop_reason):
2102        """
2103        Run the 'thread list' command, and select the thread with stop reason as
2104        'stop_reason'.  If no such thread exists, no select action is done.
2105        """
2106        from .lldbutil import stop_reason_to_str
2107        self.runCmd('thread list')
2108        output = self.res.GetOutput()
2109        thread_line_pattern = re.compile(
2110            "^[ *] thread #([0-9]+):.*stop reason = %s" %
2111            stop_reason_to_str(stop_reason))
2112        for line in output.splitlines():
2113            matched = thread_line_pattern.match(line)
2114            if matched:
2115                self.runCmd('thread select %s' % matched.group(1))
2116
2117    def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False):
2118        """
2119        Ask the command interpreter to handle the command and then check its
2120        return status.
2121        """
2122        # Fail fast if 'cmd' is not meaningful.
2123        if cmd is None:
2124            raise Exception("Bad 'cmd' parameter encountered")
2125
2126        trace = (True if traceAlways else trace)
2127
2128        if cmd.startswith("target create "):
2129            cmd = cmd.replace("target create ", "file ")
2130
2131        running = (cmd.startswith("run") or cmd.startswith("process launch"))
2132
2133        for i in range(self.maxLaunchCount if running else 1):
2134            self.ci.HandleCommand(cmd, self.res, inHistory)
2135
2136            with recording(self, trace) as sbuf:
2137                print("runCmd:", cmd, file=sbuf)
2138                if not check:
2139                    print("check of return status not required", file=sbuf)
2140                if self.res.Succeeded():
2141                    print("output:", self.res.GetOutput(), file=sbuf)
2142                else:
2143                    print("runCmd failed!", file=sbuf)
2144                    print(self.res.GetError(), file=sbuf)
2145
2146            if self.res.Succeeded():
2147                break
2148            elif running:
2149                # For process launch, wait some time before possible next try.
2150                time.sleep(self.timeWaitNextLaunch)
2151                with recording(self, trace) as sbuf:
2152                    print("Command '" + cmd + "' failed!", file=sbuf)
2153
2154        if check:
2155            output = ""
2156            if self.res.GetOutput():
2157                output += "\nCommand output:\n" + self.res.GetOutput()
2158            if self.res.GetError():
2159                output += "\nError output:\n" + self.res.GetError()
2160            if msg:
2161                msg += output
2162            if cmd:
2163                cmd += output
2164            self.assertTrue(self.res.Succeeded(),
2165                            msg if (msg) else CMD_MSG(cmd))
2166
2167    def match(
2168            self,
2169            str,
2170            patterns,
2171            msg=None,
2172            trace=False,
2173            error=False,
2174            matching=True,
2175            exe=True):
2176        """run command in str, and match the result against regexp in patterns returning the match object for the first matching pattern
2177
2178        Otherwise, all the arguments have the same meanings as for the expect function"""
2179
2180        trace = (True if traceAlways else trace)
2181
2182        if exe:
2183            # First run the command.  If we are expecting error, set check=False.
2184            # Pass the assert message along since it provides more semantic
2185            # info.
2186            self.runCmd(
2187                str,
2188                msg=msg,
2189                trace=(
2190                    True if trace else False),
2191                check=not error)
2192
2193            # Then compare the output against expected strings.
2194            output = self.res.GetError() if error else self.res.GetOutput()
2195
2196            # If error is True, the API client expects the command to fail!
2197            if error:
2198                self.assertFalse(self.res.Succeeded(),
2199                                 "Command '" + str + "' is expected to fail!")
2200        else:
2201            # No execution required, just compare str against the golden input.
2202            output = str
2203            with recording(self, trace) as sbuf:
2204                print("looking at:", output, file=sbuf)
2205
2206        # The heading says either "Expecting" or "Not expecting".
2207        heading = "Expecting" if matching else "Not expecting"
2208
2209        for pattern in patterns:
2210            # Match Objects always have a boolean value of True.
2211            match_object = re.search(pattern, output)
2212            matched = bool(match_object)
2213            with recording(self, trace) as sbuf:
2214                print("%s pattern: %s" % (heading, pattern), file=sbuf)
2215                print("Matched" if matched else "Not matched", file=sbuf)
2216            if matched:
2217                break
2218
2219        self.assertTrue(matched if matching else not matched,
2220                        msg if msg else EXP_MSG(str, output, exe))
2221
2222        return match_object
2223
2224    def check_completion_with_desc(self, str_input, match_desc_pairs, enforce_order=False):
2225        """
2226        Checks that when the given input is completed at the given list of
2227        completions and descriptions is returned.
2228        :param str_input: The input that should be completed. The completion happens at the end of the string.
2229        :param match_desc_pairs: A list of pairs that indicate what completions have to be in the list of
2230                                 completions returned by LLDB. The first element of the pair is the completion
2231                                 string that LLDB should generate and the second element the description.
2232        :param enforce_order: True iff the order in which the completions are returned by LLDB
2233                              should match the order of the match_desc_pairs pairs.
2234        """
2235        interp = self.dbg.GetCommandInterpreter()
2236        match_strings = lldb.SBStringList()
2237        description_strings = lldb.SBStringList()
2238        num_matches = interp.HandleCompletionWithDescriptions(str_input, len(str_input), 0, -1, match_strings, description_strings)
2239        self.assertEqual(len(description_strings), len(match_strings))
2240
2241        # The index of the last matched description in description_strings or
2242        # -1 if no description has been matched yet.
2243        last_found_index = -1
2244        out_of_order_errors = ""
2245        missing_pairs = []
2246        for pair in match_desc_pairs:
2247            found_pair = False
2248            for i in range(num_matches + 1):
2249                match_candidate = match_strings.GetStringAtIndex(i)
2250                description_candidate = description_strings.GetStringAtIndex(i)
2251                if match_candidate == pair[0] and description_candidate == pair[1]:
2252                    found_pair = True
2253                    if enforce_order and last_found_index > i:
2254                        new_err = ("Found completion " + pair[0] + " at index " +
2255                                  str(i) + " in returned completion list but " +
2256                                  "should have been after completion " +
2257                                  match_strings.GetStringAtIndex(last_found_index) +
2258                                  " (index:" + str(last_found_index) + ")\n")
2259                        out_of_order_errors += new_err
2260                    last_found_index = i
2261                    break
2262            if not found_pair:
2263                missing_pairs.append(pair)
2264
2265        error_msg = ""
2266        got_failure = False
2267        if len(missing_pairs):
2268            got_failure = True
2269            error_msg += "Missing pairs:\n"
2270            for pair in missing_pairs:
2271                error_msg += " [" + pair[0] + ":" + pair[1] + "]\n"
2272        if len(out_of_order_errors):
2273            got_failure = True
2274            error_msg += out_of_order_errors
2275        if got_failure:
2276            error_msg += "Got the following " + str(num_matches) + " completions back:\n"
2277            for i in range(num_matches + 1):
2278                match_candidate = match_strings.GetStringAtIndex(i)
2279                description_candidate = description_strings.GetStringAtIndex(i)
2280                error_msg += "[" + match_candidate + ":" + description_candidate + "] index " + str(i) + "\n"
2281            self.assertFalse(got_failure, error_msg)
2282
2283    def complete_exactly(self, str_input, patterns):
2284        self.complete_from_to(str_input, patterns, True)
2285
2286    def complete_from_to(self, str_input, patterns, turn_off_re_match=False):
2287        """Test that the completion mechanism completes str_input to patterns,
2288        where patterns could be a pattern-string or a list of pattern-strings"""
2289        # Patterns should not be None in order to proceed.
2290        self.assertFalse(patterns is None)
2291        # And should be either a string or list of strings.  Check for list type
2292        # below, if not, make a list out of the singleton string.  If patterns
2293        # is not a string or not a list of strings, there'll be runtime errors
2294        # later on.
2295        if not isinstance(patterns, list):
2296            patterns = [patterns]
2297
2298        interp = self.dbg.GetCommandInterpreter()
2299        match_strings = lldb.SBStringList()
2300        num_matches = interp.HandleCompletion(str_input, len(str_input), 0, -1, match_strings)
2301        common_match = match_strings.GetStringAtIndex(0)
2302        if num_matches == 0:
2303            compare_string = str_input
2304        else:
2305            if common_match != None and len(common_match) > 0:
2306                compare_string = str_input + common_match
2307            else:
2308                compare_string = ""
2309                for idx in range(1, num_matches+1):
2310                    compare_string += match_strings.GetStringAtIndex(idx) + "\n"
2311
2312        for p in patterns:
2313            if turn_off_re_match:
2314                self.expect(
2315                    compare_string, msg=COMPLETION_MSG(
2316                        str_input, p, match_strings), exe=False, substrs=[p])
2317            else:
2318                self.expect(
2319                    compare_string, msg=COMPLETION_MSG(
2320                        str_input, p, match_strings), exe=False, patterns=[p])
2321
2322    def completions_match(self, command, completions):
2323        """Checks that the completions for the given command are equal to the
2324        given list of completions"""
2325        interp = self.dbg.GetCommandInterpreter()
2326        match_strings = lldb.SBStringList()
2327        interp.HandleCompletion(command, len(command), 0, -1, match_strings)
2328        # match_strings is a 1-indexed list, so we have to slice...
2329        self.assertItemsEqual(completions, list(match_strings)[1:],
2330                              "List of returned completion is wrong")
2331
2332    def completions_contain(self, command, completions):
2333        """Checks that the completions for the given command contain the given
2334        list of completions."""
2335        interp = self.dbg.GetCommandInterpreter()
2336        match_strings = lldb.SBStringList()
2337        interp.HandleCompletion(command, len(command), 0, -1, match_strings)
2338        for completion in completions:
2339            # match_strings is a 1-indexed list, so we have to slice...
2340            self.assertIn(completion, list(match_strings)[1:],
2341                          "Couldn't find expected completion")
2342
2343    def filecheck(
2344            self,
2345            command,
2346            check_file,
2347            filecheck_options = '',
2348            expect_cmd_failure = False):
2349        # Run the command.
2350        self.runCmd(
2351                command,
2352                check=(not expect_cmd_failure),
2353                msg="FileCheck'ing result of `{0}`".format(command))
2354
2355        self.assertTrue((not expect_cmd_failure) == self.res.Succeeded())
2356
2357        # Get the error text if there was an error, and the regular text if not.
2358        output = self.res.GetOutput() if self.res.Succeeded() \
2359                else self.res.GetError()
2360
2361        # Assemble the absolute path to the check file. As a convenience for
2362        # LLDB inline tests, assume that the check file is a relative path to
2363        # a file within the inline test directory.
2364        if check_file.endswith('.pyc'):
2365            check_file = check_file[:-1]
2366        check_file_abs = os.path.abspath(check_file)
2367
2368        # Run FileCheck.
2369        filecheck_bin = configuration.get_filecheck_path()
2370        if not filecheck_bin:
2371            self.assertTrue(False, "No valid FileCheck executable specified")
2372        filecheck_args = [filecheck_bin, check_file_abs]
2373        if filecheck_options:
2374            filecheck_args.append(filecheck_options)
2375        subproc = Popen(filecheck_args, stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines = True)
2376        cmd_stdout, cmd_stderr = subproc.communicate(input=output)
2377        cmd_status = subproc.returncode
2378
2379        filecheck_cmd = " ".join(filecheck_args)
2380        filecheck_trace = """
2381--- FileCheck trace (code={0}) ---
2382{1}
2383
2384FileCheck input:
2385{2}
2386
2387FileCheck output:
2388{3}
2389{4}
2390""".format(cmd_status, filecheck_cmd, output, cmd_stdout, cmd_stderr)
2391
2392        trace = cmd_status != 0 or traceAlways
2393        with recording(self, trace) as sbuf:
2394            print(filecheck_trace, file=sbuf)
2395
2396        self.assertTrue(cmd_status == 0)
2397
2398    def expect(
2399            self,
2400            str,
2401            msg=None,
2402            patterns=None,
2403            startstr=None,
2404            endstr=None,
2405            substrs=None,
2406            trace=False,
2407            error=False,
2408            ordered=True,
2409            matching=True,
2410            exe=True,
2411            inHistory=False):
2412        """
2413        Similar to runCmd; with additional expect style output matching ability.
2414
2415        Ask the command interpreter to handle the command and then check its
2416        return status.  The 'msg' parameter specifies an informational assert
2417        message.  We expect the output from running the command to start with
2418        'startstr', matches the substrings contained in 'substrs', and regexp
2419        matches the patterns contained in 'patterns'.
2420
2421        When matching is true and ordered is true, which are both the default,
2422        the strings in the substrs array have to appear in the command output
2423        in the order in which they appear in the array.
2424
2425        If the keyword argument error is set to True, it signifies that the API
2426        client is expecting the command to fail.  In this case, the error stream
2427        from running the command is retrieved and compared against the golden
2428        input, instead.
2429
2430        If the keyword argument matching is set to False, it signifies that the API
2431        client is expecting the output of the command not to match the golden
2432        input.
2433
2434        Finally, the required argument 'str' represents the lldb command to be
2435        sent to the command interpreter.  In case the keyword argument 'exe' is
2436        set to False, the 'str' is treated as a string to be matched/not-matched
2437        against the golden input.
2438        """
2439        # Catch cases where `expect` has been miscalled. Specifically, prevent
2440        # this easy to make mistake:
2441        #     self.expect("lldb command", "some substr")
2442        # The `msg` parameter is used only when a failed match occurs. A failed
2443        # match can only occur when one of `patterns`, `startstr`, `endstr`, or
2444        # `substrs` has been given. Thus, if a `msg` is given, it's an error to
2445        # not also provide one of the matcher parameters.
2446        if msg and not (patterns or startstr or endstr or substrs or error):
2447            assert False, "expect() missing a matcher argument"
2448
2449        # Check `patterns` and `substrs` are not accidentally given as strings.
2450        assert not isinstance(patterns, six.string_types), \
2451            "patterns must be a collection of strings"
2452        assert not isinstance(substrs, six.string_types), \
2453            "substrs must be a collection of strings"
2454
2455        trace = (True if traceAlways else trace)
2456
2457        if exe:
2458            # First run the command.  If we are expecting error, set check=False.
2459            # Pass the assert message along since it provides more semantic
2460            # info.
2461            self.runCmd(
2462                str,
2463                msg=msg,
2464                trace=(
2465                    True if trace else False),
2466                check=not error,
2467                inHistory=inHistory)
2468
2469            # Then compare the output against expected strings.
2470            output = self.res.GetError() if error else self.res.GetOutput()
2471
2472            # If error is True, the API client expects the command to fail!
2473            if error:
2474                self.assertFalse(self.res.Succeeded(),
2475                                 "Command '" + str + "' is expected to fail!")
2476        else:
2477            # No execution required, just compare str against the golden input.
2478            if isinstance(str, lldb.SBCommandReturnObject):
2479                output = str.GetOutput()
2480            else:
2481                output = str
2482            with recording(self, trace) as sbuf:
2483                print("looking at:", output, file=sbuf)
2484
2485        expecting_str = "Expecting" if matching else "Not expecting"
2486        def found_str(matched):
2487            return "was found" if matched else "was not found"
2488
2489        # To be used as assert fail message and/or trace content
2490        log_lines = [
2491                "{}:".format("Ran command" if exe else "Checking string"),
2492                "\"{}\"".format(str),
2493                # Space out command and output
2494                "",
2495        ]
2496        if exe:
2497            # Newline before output to make large strings more readable
2498            log_lines.append("Got output:\n{}".format(output))
2499
2500        # Assume that we start matched if we want a match
2501        # Meaning if you have no conditions, matching or
2502        # not matching will always pass
2503        matched = matching
2504
2505        # We will stop checking on first failure
2506        if startstr:
2507            matched = output.startswith(startstr)
2508            log_lines.append("{} start string: \"{}\" ({})".format(
2509                    expecting_str, startstr, found_str(matched)))
2510
2511        if endstr and matched == matching:
2512            matched = output.endswith(endstr)
2513            log_lines.append("{} end string: \"{}\" ({})".format(
2514                    expecting_str, endstr, found_str(matched)))
2515
2516        if substrs and matched == matching:
2517            start = 0
2518            for substr in substrs:
2519                index = output[start:].find(substr)
2520                start = start + index if ordered and matching else 0
2521                matched = index != -1
2522                log_lines.append("{} sub string: \"{}\" ({})".format(
2523                        expecting_str, substr, found_str(matched)))
2524
2525                if matched != matching:
2526                    break
2527
2528        if patterns and matched == matching:
2529            for pattern in patterns:
2530                matched = re.search(pattern, output)
2531
2532                pattern_line = "{} regex pattern: \"{}\" ({}".format(
2533                        expecting_str, pattern, found_str(matched))
2534                if matched:
2535                    pattern_line += ", matched \"{}\"".format(
2536                            matched.group(0))
2537                pattern_line += ")"
2538                log_lines.append(pattern_line)
2539
2540                # Convert to bool because match objects
2541                # are True-ish but != True itself
2542                matched = bool(matched)
2543                if matched != matching:
2544                    break
2545
2546        # If a check failed, add any extra assert message
2547        if msg is not None and matched != matching:
2548            log_lines.append(msg)
2549
2550        log_msg = "\n".join(log_lines)
2551        with recording(self, trace) as sbuf:
2552            print(log_msg, file=sbuf)
2553        if matched != matching:
2554            self.fail(log_msg)
2555
2556    def expect_expr(
2557            self,
2558            expr,
2559            result_summary=None,
2560            result_value=None,
2561            result_type=None,
2562            result_children=None
2563            ):
2564        """
2565        Evaluates the given expression and verifies the result.
2566        :param expr: The expression as a string.
2567        :param result_summary: The summary that the expression should have. None if the summary should not be checked.
2568        :param result_value: The value that the expression should have. None if the value should not be checked.
2569        :param result_type: The type that the expression result should have. None if the type should not be checked.
2570        :param result_children: The expected children of the expression result
2571                                as a list of ValueChecks. None if the children shouldn't be checked.
2572        """
2573        self.assertTrue(expr.strip() == expr, "Expression contains trailing/leading whitespace: '" + expr + "'")
2574
2575        frame = self.frame()
2576        options = lldb.SBExpressionOptions()
2577
2578        # Disable fix-its that tests don't pass by accident.
2579        options.SetAutoApplyFixIts(False)
2580
2581        # Set the usual default options for normal expressions.
2582        options.SetIgnoreBreakpoints(True)
2583
2584        if self.frame().IsValid():
2585            options.SetLanguage(frame.GuessLanguage())
2586            eval_result = self.frame().EvaluateExpression(expr, options)
2587        else:
2588            target = self.target()
2589            # If there is no selected target, run the expression in the dummy
2590            # target.
2591            if not target.IsValid():
2592                target = self.dbg.GetDummyTarget()
2593            eval_result = target.EvaluateExpression(expr, options)
2594
2595        value_check = ValueCheck(type=result_type, value=result_value,
2596                                 summary=result_summary, children=result_children)
2597        value_check.check_value(self, eval_result, str(eval_result))
2598        return eval_result
2599
2600    def expect_var_path(
2601            self,
2602            var_path,
2603            summary=None,
2604            value=None,
2605            type=None,
2606            children=None
2607            ):
2608        """
2609        Evaluates the given variable path and verifies the result.
2610        See also 'frame variable' and SBFrame.GetValueForVariablePath.
2611        :param var_path: The variable path as a string.
2612        :param summary: The summary that the variable should have. None if the summary should not be checked.
2613        :param value: The value that the variable should have. None if the value should not be checked.
2614        :param type: The type that the variable result should have. None if the type should not be checked.
2615        :param children: The expected children of the variable  as a list of ValueChecks.
2616                         None if the children shouldn't be checked.
2617        """
2618        self.assertTrue(var_path.strip() == var_path,
2619                        "Expression contains trailing/leading whitespace: '" + var_path + "'")
2620
2621        frame = self.frame()
2622        eval_result = frame.GetValueForVariablePath(var_path)
2623
2624        value_check = ValueCheck(type=type, value=value,
2625                                 summary=summary, children=children)
2626        value_check.check_value(self, eval_result, str(eval_result))
2627        return eval_result
2628
2629    def build(
2630            self,
2631            architecture=None,
2632            compiler=None,
2633            dictionary=None):
2634        """Platform specific way to build the default binaries."""
2635        module = builder_module()
2636
2637        if not architecture and configuration.arch:
2638            architecture = configuration.arch
2639
2640        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
2641        if self.getDebugInfo() is None:
2642            return self.buildDefault(architecture, compiler, dictionary)
2643        elif self.getDebugInfo() == "dsym":
2644            return self.buildDsym(architecture, compiler, dictionary)
2645        elif self.getDebugInfo() == "dwarf":
2646            return self.buildDwarf(architecture, compiler, dictionary)
2647        elif self.getDebugInfo() == "dwo":
2648            return self.buildDwo(architecture, compiler, dictionary)
2649        elif self.getDebugInfo() == "gmodules":
2650            return self.buildGModules(architecture, compiler, dictionary)
2651        else:
2652            self.fail("Can't build for debug info: %s" % self.getDebugInfo())
2653
2654    """Assert that an lldb.SBError is in the "success" state."""
2655    def assertSuccess(self, obj, msg=None):
2656        if not obj.Success():
2657            error = obj.GetCString()
2658            self.fail(self._formatMessage(msg,
2659                "'{}' is not success".format(error)))
2660
2661    def createTestTarget(self, file_path=None, msg=None):
2662        """
2663        Creates a target from the file found at the given file path.
2664        Asserts that the resulting target is valid.
2665        :param file_path: The file path that should be used to create the target.
2666                          The default argument opens the current default test
2667                          executable in the current test directory.
2668        :param msg: A custom error message.
2669        """
2670        if file_path is None:
2671            file_path = self.getBuildArtifact("a.out")
2672        error = lldb.SBError()
2673        triple = ""
2674        platform = ""
2675        load_dependent_modules = True
2676        target = self.dbg.CreateTarget(file_path, triple, platform,
2677                                       load_dependent_modules, error)
2678        if error.Fail():
2679            err = "Couldn't create target for path '{}': {}".format(file_path,
2680                                                                    str(error))
2681            self.fail(self._formatMessage(msg, err))
2682
2683        self.assertTrue(target.IsValid(), "Got invalid target without error")
2684        return target
2685
2686    # =================================================
2687    # Misc. helper methods for debugging test execution
2688    # =================================================
2689
2690    def DebugSBValue(self, val):
2691        """Debug print a SBValue object, if traceAlways is True."""
2692        from .lldbutil import value_type_to_str
2693
2694        if not traceAlways:
2695            return
2696
2697        err = sys.stderr
2698        err.write(val.GetName() + ":\n")
2699        err.write('\t' + "TypeName         -> " + val.GetTypeName() + '\n')
2700        err.write('\t' + "ByteSize         -> " +
2701                  str(val.GetByteSize()) + '\n')
2702        err.write('\t' + "NumChildren      -> " +
2703                  str(val.GetNumChildren()) + '\n')
2704        err.write('\t' + "Value            -> " + str(val.GetValue()) + '\n')
2705        err.write('\t' + "ValueAsUnsigned  -> " +
2706                  str(val.GetValueAsUnsigned()) + '\n')
2707        err.write(
2708            '\t' +
2709            "ValueType        -> " +
2710            value_type_to_str(
2711                val.GetValueType()) +
2712            '\n')
2713        err.write('\t' + "Summary          -> " + str(val.GetSummary()) + '\n')
2714        err.write('\t' + "IsPointerType    -> " +
2715                  str(val.TypeIsPointerType()) + '\n')
2716        err.write('\t' + "Location         -> " + val.GetLocation() + '\n')
2717
2718    def DebugSBType(self, type):
2719        """Debug print a SBType object, if traceAlways is True."""
2720        if not traceAlways:
2721            return
2722
2723        err = sys.stderr
2724        err.write(type.GetName() + ":\n")
2725        err.write('\t' + "ByteSize        -> " +
2726                  str(type.GetByteSize()) + '\n')
2727        err.write('\t' + "IsPointerType   -> " +
2728                  str(type.IsPointerType()) + '\n')
2729        err.write('\t' + "IsReferenceType -> " +
2730                  str(type.IsReferenceType()) + '\n')
2731
2732    def DebugPExpect(self, child):
2733        """Debug the spwaned pexpect object."""
2734        if not traceAlways:
2735            return
2736
2737        print(child)
2738
2739    @classmethod
2740    def RemoveTempFile(cls, file):
2741        if os.path.exists(file):
2742            remove_file(file)
2743
2744# On Windows, the first attempt to delete a recently-touched file can fail
2745# because of a race with antimalware scanners.  This function will detect a
2746# failure and retry.
2747
2748
2749def remove_file(file, num_retries=1, sleep_duration=0.5):
2750    for i in range(num_retries + 1):
2751        try:
2752            os.remove(file)
2753            return True
2754        except:
2755            time.sleep(sleep_duration)
2756            continue
2757    return False
2758