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