1"""
2LLDB module which provides the abstract base class of lldb test case.
3
4The concrete subclass can override lldbtest.TesBase 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
39import collections
40from functools import wraps
41import gc
42import glob
43import inspect
44import io
45import os.path
46import re
47import signal
48from subprocess import *
49import sys
50import time
51import traceback
52import types
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 use_lldb_suite
62import lldb
63from . import configuration
64from . import decorators
65from . import lldbplatformutil
66from . import lldbtest_config
67from . import lldbutil
68from . import test_categories
69from lldbsuite.support import encoded_file
70from lldbsuite.support import funcutils
71
72# dosep.py starts lots and lots of dotest instances
73# This option helps you find if two (or more) dotest instances are using the same
74# directory at the same time
75# Enable it to cause test failures and stderr messages if dotest instances try to run in
76# the same directory simultaneously
77# it is disabled by default because it litters the test directories with ".dirlock" files
78debug_confirm_directory_exclusivity = False
79
80# See also dotest.parseOptionsAndInitTestdirs(), where the environment variables
81# LLDB_COMMAND_TRACE and LLDB_DO_CLEANUP are set from '-t' and '-r dir' options.
82
83# By default, traceAlways is False.
84if "LLDB_COMMAND_TRACE" in os.environ and os.environ["LLDB_COMMAND_TRACE"]=="YES":
85    traceAlways = True
86else:
87    traceAlways = False
88
89# By default, doCleanup is True.
90if "LLDB_DO_CLEANUP" in os.environ and os.environ["LLDB_DO_CLEANUP"]=="NO":
91    doCleanup = False
92else:
93    doCleanup = True
94
95
96#
97# Some commonly used assert messages.
98#
99
100COMMAND_FAILED_AS_EXPECTED = "Command has failed as expected"
101
102CURRENT_EXECUTABLE_SET = "Current executable set successfully"
103
104PROCESS_IS_VALID = "Process is valid"
105
106PROCESS_KILLED = "Process is killed successfully"
107
108PROCESS_EXITED = "Process exited successfully"
109
110PROCESS_STOPPED = "Process status should be stopped"
111
112RUN_SUCCEEDED = "Process is launched successfully"
113
114RUN_COMPLETED = "Process exited successfully"
115
116BACKTRACE_DISPLAYED_CORRECTLY = "Backtrace displayed correctly"
117
118BREAKPOINT_CREATED = "Breakpoint created successfully"
119
120BREAKPOINT_STATE_CORRECT = "Breakpoint state is correct"
121
122BREAKPOINT_PENDING_CREATED = "Pending breakpoint created successfully"
123
124BREAKPOINT_HIT_ONCE = "Breakpoint resolved with hit cout = 1"
125
126BREAKPOINT_HIT_TWICE = "Breakpoint resolved with hit cout = 2"
127
128BREAKPOINT_HIT_THRICE = "Breakpoint resolved with hit cout = 3"
129
130MISSING_EXPECTED_REGISTERS = "At least one expected register is unavailable."
131
132OBJECT_PRINTED_CORRECTLY = "Object printed correctly"
133
134SOURCE_DISPLAYED_CORRECTLY = "Source code displayed correctly"
135
136STEP_OUT_SUCCEEDED = "Thread step-out succeeded"
137
138STOPPED_DUE_TO_EXC_BAD_ACCESS = "Process should be stopped due to bad access exception"
139
140STOPPED_DUE_TO_ASSERT = "Process should be stopped due to an assertion"
141
142STOPPED_DUE_TO_BREAKPOINT = "Process should be stopped due to breakpoint"
143
144STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS = "%s, %s" % (
145    STOPPED_DUE_TO_BREAKPOINT, "instead, the actual stop reason is: '%s'")
146
147STOPPED_DUE_TO_BREAKPOINT_CONDITION = "Stopped due to breakpoint condition"
148
149STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT = "Stopped due to breakpoint and ignore count"
150
151STOPPED_DUE_TO_SIGNAL = "Process state is stopped due to signal"
152
153STOPPED_DUE_TO_STEP_IN = "Process state is stopped due to step in"
154
155STOPPED_DUE_TO_WATCHPOINT = "Process should be stopped due to watchpoint"
156
157DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly"
158
159VALID_BREAKPOINT = "Got a valid breakpoint"
160
161VALID_BREAKPOINT_LOCATION = "Got a valid breakpoint location"
162
163VALID_COMMAND_INTERPRETER = "Got a valid command interpreter"
164
165VALID_FILESPEC = "Got a valid filespec"
166
167VALID_MODULE = "Got a valid module"
168
169VALID_PROCESS = "Got a valid process"
170
171VALID_SYMBOL = "Got a valid symbol"
172
173VALID_TARGET = "Got a valid target"
174
175VALID_PLATFORM = "Got a valid platform"
176
177VALID_TYPE = "Got a valid type"
178
179VALID_VARIABLE = "Got a valid variable"
180
181VARIABLES_DISPLAYED_CORRECTLY = "Variable(s) displayed correctly"
182
183WATCHPOINT_CREATED = "Watchpoint created successfully"
184
185def CMD_MSG(str):
186    '''A generic "Command '%s' returns successfully" message generator.'''
187    return "Command '%s' returns successfully" % str
188
189def COMPLETION_MSG(str_before, str_after):
190    '''A generic message generator for the completion mechanism.'''
191    return "'%s' successfully completes to '%s'" % (str_before, str_after)
192
193def EXP_MSG(str, actual, exe):
194    '''A generic "'%s' returns expected result" message generator if exe.
195    Otherwise, it generates "'%s' matches expected result" message.'''
196
197    return "'%s' %s expected result, got '%s'" % (str, 'returns' if exe else 'matches', actual.strip())
198
199def SETTING_MSG(setting):
200    '''A generic "Value of setting '%s' is correct" message generator.'''
201    return "Value of setting '%s' is correct" % setting
202
203def EnvArray():
204    """Returns an env variable array from the os.environ map object."""
205    return list(map(lambda k,v: k+"="+v, list(os.environ.keys()), list(os.environ.values())))
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("Unable to find '%s' within file %s" % (string_to_match, filename))
215
216def pointer_size():
217    """Return the pointer size of the host system."""
218    import ctypes
219    a_pointer = ctypes.c_void_p(0xffff)
220    return 8 * ctypes.sizeof(a_pointer)
221
222def is_exe(fpath):
223    """Returns true if fpath is an executable."""
224    return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
225
226def which(program):
227    """Returns the full path to a program; None otherwise."""
228    fpath, fname = os.path.split(program)
229    if fpath:
230        if is_exe(program):
231            return program
232    else:
233        for path in os.environ["PATH"].split(os.pathsep):
234            exe_file = os.path.join(path, program)
235            if is_exe(exe_file):
236                return exe_file
237    return None
238
239class recording(SixStringIO):
240    """
241    A nice little context manager for recording the debugger interactions into
242    our session object.  If trace flag is ON, it also emits the interactions
243    into the stderr.
244    """
245    def __init__(self, test, trace):
246        """Create a SixStringIO instance; record the session obj and trace flag."""
247        SixStringIO.__init__(self)
248        # The test might not have undergone the 'setUp(self)' phase yet, so that
249        # the attribute 'session' might not even exist yet.
250        self.session = getattr(test, "session", None) if test else None
251        self.trace = trace
252
253    def __enter__(self):
254        """
255        Context management protocol on entry to the body of the with statement.
256        Just return the SixStringIO object.
257        """
258        return self
259
260    def __exit__(self, type, value, tb):
261        """
262        Context management protocol on exit from the body of the with statement.
263        If trace is ON, it emits the recordings into stderr.  Always add the
264        recordings to our session object.  And close the SixStringIO object, too.
265        """
266        if self.trace:
267            print(self.getvalue(), file=sys.stderr)
268        if self.session:
269            print(self.getvalue(), file=self.session)
270        self.close()
271
272@add_metaclass(abc.ABCMeta)
273class _BaseProcess(object):
274
275    @abc.abstractproperty
276    def pid(self):
277        """Returns process PID if has been launched already."""
278
279    @abc.abstractmethod
280    def launch(self, executable, args):
281        """Launches new process with given executable and args."""
282
283    @abc.abstractmethod
284    def terminate(self):
285        """Terminates previously launched process.."""
286
287class _LocalProcess(_BaseProcess):
288
289    def __init__(self, trace_on):
290        self._proc = None
291        self._trace_on = trace_on
292        self._delayafterterminate = 0.1
293
294    @property
295    def pid(self):
296        return self._proc.pid
297
298    def launch(self, executable, args):
299        self._proc = Popen([executable] + args,
300                           stdout = open(os.devnull) if not self._trace_on else None,
301                           stdin = PIPE)
302
303    def terminate(self):
304        if self._proc.poll() == None:
305            # Terminate _proc like it does the pexpect
306            signals_to_try = [sig for sig in ['SIGHUP', 'SIGCONT', 'SIGINT'] if sig in dir(signal)]
307            for sig in signals_to_try:
308                try:
309                    self._proc.send_signal(getattr(signal, sig))
310                    time.sleep(self._delayafterterminate)
311                    if self._proc.poll() != None:
312                        return
313                except ValueError:
314                    pass  # Windows says SIGINT is not a valid signal to send
315            self._proc.terminate()
316            time.sleep(self._delayafterterminate)
317            if self._proc.poll() != None:
318                return
319            self._proc.kill()
320            time.sleep(self._delayafterterminate)
321
322    def poll(self):
323        return self._proc.poll()
324
325class _RemoteProcess(_BaseProcess):
326
327    def __init__(self, install_remote):
328        self._pid = None
329        self._install_remote = install_remote
330
331    @property
332    def pid(self):
333        return self._pid
334
335    def launch(self, executable, args):
336        if self._install_remote:
337            src_path = executable
338            dst_path = lldbutil.append_to_process_working_directory(os.path.basename(executable))
339
340            dst_file_spec = lldb.SBFileSpec(dst_path, False)
341            err = lldb.remote_platform.Install(lldb.SBFileSpec(src_path, True), dst_file_spec)
342            if err.Fail():
343                raise Exception("remote_platform.Install('%s', '%s') failed: %s" % (src_path, dst_path, err))
344        else:
345            dst_path = executable
346            dst_file_spec = lldb.SBFileSpec(executable, False)
347
348        launch_info = lldb.SBLaunchInfo(args)
349        launch_info.SetExecutableFile(dst_file_spec, True)
350        launch_info.SetWorkingDirectory(lldb.remote_platform.GetWorkingDirectory())
351
352        # Redirect stdout and stderr to /dev/null
353        launch_info.AddSuppressFileAction(1, False, True)
354        launch_info.AddSuppressFileAction(2, False, True)
355
356        err = lldb.remote_platform.Launch(launch_info)
357        if err.Fail():
358            raise Exception("remote_platform.Launch('%s', '%s') failed: %s" % (dst_path, args, err))
359        self._pid = launch_info.GetProcessID()
360
361    def terminate(self):
362        lldb.remote_platform.Kill(self._pid)
363
364# From 2.7's subprocess.check_output() convenience function.
365# Return a tuple (stdoutdata, stderrdata).
366def system(commands, **kwargs):
367    r"""Run an os command with arguments and return its output as a byte string.
368
369    If the exit code was non-zero it raises a CalledProcessError.  The
370    CalledProcessError object will have the return code in the returncode
371    attribute and output in the output attribute.
372
373    The arguments are the same as for the Popen constructor.  Example:
374
375    >>> check_output(["ls", "-l", "/dev/null"])
376    'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'
377
378    The stdout argument is not allowed as it is used internally.
379    To capture standard error in the result, use stderr=STDOUT.
380
381    >>> check_output(["/bin/sh", "-c",
382    ...               "ls -l non_existent_file ; exit 0"],
383    ...              stderr=STDOUT)
384    'ls: non_existent_file: No such file or directory\n'
385    """
386
387    # Assign the sender object to variable 'test' and remove it from kwargs.
388    test = kwargs.pop('sender', None)
389
390    # [['make', 'clean', 'foo'], ['make', 'foo']] -> ['make clean foo', 'make foo']
391    commandList = [' '.join(x) for x in commands]
392    output = ""
393    error = ""
394    for shellCommand in commandList:
395        if 'stdout' in kwargs:
396            raise ValueError('stdout argument not allowed, it will be overridden.')
397        if 'shell' in kwargs and kwargs['shell']==False:
398            raise ValueError('shell=False not allowed')
399        process = Popen(shellCommand, stdout=PIPE, stderr=PIPE, shell=True, universal_newlines=True, **kwargs)
400        pid = process.pid
401        this_output, this_error = process.communicate()
402        retcode = process.poll()
403
404        # Enable trace on failure return while tracking down FreeBSD buildbot issues
405        trace = traceAlways
406        if not trace and retcode and sys.platform.startswith("freebsd"):
407            trace = True
408
409        with recording(test, trace) as sbuf:
410            print(file=sbuf)
411            print("os command:", shellCommand, file=sbuf)
412            print("with pid:", pid, file=sbuf)
413            print("stdout:", this_output, file=sbuf)
414            print("stderr:", this_error, file=sbuf)
415            print("retcode:", retcode, file=sbuf)
416            print(file=sbuf)
417
418        if retcode:
419            cmd = kwargs.get("args")
420            if cmd is None:
421                cmd = shellCommand
422            raise CalledProcessError(retcode, cmd)
423        output = output + this_output
424        error = error + this_error
425    return (output, error)
426
427def getsource_if_available(obj):
428    """
429    Return the text of the source code for an object if available.  Otherwise,
430    a print representation is returned.
431    """
432    import inspect
433    try:
434        return inspect.getsource(obj)
435    except:
436        return repr(obj)
437
438def builder_module():
439    if sys.platform.startswith("freebsd"):
440        return __import__("builder_freebsd")
441    if sys.platform.startswith("netbsd"):
442        return __import__("builder_netbsd")
443    if sys.platform.startswith("linux"):
444        # sys.platform with Python-3.x returns 'linux', but with
445        # Python-2.x it returns 'linux2'.
446        return __import__("builder_linux")
447    return __import__("builder_" + sys.platform)
448
449
450class Base(unittest2.TestCase):
451    """
452    Abstract base for performing lldb (see TestBase) or other generic tests (see
453    BenchBase for one example).  lldbtest.Base works with the test driver to
454    accomplish things.
455
456    """
457
458    # The concrete subclass should override this attribute.
459    mydir = None
460
461    # Keep track of the old current working directory.
462    oldcwd = None
463
464    @staticmethod
465    def compute_mydir(test_file):
466        '''Subclasses should call this function to correctly calculate the required "mydir" attribute as follows:
467
468            mydir = TestBase.compute_mydir(__file__)'''
469        test_dir = os.path.dirname(test_file)
470        return test_dir[len(os.environ["LLDB_TEST"])+1:]
471
472    def TraceOn(self):
473        """Returns True if we are in trace mode (tracing detailed test execution)."""
474        return traceAlways
475
476    @classmethod
477    def setUpClass(cls):
478        """
479        Python unittest framework class setup fixture.
480        Do current directory manipulation.
481        """
482        # Fail fast if 'mydir' attribute is not overridden.
483        if not cls.mydir or len(cls.mydir) == 0:
484            raise Exception("Subclasses must override the 'mydir' attribute.")
485
486        # Save old working directory.
487        cls.oldcwd = os.getcwd()
488
489        # Change current working directory if ${LLDB_TEST} is defined.
490        # See also dotest.py which sets up ${LLDB_TEST}.
491        if ("LLDB_TEST" in os.environ):
492            full_dir = os.path.join(os.environ["LLDB_TEST"], cls.mydir)
493            if traceAlways:
494                print("Change dir to:", full_dir, file=sys.stderr)
495            os.chdir(os.path.join(os.environ["LLDB_TEST"], cls.mydir))
496
497        if debug_confirm_directory_exclusivity:
498            import lock
499            cls.dir_lock = lock.Lock(os.path.join(full_dir, ".dirlock"))
500            try:
501                cls.dir_lock.try_acquire()
502                # write the class that owns the lock into the lock file
503                cls.dir_lock.handle.write(cls.__name__)
504            except IOError as ioerror:
505                # nothing else should have this directory lock
506                # wait here until we get a lock
507                cls.dir_lock.acquire()
508                # read the previous owner from the lock file
509                lock_id = cls.dir_lock.handle.read()
510                print("LOCK ERROR: {} wants to lock '{}' but it is already locked by '{}'".format(cls.__name__, full_dir, lock_id), file=sys.stderr)
511                raise ioerror
512
513        # Set platform context.
514        cls.platformContext = lldbplatformutil.createPlatformContext()
515
516    @classmethod
517    def tearDownClass(cls):
518        """
519        Python unittest framework class teardown fixture.
520        Do class-wide cleanup.
521        """
522
523        if doCleanup:
524            # First, let's do the platform-specific cleanup.
525            module = builder_module()
526            module.cleanup()
527
528            # Subclass might have specific cleanup function defined.
529            if getattr(cls, "classCleanup", None):
530                if traceAlways:
531                    print("Call class-specific cleanup function for class:", cls, file=sys.stderr)
532                try:
533                    cls.classCleanup()
534                except:
535                    exc_type, exc_value, exc_tb = sys.exc_info()
536                    traceback.print_exception(exc_type, exc_value, exc_tb)
537
538        if debug_confirm_directory_exclusivity:
539            cls.dir_lock.release()
540            del cls.dir_lock
541
542        # Restore old working directory.
543        if traceAlways:
544            print("Restore dir to:", cls.oldcwd, file=sys.stderr)
545        os.chdir(cls.oldcwd)
546
547    @classmethod
548    def skipLongRunningTest(cls):
549        """
550        By default, we skip long running test case.
551        This can be overridden by passing '-l' to the test driver (dotest.py).
552        """
553        if "LLDB_SKIP_LONG_RUNNING_TEST" in os.environ and "NO" == os.environ["LLDB_SKIP_LONG_RUNNING_TEST"]:
554            return False
555        else:
556            return True
557
558    def enableLogChannelsForCurrentTest(self):
559        if len(lldbtest_config.channels) == 0:
560            return
561
562        # if debug channels are specified in lldbtest_config.channels,
563        # create a new set of log files for every test
564        log_basename = self.getLogBasenameForCurrentTest()
565
566        # confirm that the file is writeable
567        host_log_path = "{}-host.log".format(log_basename)
568        open(host_log_path, 'w').close()
569
570        log_enable = "log enable -Tpn -f {} ".format(host_log_path)
571        for channel_with_categories in lldbtest_config.channels:
572            channel_then_categories = channel_with_categories.split(' ', 1)
573            channel = channel_then_categories[0]
574            if len(channel_then_categories) > 1:
575                categories = channel_then_categories[1]
576            else:
577                categories = "default"
578
579            if channel == "gdb-remote":
580                # communicate gdb-remote categories to debugserver
581                os.environ["LLDB_DEBUGSERVER_LOG_FLAGS"] = categories
582
583            self.ci.HandleCommand(log_enable + channel_with_categories, self.res)
584            if not self.res.Succeeded():
585                raise Exception('log enable failed (check LLDB_LOG_OPTION env variable)')
586
587        # Communicate log path name to debugserver & lldb-server
588        server_log_path = "{}-server.log".format(log_basename)
589        open(server_log_path, 'w').close()
590        os.environ["LLDB_DEBUGSERVER_LOG_FILE"] = server_log_path
591
592        # Communicate channels to lldb-server
593        os.environ["LLDB_SERVER_LOG_CHANNELS"] = ":".join(lldbtest_config.channels)
594
595        if len(lldbtest_config.channels) == 0:
596            return
597
598    def disableLogChannelsForCurrentTest(self):
599        # close all log files that we opened
600        for channel_and_categories in lldbtest_config.channels:
601            # channel format - <channel-name> [<category0> [<category1> ...]]
602            channel = channel_and_categories.split(' ', 1)[0]
603            self.ci.HandleCommand("log disable " + channel, self.res)
604            if not self.res.Succeeded():
605                raise Exception('log disable failed (check LLDB_LOG_OPTION env variable)')
606
607    def setUp(self):
608        """Fixture for unittest test case setup.
609
610        It works with the test driver to conditionally skip tests and does other
611        initializations."""
612        #import traceback
613        #traceback.print_stack()
614
615        if "LIBCXX_PATH" in os.environ:
616            self.libcxxPath = os.environ["LIBCXX_PATH"]
617        else:
618            self.libcxxPath = None
619
620        if "LLDBMI_EXEC" in os.environ:
621            self.lldbMiExec = os.environ["LLDBMI_EXEC"]
622        else:
623            self.lldbMiExec = None
624
625        # If we spawn an lldb process for test (via pexpect), do not load the
626        # init file unless told otherwise.
627        if "NO_LLDBINIT" in os.environ and "NO" == os.environ["NO_LLDBINIT"]:
628            self.lldbOption = ""
629        else:
630            self.lldbOption = "--no-lldbinit"
631
632        # Assign the test method name to self.testMethodName.
633        #
634        # For an example of the use of this attribute, look at test/types dir.
635        # There are a bunch of test cases under test/types and we don't want the
636        # module cacheing subsystem to be confused with executable name "a.out"
637        # used for all the test cases.
638        self.testMethodName = self._testMethodName
639
640        # This is for the case of directly spawning 'lldb'/'gdb' and interacting
641        # with it using pexpect.
642        self.child = None
643        self.child_prompt = "(lldb) "
644        # If the child is interacting with the embedded script interpreter,
645        # there are two exits required during tear down, first to quit the
646        # embedded script interpreter and second to quit the lldb command
647        # interpreter.
648        self.child_in_script_interpreter = False
649
650        # These are for customized teardown cleanup.
651        self.dict = None
652        self.doTearDownCleanup = False
653        # And in rare cases where there are multiple teardown cleanups.
654        self.dicts = []
655        self.doTearDownCleanups = False
656
657        # List of spawned subproces.Popen objects
658        self.subprocesses = []
659
660        # List of forked process PIDs
661        self.forkedProcessPids = []
662
663        # Create a string buffer to record the session info, to be dumped into a
664        # test case specific file if test failure is encountered.
665        self.log_basename = self.getLogBasenameForCurrentTest()
666
667        session_file = "{}.log".format(self.log_basename)
668        # Python 3 doesn't support unbuffered I/O in text mode.  Open buffered.
669        self.session = encoded_file.open(session_file, "utf-8", mode="w")
670
671        # Optimistically set __errored__, __failed__, __expected__ to False
672        # initially.  If the test errored/failed, the session info
673        # (self.session) is then dumped into a session specific file for
674        # diagnosis.
675        self.__cleanup_errored__ = False
676        self.__errored__    = False
677        self.__failed__     = False
678        self.__expected__   = False
679        # We are also interested in unexpected success.
680        self.__unexpected__ = False
681        # And skipped tests.
682        self.__skipped__ = False
683
684        # See addTearDownHook(self, hook) which allows the client to add a hook
685        # function to be run during tearDown() time.
686        self.hooks = []
687
688        # See HideStdout(self).
689        self.sys_stdout_hidden = False
690
691        if self.platformContext:
692            # set environment variable names for finding shared libraries
693            self.dylibPath = self.platformContext.shlib_environment_var
694
695        # Create the debugger instance if necessary.
696        try:
697            self.dbg = lldb.DBG
698        except AttributeError:
699            self.dbg = lldb.SBDebugger.Create()
700
701        if not self.dbg:
702            raise Exception('Invalid debugger instance')
703
704        # Retrieve the associated command interpreter instance.
705        self.ci = self.dbg.GetCommandInterpreter()
706        if not self.ci:
707            raise Exception('Could not get the command interpreter')
708
709        # And the result object.
710        self.res = lldb.SBCommandReturnObject()
711
712        self.enableLogChannelsForCurrentTest()
713
714        #Initialize debug_info
715        self.debug_info = None
716
717    def setAsync(self, value):
718        """ Sets async mode to True/False and ensures it is reset after the testcase completes."""
719        old_async = self.dbg.GetAsync()
720        self.dbg.SetAsync(value)
721        self.addTearDownHook(lambda: self.dbg.SetAsync(old_async))
722
723    def cleanupSubprocesses(self):
724        # Ensure any subprocesses are cleaned up
725        for p in self.subprocesses:
726            p.terminate()
727            del p
728        del self.subprocesses[:]
729        # Ensure any forked processes are cleaned up
730        for pid in self.forkedProcessPids:
731            if os.path.exists("/proc/" + str(pid)):
732                os.kill(pid, signal.SIGTERM)
733
734    def spawnSubprocess(self, executable, args=[], install_remote=True):
735        """ Creates a subprocess.Popen object with the specified executable and arguments,
736            saves it in self.subprocesses, and returns the object.
737            NOTE: if using this function, ensure you also call:
738
739              self.addTearDownHook(self.cleanupSubprocesses)
740
741            otherwise the test suite will leak processes.
742        """
743        proc = _RemoteProcess(install_remote) if lldb.remote_platform else _LocalProcess(self.TraceOn())
744        proc.launch(executable, args)
745        self.subprocesses.append(proc)
746        return proc
747
748    def forkSubprocess(self, executable, args=[]):
749        """ Fork a subprocess with its own group ID.
750            NOTE: if using this function, ensure you also call:
751
752              self.addTearDownHook(self.cleanupSubprocesses)
753
754            otherwise the test suite will leak processes.
755        """
756        child_pid = os.fork()
757        if child_pid == 0:
758            # If more I/O support is required, this can be beefed up.
759            fd = os.open(os.devnull, os.O_RDWR)
760            os.dup2(fd, 1)
761            os.dup2(fd, 2)
762            # This call causes the child to have its of group ID
763            os.setpgid(0,0)
764            os.execvp(executable, [executable] + args)
765        # Give the child time to get through the execvp() call
766        time.sleep(0.1)
767        self.forkedProcessPids.append(child_pid)
768        return child_pid
769
770    def HideStdout(self):
771        """Hide output to stdout from the user.
772
773        During test execution, there might be cases where we don't want to show the
774        standard output to the user.  For example,
775
776            self.runCmd(r'''sc print("\n\n\tHello!\n")''')
777
778        tests whether command abbreviation for 'script' works or not.  There is no
779        need to show the 'Hello' output to the user as long as the 'script' command
780        succeeds and we are not in TraceOn() mode (see the '-t' option).
781
782        In this case, the test method calls self.HideStdout(self) to redirect the
783        sys.stdout to a null device, and restores the sys.stdout upon teardown.
784
785        Note that you should only call this method at most once during a test case
786        execution.  Any subsequent call has no effect at all."""
787        if self.sys_stdout_hidden:
788            return
789
790        self.sys_stdout_hidden = True
791        old_stdout = sys.stdout
792        sys.stdout = open(os.devnull, 'w')
793        def restore_stdout():
794            sys.stdout = old_stdout
795        self.addTearDownHook(restore_stdout)
796
797    # =======================================================================
798    # Methods for customized teardown cleanups as well as execution of hooks.
799    # =======================================================================
800
801    def setTearDownCleanup(self, dictionary=None):
802        """Register a cleanup action at tearDown() time with a dictinary"""
803        self.dict = dictionary
804        self.doTearDownCleanup = True
805
806    def addTearDownCleanup(self, dictionary):
807        """Add a cleanup action at tearDown() time with a dictinary"""
808        self.dicts.append(dictionary)
809        self.doTearDownCleanups = True
810
811    def addTearDownHook(self, hook):
812        """
813        Add a function to be run during tearDown() time.
814
815        Hooks are executed in a first come first serve manner.
816        """
817        if six.callable(hook):
818            with recording(self, traceAlways) as sbuf:
819                print("Adding tearDown hook:", getsource_if_available(hook), file=sbuf)
820            self.hooks.append(hook)
821
822        return self
823
824    def deletePexpectChild(self):
825        # This is for the case of directly spawning 'lldb' and interacting with it
826        # using pexpect.
827        if self.child and self.child.isalive():
828            import pexpect
829            with recording(self, traceAlways) as sbuf:
830                print("tearing down the child process....", file=sbuf)
831            try:
832                if self.child_in_script_interpreter:
833                    self.child.sendline('quit()')
834                    self.child.expect_exact(self.child_prompt)
835                self.child.sendline('settings set interpreter.prompt-on-quit false')
836                self.child.sendline('quit')
837                self.child.expect(pexpect.EOF)
838            except (ValueError, pexpect.ExceptionPexpect):
839                # child is already terminated
840                pass
841            except OSError as exception:
842                import errno
843                if exception.errno != errno.EIO:
844                    # unexpected error
845                    raise
846                # child is already terminated
847                pass
848            finally:
849                # Give it one final blow to make sure the child is terminated.
850                self.child.close()
851
852    def tearDown(self):
853        """Fixture for unittest test case teardown."""
854        #import traceback
855        #traceback.print_stack()
856
857        self.deletePexpectChild()
858
859        # Check and run any hook functions.
860        for hook in reversed(self.hooks):
861            with recording(self, traceAlways) as sbuf:
862                print("Executing tearDown hook:", getsource_if_available(hook), file=sbuf)
863            if funcutils.requires_self(hook):
864                hook(self)
865            else:
866                hook() # try the plain call and hope it works
867
868        del self.hooks
869
870        # Perform registered teardown cleanup.
871        if doCleanup and self.doTearDownCleanup:
872            self.cleanup(dictionary=self.dict)
873
874        # In rare cases where there are multiple teardown cleanups added.
875        if doCleanup and self.doTearDownCleanups:
876            if self.dicts:
877                for dict in reversed(self.dicts):
878                    self.cleanup(dictionary=dict)
879
880        self.disableLogChannelsForCurrentTest()
881
882    # =========================================================
883    # Various callbacks to allow introspection of test progress
884    # =========================================================
885
886    def markError(self):
887        """Callback invoked when an error (unexpected exception) errored."""
888        self.__errored__ = True
889        with recording(self, False) as sbuf:
890            # False because there's no need to write "ERROR" to the stderr twice.
891            # Once by the Python unittest framework, and a second time by us.
892            print("ERROR", file=sbuf)
893
894    def markCleanupError(self):
895        """Callback invoked when an error occurs while a test is cleaning up."""
896        self.__cleanup_errored__ = True
897        with recording(self, False) as sbuf:
898            # False because there's no need to write "CLEANUP_ERROR" to the stderr twice.
899            # Once by the Python unittest framework, and a second time by us.
900            print("CLEANUP_ERROR", file=sbuf)
901
902    def markFailure(self):
903        """Callback invoked when a failure (test assertion failure) occurred."""
904        self.__failed__ = True
905        with recording(self, False) as sbuf:
906            # False because there's no need to write "FAIL" to the stderr twice.
907            # Once by the Python unittest framework, and a second time by us.
908            print("FAIL", file=sbuf)
909
910    def markExpectedFailure(self,err,bugnumber):
911        """Callback invoked when an expected failure/error occurred."""
912        self.__expected__ = True
913        with recording(self, False) as sbuf:
914            # False because there's no need to write "expected failure" to the
915            # stderr twice.
916            # Once by the Python unittest framework, and a second time by us.
917            if bugnumber == None:
918                print("expected failure", file=sbuf)
919            else:
920                print("expected failure (problem id:" + str(bugnumber) + ")", file=sbuf)
921
922    def markSkippedTest(self):
923        """Callback invoked when a test is skipped."""
924        self.__skipped__ = True
925        with recording(self, False) as sbuf:
926            # False because there's no need to write "skipped test" to the
927            # stderr twice.
928            # Once by the Python unittest framework, and a second time by us.
929            print("skipped test", file=sbuf)
930
931    def markUnexpectedSuccess(self, bugnumber):
932        """Callback invoked when an unexpected success occurred."""
933        self.__unexpected__ = True
934        with recording(self, False) as sbuf:
935            # False because there's no need to write "unexpected success" to the
936            # stderr twice.
937            # Once by the Python unittest framework, and a second time by us.
938            if bugnumber == None:
939                print("unexpected success", file=sbuf)
940            else:
941                print("unexpected success (problem id:" + str(bugnumber) + ")", file=sbuf)
942
943    def getRerunArgs(self):
944        return " -f %s.%s" % (self.__class__.__name__, self._testMethodName)
945
946    def getLogBasenameForCurrentTest(self, prefix=None):
947        """
948        returns a partial path that can be used as the beginning of the name of multiple
949        log files pertaining to this test
950
951        <session-dir>/<arch>-<compiler>-<test-file>.<test-class>.<test-method>
952        """
953        dname = os.path.join(os.environ["LLDB_TEST"],
954                     os.environ["LLDB_SESSION_DIRNAME"])
955        if not os.path.isdir(dname):
956            os.mkdir(dname)
957
958        compiler = self.getCompiler()
959
960        if compiler[1] == ':':
961            compiler = compiler[2:]
962        if os.path.altsep is not None:
963            compiler = compiler.replace(os.path.altsep, os.path.sep)
964
965        fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), "_".join(compiler.split(os.path.sep)))
966        if len(fname) > 200:
967            fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), compiler.split(os.path.sep)[-1])
968
969        if prefix is not None:
970            fname = "{}-{}".format(prefix, fname)
971
972        return os.path.join(dname, fname)
973
974    def dumpSessionInfo(self):
975        """
976        Dump the debugger interactions leading to a test error/failure.  This
977        allows for more convenient postmortem analysis.
978
979        See also LLDBTestResult (dotest.py) which is a singlton class derived
980        from TextTestResult and overwrites addError, addFailure, and
981        addExpectedFailure methods to allow us to to mark the test instance as
982        such.
983        """
984
985        # We are here because self.tearDown() detected that this test instance
986        # either errored or failed.  The lldb.test_result singleton contains
987        # two lists (erros and failures) which get populated by the unittest
988        # framework.  Look over there for stack trace information.
989        #
990        # The lists contain 2-tuples of TestCase instances and strings holding
991        # formatted tracebacks.
992        #
993        # See http://docs.python.org/library/unittest.html#unittest.TestResult.
994
995        # output tracebacks into session
996        pairs = []
997        if self.__errored__:
998            pairs = configuration.test_result.errors
999            prefix = 'Error'
1000        elif self.__cleanup_errored__:
1001            pairs = configuration.test_result.cleanup_errors
1002            prefix = 'CleanupError'
1003        elif self.__failed__:
1004            pairs = configuration.test_result.failures
1005            prefix = 'Failure'
1006        elif self.__expected__:
1007            pairs = configuration.test_result.expectedFailures
1008            prefix = 'ExpectedFailure'
1009        elif self.__skipped__:
1010            prefix = 'SkippedTest'
1011        elif self.__unexpected__:
1012            prefix = 'UnexpectedSuccess'
1013        else:
1014            prefix = 'Success'
1015
1016        if not self.__unexpected__ and not self.__skipped__:
1017            for test, traceback in pairs:
1018                if test is self:
1019                    print(traceback, file=self.session)
1020
1021        # put footer (timestamp/rerun instructions) into session
1022        testMethod = getattr(self, self._testMethodName)
1023        if getattr(testMethod, "__benchmarks_test__", False):
1024            benchmarks = True
1025        else:
1026            benchmarks = False
1027
1028        import datetime
1029        print("Session info generated @", datetime.datetime.now().ctime(), file=self.session)
1030        print("To rerun this test, issue the following command from the 'test' directory:\n", file=self.session)
1031        print("./dotest.py %s -v %s %s" % (self.getRunOptions(),
1032                                                 ('+b' if benchmarks else '-t'),
1033                                                 self.getRerunArgs()), file=self.session)
1034        self.session.close()
1035        del self.session
1036
1037        # process the log files
1038        log_files_for_this_test = glob.glob(self.log_basename + "*")
1039
1040        if prefix != 'Success' or lldbtest_config.log_success:
1041            # keep all log files, rename them to include prefix
1042            dst_log_basename = self.getLogBasenameForCurrentTest(prefix)
1043            for src in log_files_for_this_test:
1044                if os.path.isfile(src):
1045                    dst = src.replace(self.log_basename, dst_log_basename)
1046                    if os.name == "nt" and os.path.isfile(dst):
1047                        # On Windows, renaming a -> b will throw an exception if b exists.  On non-Windows platforms
1048                        # it silently replaces the destination.  Ultimately this means that atomic renames are not
1049                        # guaranteed to be possible on Windows, but we need this to work anyway, so just remove the
1050                        # destination first if it already exists.
1051                        remove_file(dst)
1052
1053                    os.rename(src, dst)
1054        else:
1055            # success!  (and we don't want log files) delete log files
1056            for log_file in log_files_for_this_test:
1057                remove_file(log_file)
1058
1059    # ====================================================
1060    # Config. methods supported through a plugin interface
1061    # (enables reading of the current test configuration)
1062    # ====================================================
1063
1064    def getArchitecture(self):
1065        """Returns the architecture in effect the test suite is running with."""
1066        module = builder_module()
1067        arch = module.getArchitecture()
1068        if arch == 'amd64':
1069            arch = 'x86_64'
1070        return arch
1071
1072    def getLldbArchitecture(self):
1073        """Returns the architecture of the lldb binary."""
1074        if not hasattr(self, 'lldbArchitecture'):
1075
1076            # spawn local process
1077            command = [
1078                lldbtest_config.lldbExec,
1079                "-o",
1080                "file " + lldbtest_config.lldbExec,
1081                "-o",
1082                "quit"
1083            ]
1084
1085            output = check_output(command)
1086            str = output.decode("utf-8");
1087
1088            for line in str.splitlines():
1089                m = re.search("Current executable set to '.*' \\((.*)\\)\\.", line)
1090                if m:
1091                    self.lldbArchitecture = m.group(1)
1092                    break
1093
1094        return self.lldbArchitecture
1095
1096    def getCompiler(self):
1097        """Returns the compiler in effect the test suite is running with."""
1098        module = builder_module()
1099        return module.getCompiler()
1100
1101    def getCompilerBinary(self):
1102        """Returns the compiler binary the test suite is running with."""
1103        return self.getCompiler().split()[0]
1104
1105    def getCompilerVersion(self):
1106        """ Returns a string that represents the compiler version.
1107            Supports: llvm, clang.
1108        """
1109        version = 'unknown'
1110
1111        compiler = self.getCompilerBinary()
1112        version_output = system([[compiler, "-v"]])[1]
1113        for line in version_output.split(os.linesep):
1114            m = re.search('version ([0-9\.]+)', line)
1115            if m:
1116                version = m.group(1)
1117        return version
1118
1119    def getGoCompilerVersion(self):
1120        """ Returns a string that represents the go compiler version, or None if go is not found.
1121        """
1122        compiler = which("go")
1123        if compiler:
1124            version_output = system([[compiler, "version"]])[0]
1125            for line in version_output.split(os.linesep):
1126                m = re.search('go version (devel|go\\S+)', line)
1127                if m:
1128                    return m.group(1)
1129        return None
1130
1131    def platformIsDarwin(self):
1132        """Returns true if the OS triple for the selected platform is any valid apple OS"""
1133        return lldbplatformutil.platformIsDarwin()
1134
1135    def getPlatform(self):
1136        """Returns the target platform the test suite is running on."""
1137        return lldbplatformutil.getPlatform()
1138
1139    def isIntelCompiler(self):
1140        """ Returns true if using an Intel (ICC) compiler, false otherwise. """
1141        return any([x in self.getCompiler() for x in ["icc", "icpc", "icl"]])
1142
1143    def expectedCompilerVersion(self, compiler_version):
1144        """Returns True iff compiler_version[1] matches the current compiler version.
1145           Use compiler_version[0] to specify the operator used to determine if a match has occurred.
1146           Any operator other than the following defaults to an equality test:
1147             '>', '>=', "=>", '<', '<=', '=<', '!=', "!" or 'not'
1148        """
1149        if (compiler_version == None):
1150            return True
1151        operator = str(compiler_version[0])
1152        version = compiler_version[1]
1153
1154        if (version == None):
1155            return True
1156        if (operator == '>'):
1157            return self.getCompilerVersion() > version
1158        if (operator == '>=' or operator == '=>'):
1159            return self.getCompilerVersion() >= version
1160        if (operator == '<'):
1161            return self.getCompilerVersion() < version
1162        if (operator == '<=' or operator == '=<'):
1163            return self.getCompilerVersion() <= version
1164        if (operator == '!=' or operator == '!' or operator == 'not'):
1165            return str(version) not in str(self.getCompilerVersion())
1166        return str(version) in str(self.getCompilerVersion())
1167
1168    def expectedCompiler(self, compilers):
1169        """Returns True iff any element of compilers is a sub-string of the current compiler."""
1170        if (compilers == None):
1171            return True
1172
1173        for compiler in compilers:
1174            if compiler in self.getCompiler():
1175                return True
1176
1177        return False
1178
1179    def expectedArch(self, archs):
1180        """Returns True iff any element of archs is a sub-string of the current architecture."""
1181        if (archs == None):
1182            return True
1183
1184        for arch in archs:
1185            if arch in self.getArchitecture():
1186                return True
1187
1188        return False
1189
1190    def getRunOptions(self):
1191        """Command line option for -A and -C to run this test again, called from
1192        self.dumpSessionInfo()."""
1193        arch = self.getArchitecture()
1194        comp = self.getCompiler()
1195        if arch:
1196            option_str = "-A " + arch
1197        else:
1198            option_str = ""
1199        if comp:
1200            option_str += " -C " + comp
1201        return option_str
1202
1203    # ==================================================
1204    # Build methods supported through a plugin interface
1205    # ==================================================
1206
1207    def getstdlibFlag(self):
1208        """ Returns the proper -stdlib flag, or empty if not required."""
1209        if self.platformIsDarwin() or self.getPlatform() == "freebsd":
1210            stdlibflag = "-stdlib=libc++"
1211        else: # this includes NetBSD
1212            stdlibflag = ""
1213        return stdlibflag
1214
1215    def getstdFlag(self):
1216        """ Returns the proper stdflag. """
1217        if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
1218          stdflag = "-std=c++0x"
1219        else:
1220          stdflag = "-std=c++11"
1221        return stdflag
1222
1223    def buildDriver(self, sources, exe_name):
1224        """ Platform-specific way to build a program that links with LLDB (via the liblldb.so
1225            or LLDB.framework).
1226        """
1227
1228        stdflag = self.getstdFlag()
1229        stdlibflag = self.getstdlibFlag()
1230
1231        lib_dir = os.environ["LLDB_LIB_DIR"]
1232        if sys.platform.startswith("darwin"):
1233            dsym = os.path.join(lib_dir, 'LLDB.framework', 'LLDB')
1234            d = {'CXX_SOURCES' : sources,
1235                 'EXE' : exe_name,
1236                 'CFLAGS_EXTRAS' : "%s %s" % (stdflag, stdlibflag),
1237                 'FRAMEWORK_INCLUDES' : "-F%s" % lib_dir,
1238                 'LD_EXTRAS' : "%s -Wl,-rpath,%s" % (dsym, lib_dir),
1239                }
1240        elif sys.platform.rstrip('0123456789') in ('freebsd', 'linux', 'netbsd') or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
1241            d = {'CXX_SOURCES' : sources,
1242                 'EXE' : exe_name,
1243                 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
1244                 'LD_EXTRAS' : "-L%s -llldb" % lib_dir}
1245        elif sys.platform.startswith('win'):
1246            d = {'CXX_SOURCES' : sources,
1247                 'EXE' : exe_name,
1248                 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
1249                 'LD_EXTRAS' : "-L%s -lliblldb" % os.environ["LLDB_IMPLIB_DIR"]}
1250        if self.TraceOn():
1251            print("Building LLDB Driver (%s) from sources %s" % (exe_name, sources))
1252
1253        self.buildDefault(dictionary=d)
1254
1255    def buildLibrary(self, sources, lib_name):
1256        """Platform specific way to build a default library. """
1257
1258        stdflag = self.getstdFlag()
1259
1260        lib_dir = os.environ["LLDB_LIB_DIR"]
1261        if self.platformIsDarwin():
1262            dsym = os.path.join(lib_dir, 'LLDB.framework', 'LLDB')
1263            d = {'DYLIB_CXX_SOURCES' : sources,
1264                 'DYLIB_NAME' : lib_name,
1265                 'CFLAGS_EXTRAS' : "%s -stdlib=libc++" % stdflag,
1266                 'FRAMEWORK_INCLUDES' : "-F%s" % lib_dir,
1267                 'LD_EXTRAS' : "%s -Wl,-rpath,%s -dynamiclib" % (dsym, lib_dir),
1268                }
1269        elif self.getPlatform() in ('freebsd', 'linux', 'netbsd') or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
1270            d = {'DYLIB_CXX_SOURCES' : sources,
1271                 'DYLIB_NAME' : lib_name,
1272                 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
1273                 'LD_EXTRAS' : "-shared -L%s -llldb" % lib_dir}
1274        elif self.getPlatform() == 'windows':
1275            d = {'DYLIB_CXX_SOURCES' : sources,
1276                 'DYLIB_NAME' : lib_name,
1277                 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
1278                 'LD_EXTRAS' : "-shared -l%s\liblldb.lib" % self.os.environ["LLDB_IMPLIB_DIR"]}
1279        if self.TraceOn():
1280            print("Building LLDB Library (%s) from sources %s" % (lib_name, sources))
1281
1282        self.buildDefault(dictionary=d)
1283
1284    def buildProgram(self, sources, exe_name):
1285        """ Platform specific way to build an executable from C/C++ sources. """
1286        d = {'CXX_SOURCES' : sources,
1287             'EXE' : exe_name}
1288        self.buildDefault(dictionary=d)
1289
1290    def buildDefault(self, architecture=None, compiler=None, dictionary=None, clean=True):
1291        """Platform specific way to build the default binaries."""
1292        module = builder_module()
1293        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1294        if not module.buildDefault(self, architecture, compiler, dictionary, clean):
1295            raise Exception("Don't know how to build default binary")
1296
1297    def buildDsym(self, architecture=None, compiler=None, dictionary=None, clean=True):
1298        """Platform specific way to build binaries with dsym info."""
1299        module = builder_module()
1300        if not module.buildDsym(self, architecture, compiler, dictionary, clean):
1301            raise Exception("Don't know how to build binary with dsym")
1302
1303    def buildDwarf(self, architecture=None, compiler=None, dictionary=None, clean=True):
1304        """Platform specific way to build binaries with dwarf maps."""
1305        module = builder_module()
1306        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1307        if not module.buildDwarf(self, architecture, compiler, dictionary, clean):
1308            raise Exception("Don't know how to build binary with dwarf")
1309
1310    def buildDwo(self, architecture=None, compiler=None, dictionary=None, clean=True):
1311        """Platform specific way to build binaries with dwarf maps."""
1312        module = builder_module()
1313        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1314        if not module.buildDwo(self, architecture, compiler, dictionary, clean):
1315            raise Exception("Don't know how to build binary with dwo")
1316
1317    def buildGo(self):
1318        """Build the default go binary.
1319        """
1320        system([[which('go'), 'build -gcflags "-N -l" -o a.out main.go']])
1321
1322    def signBinary(self, binary_path):
1323        if sys.platform.startswith("darwin"):
1324            codesign_cmd = "codesign --force --sign lldb_codesign %s" % (binary_path)
1325            call(codesign_cmd, shell=True)
1326
1327    def findBuiltClang(self):
1328        """Tries to find and use Clang from the build directory as the compiler (instead of the system compiler)."""
1329        paths_to_try = [
1330          "llvm-build/Release+Asserts/x86_64/Release+Asserts/bin/clang",
1331          "llvm-build/Debug+Asserts/x86_64/Debug+Asserts/bin/clang",
1332          "llvm-build/Release/x86_64/Release/bin/clang",
1333          "llvm-build/Debug/x86_64/Debug/bin/clang",
1334        ]
1335        lldb_root_path = os.path.join(os.path.dirname(__file__), "..", "..", "..", "..")
1336        for p in paths_to_try:
1337            path = os.path.join(lldb_root_path, p)
1338            if os.path.exists(path):
1339                return path
1340
1341        # Tries to find clang at the same folder as the lldb
1342        path = os.path.join(os.path.dirname(lldbtest_config.lldbExec), "clang")
1343        if os.path.exists(path):
1344            return path
1345
1346        return os.environ["CC"]
1347
1348    def getBuildFlags(self, use_cpp11=True, use_libcxx=False, use_libstdcxx=False):
1349        """ Returns a dictionary (which can be provided to build* functions above) which
1350            contains OS-specific build flags.
1351        """
1352        cflags = ""
1353        ldflags = ""
1354
1355        # On Mac OS X, unless specifically requested to use libstdc++, use libc++
1356        if not use_libstdcxx and self.platformIsDarwin():
1357            use_libcxx = True
1358
1359        if use_libcxx and self.libcxxPath:
1360            cflags += "-stdlib=libc++ "
1361            if self.libcxxPath:
1362                libcxxInclude = os.path.join(self.libcxxPath, "include")
1363                libcxxLib = os.path.join(self.libcxxPath, "lib")
1364                if os.path.isdir(libcxxInclude) and os.path.isdir(libcxxLib):
1365                    cflags += "-nostdinc++ -I%s -L%s -Wl,-rpath,%s " % (libcxxInclude, libcxxLib, libcxxLib)
1366
1367        if use_cpp11:
1368            cflags += "-std="
1369            if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
1370                cflags += "c++0x"
1371            else:
1372                cflags += "c++11"
1373        if self.platformIsDarwin() or self.getPlatform() == "freebsd":
1374            cflags += " -stdlib=libc++"
1375        elif self.getPlatform() == "netbsd":
1376            cflags += " -stdlib=libstdc++"
1377        elif "clang" in self.getCompiler():
1378            cflags += " -stdlib=libstdc++"
1379
1380        return {'CFLAGS_EXTRAS' : cflags,
1381                'LD_EXTRAS' : ldflags,
1382               }
1383
1384    def cleanup(self, dictionary=None):
1385        """Platform specific way to do cleanup after build."""
1386        module = builder_module()
1387        if not module.cleanup(self, dictionary):
1388            raise Exception("Don't know how to do cleanup with dictionary: "+dictionary)
1389
1390    def getLLDBLibraryEnvVal(self):
1391        """ Returns the path that the OS-specific library search environment variable
1392            (self.dylibPath) should be set to in order for a program to find the LLDB
1393            library. If an environment variable named self.dylibPath is already set,
1394            the new path is appended to it and returned.
1395        """
1396        existing_library_path = os.environ[self.dylibPath] if self.dylibPath in os.environ else None
1397        lib_dir = os.environ["LLDB_LIB_DIR"]
1398        if existing_library_path:
1399            return "%s:%s" % (existing_library_path, lib_dir)
1400        elif sys.platform.startswith("darwin"):
1401            return os.path.join(lib_dir, 'LLDB.framework')
1402        else:
1403            return lib_dir
1404
1405    def getLibcPlusPlusLibs(self):
1406        if self.getPlatform() in ('freebsd', 'linux', 'netbsd'):
1407            return ['libc++.so.1']
1408        else:
1409            return ['libc++.1.dylib','libc++abi.dylib']
1410
1411# Metaclass for TestBase to change the list of test metods when a new TestCase is loaded.
1412# We change the test methods to create a new test method for each test for each debug info we are
1413# testing. The name of the new test method will be '<original-name>_<debug-info>' and with adding
1414# the new test method we remove the old method at the same time. This functionality can be
1415# supressed by at test case level setting the class attribute NO_DEBUG_INFO_TESTCASE or at test
1416# level by using the decorator @no_debug_info_test.
1417class LLDBTestCaseFactory(type):
1418    def __new__(cls, name, bases, attrs):
1419        original_testcase = super(LLDBTestCaseFactory, cls).__new__(cls, name, bases, attrs)
1420        if original_testcase.NO_DEBUG_INFO_TESTCASE:
1421            return original_testcase
1422
1423        newattrs = {}
1424        for attrname, attrvalue in attrs.items():
1425            if attrname.startswith("test") and not getattr(attrvalue, "__no_debug_info_test__", False):
1426                target_platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
1427
1428                # If any debug info categories were explicitly tagged, assume that list to be
1429                # authoritative.  If none were specified, try with all debug info formats.
1430                all_dbginfo_categories = set(test_categories.debug_info_categories)
1431                categories = set(getattr(attrvalue, "categories", [])) & all_dbginfo_categories
1432                if not categories:
1433                    categories = all_dbginfo_categories
1434
1435                supported_categories = [x for x in categories
1436                                        if test_categories.is_supported_on_platform(x, target_platform)]
1437                if "dsym" in supported_categories:
1438                    @decorators.add_test_categories(["dsym"])
1439                    @wraps(attrvalue)
1440                    def dsym_test_method(self, attrvalue=attrvalue):
1441                        self.debug_info = "dsym"
1442                        return attrvalue(self)
1443                    dsym_method_name = attrname + "_dsym"
1444                    dsym_test_method.__name__ = dsym_method_name
1445                    newattrs[dsym_method_name] = dsym_test_method
1446
1447                if "dwarf" in supported_categories:
1448                    @decorators.add_test_categories(["dwarf"])
1449                    @wraps(attrvalue)
1450                    def dwarf_test_method(self, attrvalue=attrvalue):
1451                        self.debug_info = "dwarf"
1452                        return attrvalue(self)
1453                    dwarf_method_name = attrname + "_dwarf"
1454                    dwarf_test_method.__name__ = dwarf_method_name
1455                    newattrs[dwarf_method_name] = dwarf_test_method
1456
1457                if "dwo" in supported_categories:
1458                    @decorators.add_test_categories(["dwo"])
1459                    @wraps(attrvalue)
1460                    def dwo_test_method(self, attrvalue=attrvalue):
1461                        self.debug_info = "dwo"
1462                        return attrvalue(self)
1463                    dwo_method_name = attrname + "_dwo"
1464                    dwo_test_method.__name__ = dwo_method_name
1465                    newattrs[dwo_method_name] = dwo_test_method
1466            else:
1467                newattrs[attrname] = attrvalue
1468        return super(LLDBTestCaseFactory, cls).__new__(cls, name, bases, newattrs)
1469
1470# Setup the metaclass for this class to change the list of the test methods when a new class is loaded
1471@add_metaclass(LLDBTestCaseFactory)
1472class TestBase(Base):
1473    """
1474    This abstract base class is meant to be subclassed.  It provides default
1475    implementations for setUpClass(), tearDownClass(), setUp(), and tearDown(),
1476    among other things.
1477
1478    Important things for test class writers:
1479
1480        - Overwrite the mydir class attribute, otherwise your test class won't
1481          run.  It specifies the relative directory to the top level 'test' so
1482          the test harness can change to the correct working directory before
1483          running your test.
1484
1485        - The setUp method sets up things to facilitate subsequent interactions
1486          with the debugger as part of the test.  These include:
1487              - populate the test method name
1488              - create/get a debugger set with synchronous mode (self.dbg)
1489              - get the command interpreter from with the debugger (self.ci)
1490              - create a result object for use with the command interpreter
1491                (self.res)
1492              - plus other stuffs
1493
1494        - The tearDown method tries to perform some necessary cleanup on behalf
1495          of the test to return the debugger to a good state for the next test.
1496          These include:
1497              - execute any tearDown hooks registered by the test method with
1498                TestBase.addTearDownHook(); examples can be found in
1499                settings/TestSettings.py
1500              - kill the inferior process associated with each target, if any,
1501                and, then delete the target from the debugger's target list
1502              - perform build cleanup before running the next test method in the
1503                same test class; examples of registering for this service can be
1504                found in types/TestIntegerTypes.py with the call:
1505                    - self.setTearDownCleanup(dictionary=d)
1506
1507        - Similarly setUpClass and tearDownClass perform classwise setup and
1508          teardown fixtures.  The tearDownClass method invokes a default build
1509          cleanup for the entire test class;  also, subclasses can implement the
1510          classmethod classCleanup(cls) to perform special class cleanup action.
1511
1512        - The instance methods runCmd and expect are used heavily by existing
1513          test cases to send a command to the command interpreter and to perform
1514          string/pattern matching on the output of such command execution.  The
1515          expect method also provides a mode to peform string/pattern matching
1516          without running a command.
1517
1518        - The build methods buildDefault, buildDsym, and buildDwarf are used to
1519          build the binaries used during a particular test scenario.  A plugin
1520          should be provided for the sys.platform running the test suite.  The
1521          Mac OS X implementation is located in plugins/darwin.py.
1522    """
1523
1524    # Subclasses can set this to true (if they don't depend on debug info) to avoid running the
1525    # test multiple times with various debug info types.
1526    NO_DEBUG_INFO_TESTCASE = False
1527
1528    # Maximum allowed attempts when launching the inferior process.
1529    # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
1530    maxLaunchCount = 3;
1531
1532    # Time to wait before the next launching attempt in second(s).
1533    # Can be overridden by the LLDB_TIME_WAIT_NEXT_LAUNCH environment variable.
1534    timeWaitNextLaunch = 1.0;
1535
1536    # Returns the list of categories to which this test case belongs
1537    # by default, look for a ".categories" file, and read its contents
1538    # if no such file exists, traverse the hierarchy - we guarantee
1539    # a .categories to exist at the top level directory so we do not end up
1540    # looping endlessly - subclasses are free to define their own categories
1541    # in whatever way makes sense to them
1542    def getCategories(self):
1543        import inspect
1544        import os.path
1545        folder = inspect.getfile(self.__class__)
1546        folder = os.path.dirname(folder)
1547        while folder != '/':
1548                categories_file_name = os.path.join(folder,".categories")
1549                if os.path.exists(categories_file_name):
1550                        categories_file = open(categories_file_name,'r')
1551                        categories = categories_file.readline()
1552                        categories_file.close()
1553                        categories = str.replace(categories,'\n','')
1554                        categories = str.replace(categories,'\r','')
1555                        return categories.split(',')
1556                else:
1557                        folder = os.path.dirname(folder)
1558                        continue
1559
1560    def setUp(self):
1561        #import traceback
1562        #traceback.print_stack()
1563
1564        # Works with the test driver to conditionally skip tests via decorators.
1565        Base.setUp(self)
1566
1567        if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
1568            self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])
1569
1570        if "LLDB_TIME_WAIT_NEXT_LAUNCH" in os.environ:
1571            self.timeWaitNextLaunch = float(os.environ["LLDB_TIME_WAIT_NEXT_LAUNCH"])
1572
1573        # We want our debugger to be synchronous.
1574        self.dbg.SetAsync(False)
1575
1576        # Retrieve the associated command interpreter instance.
1577        self.ci = self.dbg.GetCommandInterpreter()
1578        if not self.ci:
1579            raise Exception('Could not get the command interpreter')
1580
1581        # And the result object.
1582        self.res = lldb.SBCommandReturnObject()
1583
1584        if lldb.remote_platform and configuration.lldb_platform_working_dir:
1585            remote_test_dir = lldbutil.join_remote_paths(
1586                    configuration.lldb_platform_working_dir,
1587                    self.getArchitecture(),
1588                    str(self.test_number),
1589                    self.mydir)
1590            error = lldb.remote_platform.MakeDirectory(remote_test_dir, 448) # 448 = 0o700
1591            if error.Success():
1592                lldb.remote_platform.SetWorkingDirectory(remote_test_dir)
1593
1594                # This function removes all files from the current working directory while leaving
1595                # the directories in place. The cleaup is required to reduce the disk space required
1596                # by the test suit while leaving the directories untached is neccessary because
1597                # sub-directories might belong to an other test
1598                def clean_working_directory():
1599                    # TODO: Make it working on Windows when we need it for remote debugging support
1600                    # TODO: Replace the heuristic to remove the files with a logic what collects the
1601                    # list of files we have to remove during test runs.
1602                    shell_cmd = lldb.SBPlatformShellCommand("rm %s/*" % remote_test_dir)
1603                    lldb.remote_platform.Run(shell_cmd)
1604                self.addTearDownHook(clean_working_directory)
1605            else:
1606                print("error: making remote directory '%s': %s" % (remote_test_dir, error))
1607
1608    def registerSharedLibrariesWithTarget(self, target, shlibs):
1609        '''If we are remotely running the test suite, register the shared libraries with the target so they get uploaded, otherwise do nothing
1610
1611        Any modules in the target that have their remote install file specification set will
1612        get uploaded to the remote host. This function registers the local copies of the
1613        shared libraries with the target and sets their remote install locations so they will
1614        be uploaded when the target is run.
1615        '''
1616        if not shlibs or not self.platformContext:
1617            return None
1618
1619        shlib_environment_var = self.platformContext.shlib_environment_var
1620        shlib_prefix = self.platformContext.shlib_prefix
1621        shlib_extension = '.' + self.platformContext.shlib_extension
1622
1623        working_dir = self.get_process_working_directory()
1624        environment = ['%s=%s' % (shlib_environment_var, working_dir)]
1625        # Add any shared libraries to our target if remote so they get
1626        # uploaded into the working directory on the remote side
1627        for name in shlibs:
1628            # The path can be a full path to a shared library, or a make file name like "Foo" for
1629            # "libFoo.dylib" or "libFoo.so", or "Foo.so" for "Foo.so" or "libFoo.so", or just a
1630            # basename like "libFoo.so". So figure out which one it is and resolve the local copy
1631            # of the shared library accordingly
1632            if os.path.exists(name):
1633                local_shlib_path = name # name is the full path to the local shared library
1634            else:
1635                # Check relative names
1636                local_shlib_path = os.path.join(os.getcwd(), shlib_prefix + name + shlib_extension)
1637                if not os.path.exists(local_shlib_path):
1638                    local_shlib_path = os.path.join(os.getcwd(), name + shlib_extension)
1639                    if not os.path.exists(local_shlib_path):
1640                        local_shlib_path = os.path.join(os.getcwd(), name)
1641
1642                # Make sure we found the local shared library in the above code
1643                self.assertTrue(os.path.exists(local_shlib_path))
1644
1645            # Add the shared library to our target
1646            shlib_module = target.AddModule(local_shlib_path, None, None, None)
1647            if lldb.remote_platform:
1648                # We must set the remote install location if we want the shared library
1649                # to get uploaded to the remote target
1650                remote_shlib_path = lldbutil.append_to_process_working_directory(os.path.basename(local_shlib_path))
1651                shlib_module.SetRemoteInstallFileSpec(lldb.SBFileSpec(remote_shlib_path, False))
1652
1653        return environment
1654
1655    # utility methods that tests can use to access the current objects
1656    def target(self):
1657        if not self.dbg:
1658            raise Exception('Invalid debugger instance')
1659        return self.dbg.GetSelectedTarget()
1660
1661    def process(self):
1662        if not self.dbg:
1663            raise Exception('Invalid debugger instance')
1664        return self.dbg.GetSelectedTarget().GetProcess()
1665
1666    def thread(self):
1667        if not self.dbg:
1668            raise Exception('Invalid debugger instance')
1669        return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread()
1670
1671    def frame(self):
1672        if not self.dbg:
1673            raise Exception('Invalid debugger instance')
1674        return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
1675
1676    def get_process_working_directory(self):
1677        '''Get the working directory that should be used when launching processes for local or remote processes.'''
1678        if lldb.remote_platform:
1679            # Remote tests set the platform working directory up in TestBase.setUp()
1680            return lldb.remote_platform.GetWorkingDirectory()
1681        else:
1682            # local tests change directory into each test subdirectory
1683            return os.getcwd()
1684
1685    def tearDown(self):
1686        #import traceback
1687        #traceback.print_stack()
1688
1689        # Ensure all the references to SB objects have gone away so that we can
1690        # be sure that all test-specific resources have been freed before we
1691        # attempt to delete the targets.
1692        gc.collect()
1693
1694        # Delete the target(s) from the debugger as a general cleanup step.
1695        # This includes terminating the process for each target, if any.
1696        # We'd like to reuse the debugger for our next test without incurring
1697        # the initialization overhead.
1698        targets = []
1699        for target in self.dbg:
1700            if target:
1701                targets.append(target)
1702                process = target.GetProcess()
1703                if process:
1704                    rc = self.invoke(process, "Kill")
1705                    self.assertTrue(rc.Success(), PROCESS_KILLED)
1706        for target in targets:
1707            self.dbg.DeleteTarget(target)
1708
1709        # Do this last, to make sure it's in reverse order from how we setup.
1710        Base.tearDown(self)
1711
1712        # This must be the last statement, otherwise teardown hooks or other
1713        # lines might depend on this still being active.
1714        del self.dbg
1715
1716    def switch_to_thread_with_stop_reason(self, stop_reason):
1717        """
1718        Run the 'thread list' command, and select the thread with stop reason as
1719        'stop_reason'.  If no such thread exists, no select action is done.
1720        """
1721        from .lldbutil import stop_reason_to_str
1722        self.runCmd('thread list')
1723        output = self.res.GetOutput()
1724        thread_line_pattern = re.compile("^[ *] thread #([0-9]+):.*stop reason = %s" %
1725                                         stop_reason_to_str(stop_reason))
1726        for line in output.splitlines():
1727            matched = thread_line_pattern.match(line)
1728            if matched:
1729                self.runCmd('thread select %s' % matched.group(1))
1730
1731    def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False):
1732        """
1733        Ask the command interpreter to handle the command and then check its
1734        return status.
1735        """
1736        # Fail fast if 'cmd' is not meaningful.
1737        if not cmd or len(cmd) == 0:
1738            raise Exception("Bad 'cmd' parameter encountered")
1739
1740        trace = (True if traceAlways else trace)
1741
1742        if cmd.startswith("target create "):
1743            cmd = cmd.replace("target create ", "file ")
1744
1745        running = (cmd.startswith("run") or cmd.startswith("process launch"))
1746
1747        for i in range(self.maxLaunchCount if running else 1):
1748            self.ci.HandleCommand(cmd, self.res, inHistory)
1749
1750            with recording(self, trace) as sbuf:
1751                print("runCmd:", cmd, file=sbuf)
1752                if not check:
1753                    print("check of return status not required", file=sbuf)
1754                if self.res.Succeeded():
1755                    print("output:", self.res.GetOutput(), file=sbuf)
1756                else:
1757                    print("runCmd failed!", file=sbuf)
1758                    print(self.res.GetError(), file=sbuf)
1759
1760            if self.res.Succeeded():
1761                break
1762            elif running:
1763                # For process launch, wait some time before possible next try.
1764                time.sleep(self.timeWaitNextLaunch)
1765                with recording(self, trace) as sbuf:
1766                    print("Command '" + cmd + "' failed!", file=sbuf)
1767
1768        if check:
1769            self.assertTrue(self.res.Succeeded(),
1770                            msg if msg else CMD_MSG(cmd))
1771
1772    def match (self, str, patterns, msg=None, trace=False, error=False, matching=True, exe=True):
1773        """run command in str, and match the result against regexp in patterns returning the match object for the first matching pattern
1774
1775        Otherwise, all the arguments have the same meanings as for the expect function"""
1776
1777        trace = (True if traceAlways else trace)
1778
1779        if exe:
1780            # First run the command.  If we are expecting error, set check=False.
1781            # Pass the assert message along since it provides more semantic info.
1782            self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error)
1783
1784            # Then compare the output against expected strings.
1785            output = self.res.GetError() if error else self.res.GetOutput()
1786
1787            # If error is True, the API client expects the command to fail!
1788            if error:
1789                self.assertFalse(self.res.Succeeded(),
1790                                 "Command '" + str + "' is expected to fail!")
1791        else:
1792            # No execution required, just compare str against the golden input.
1793            output = str
1794            with recording(self, trace) as sbuf:
1795                print("looking at:", output, file=sbuf)
1796
1797        # The heading says either "Expecting" or "Not expecting".
1798        heading = "Expecting" if matching else "Not expecting"
1799
1800        for pattern in patterns:
1801            # Match Objects always have a boolean value of True.
1802            match_object = re.search(pattern, output)
1803            matched = bool(match_object)
1804            with recording(self, trace) as sbuf:
1805                print("%s pattern: %s" % (heading, pattern), file=sbuf)
1806                print("Matched" if matched else "Not matched", file=sbuf)
1807            if matched:
1808                break
1809
1810        self.assertTrue(matched if matching else not matched,
1811                        msg if msg else EXP_MSG(str, output, exe))
1812
1813        return match_object
1814
1815    def expect(self, str, msg=None, patterns=None, startstr=None, endstr=None, substrs=None, trace=False, error=False, matching=True, exe=True, inHistory=False):
1816        """
1817        Similar to runCmd; with additional expect style output matching ability.
1818
1819        Ask the command interpreter to handle the command and then check its
1820        return status.  The 'msg' parameter specifies an informational assert
1821        message.  We expect the output from running the command to start with
1822        'startstr', matches the substrings contained in 'substrs', and regexp
1823        matches the patterns contained in 'patterns'.
1824
1825        If the keyword argument error is set to True, it signifies that the API
1826        client is expecting the command to fail.  In this case, the error stream
1827        from running the command is retrieved and compared against the golden
1828        input, instead.
1829
1830        If the keyword argument matching is set to False, it signifies that the API
1831        client is expecting the output of the command not to match the golden
1832        input.
1833
1834        Finally, the required argument 'str' represents the lldb command to be
1835        sent to the command interpreter.  In case the keyword argument 'exe' is
1836        set to False, the 'str' is treated as a string to be matched/not-matched
1837        against the golden input.
1838        """
1839        trace = (True if traceAlways else trace)
1840
1841        if exe:
1842            # First run the command.  If we are expecting error, set check=False.
1843            # Pass the assert message along since it provides more semantic info.
1844            self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error, inHistory=inHistory)
1845
1846            # Then compare the output against expected strings.
1847            output = self.res.GetError() if error else self.res.GetOutput()
1848
1849            # If error is True, the API client expects the command to fail!
1850            if error:
1851                self.assertFalse(self.res.Succeeded(),
1852                                 "Command '" + str + "' is expected to fail!")
1853        else:
1854            # No execution required, just compare str against the golden input.
1855            if isinstance(str,lldb.SBCommandReturnObject):
1856                output = str.GetOutput()
1857            else:
1858                output = str
1859            with recording(self, trace) as sbuf:
1860                print("looking at:", output, file=sbuf)
1861
1862        # The heading says either "Expecting" or "Not expecting".
1863        heading = "Expecting" if matching else "Not expecting"
1864
1865        # Start from the startstr, if specified.
1866        # If there's no startstr, set the initial state appropriately.
1867        matched = output.startswith(startstr) if startstr else (True if matching else False)
1868
1869        if startstr:
1870            with recording(self, trace) as sbuf:
1871                print("%s start string: %s" % (heading, startstr), file=sbuf)
1872                print("Matched" if matched else "Not matched", file=sbuf)
1873
1874        # Look for endstr, if specified.
1875        keepgoing = matched if matching else not matched
1876        if endstr:
1877            matched = output.endswith(endstr)
1878            with recording(self, trace) as sbuf:
1879                print("%s end string: %s" % (heading, endstr), file=sbuf)
1880                print("Matched" if matched else "Not matched", file=sbuf)
1881
1882        # Look for sub strings, if specified.
1883        keepgoing = matched if matching else not matched
1884        if substrs and keepgoing:
1885            for substr in substrs:
1886                matched = output.find(substr) != -1
1887                with recording(self, trace) as sbuf:
1888                    print("%s sub string: %s" % (heading, substr), file=sbuf)
1889                    print("Matched" if matched else "Not matched", file=sbuf)
1890                keepgoing = matched if matching else not matched
1891                if not keepgoing:
1892                    break
1893
1894        # Search for regular expression patterns, if specified.
1895        keepgoing = matched if matching else not matched
1896        if patterns and keepgoing:
1897            for pattern in patterns:
1898                # Match Objects always have a boolean value of True.
1899                matched = bool(re.search(pattern, output))
1900                with recording(self, trace) as sbuf:
1901                    print("%s pattern: %s" % (heading, pattern), file=sbuf)
1902                    print("Matched" if matched else "Not matched", file=sbuf)
1903                keepgoing = matched if matching else not matched
1904                if not keepgoing:
1905                    break
1906
1907        self.assertTrue(matched if matching else not matched,
1908                        msg if msg else EXP_MSG(str, output, exe))
1909
1910    def invoke(self, obj, name, trace=False):
1911        """Use reflection to call a method dynamically with no argument."""
1912        trace = (True if traceAlways else trace)
1913
1914        method = getattr(obj, name)
1915        import inspect
1916        self.assertTrue(inspect.ismethod(method),
1917                        name + "is a method name of object: " + str(obj))
1918        result = method()
1919        with recording(self, trace) as sbuf:
1920            print(str(method) + ":",  result, file=sbuf)
1921        return result
1922
1923    def build(self, architecture=None, compiler=None, dictionary=None, clean=True):
1924        """Platform specific way to build the default binaries."""
1925        module = builder_module()
1926        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
1927        if self.debug_info is None:
1928            return self.buildDefault(architecture, compiler, dictionary, clean)
1929        elif self.debug_info == "dsym":
1930            return self.buildDsym(architecture, compiler, dictionary, clean)
1931        elif self.debug_info == "dwarf":
1932            return self.buildDwarf(architecture, compiler, dictionary, clean)
1933        elif self.debug_info == "dwo":
1934            return self.buildDwo(architecture, compiler, dictionary, clean)
1935        else:
1936            self.fail("Can't build for debug info: %s" % self.debug_info)
1937
1938    def run_platform_command(self, cmd):
1939        platform = self.dbg.GetSelectedPlatform()
1940        shell_command = lldb.SBPlatformShellCommand(cmd)
1941        err = platform.Run(shell_command)
1942        return (err, shell_command.GetStatus(), shell_command.GetOutput())
1943
1944    # =================================================
1945    # Misc. helper methods for debugging test execution
1946    # =================================================
1947
1948    def DebugSBValue(self, val):
1949        """Debug print a SBValue object, if traceAlways is True."""
1950        from .lldbutil import value_type_to_str
1951
1952        if not traceAlways:
1953            return
1954
1955        err = sys.stderr
1956        err.write(val.GetName() + ":\n")
1957        err.write('\t' + "TypeName         -> " + val.GetTypeName()            + '\n')
1958        err.write('\t' + "ByteSize         -> " + str(val.GetByteSize())       + '\n')
1959        err.write('\t' + "NumChildren      -> " + str(val.GetNumChildren())    + '\n')
1960        err.write('\t' + "Value            -> " + str(val.GetValue())          + '\n')
1961        err.write('\t' + "ValueAsUnsigned  -> " + str(val.GetValueAsUnsigned())+ '\n')
1962        err.write('\t' + "ValueType        -> " + value_type_to_str(val.GetValueType()) + '\n')
1963        err.write('\t' + "Summary          -> " + str(val.GetSummary())        + '\n')
1964        err.write('\t' + "IsPointerType    -> " + str(val.TypeIsPointerType()) + '\n')
1965        err.write('\t' + "Location         -> " + val.GetLocation()            + '\n')
1966
1967    def DebugSBType(self, type):
1968        """Debug print a SBType object, if traceAlways is True."""
1969        if not traceAlways:
1970            return
1971
1972        err = sys.stderr
1973        err.write(type.GetName() + ":\n")
1974        err.write('\t' + "ByteSize        -> " + str(type.GetByteSize())     + '\n')
1975        err.write('\t' + "IsPointerType   -> " + str(type.IsPointerType())   + '\n')
1976        err.write('\t' + "IsReferenceType -> " + str(type.IsReferenceType()) + '\n')
1977
1978    def DebugPExpect(self, child):
1979        """Debug the spwaned pexpect object."""
1980        if not traceAlways:
1981            return
1982
1983        print(child)
1984
1985    @classmethod
1986    def RemoveTempFile(cls, file):
1987        if os.path.exists(file):
1988            remove_file(file)
1989
1990# On Windows, the first attempt to delete a recently-touched file can fail
1991# because of a race with antimalware scanners.  This function will detect a
1992# failure and retry.
1993def remove_file(file, num_retries = 1, sleep_duration = 0.5):
1994    for i in range(num_retries+1):
1995        try:
1996            os.remove(file)
1997            return True
1998        except:
1999            time.sleep(sleep_duration)
2000            continue
2001    return False
2002