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