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