2 LLDB module which provides the abstract base class of lldb test case.
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.
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.
11 ./dotest.py provides a test driver which sets up the environment to run the
12 entire of part of the test suite . Example:
14 # Exercises the test suite in the types directory....
15 /Volumes/data/lldb/svn/ToT/test $ ./dotest.py -A x86_64 types
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
22 Configuration: arch=x86_64 compiler=clang
23 ----------------------------------------------------------------------
26 ........................................................................
27 ----------------------------------------------------------------------
28 Ran 72 tests in 135.468s
34 from __future__ import print_function
35 from __future__ import absolute_import
40 from distutils.version import LooseVersion
44 import os, sys, traceback
48 from subprocess import *
54 from six import add_metaclass
55 from six import StringIO as SixStringIO
56 from six.moves.urllib import parse as urlparse
61 from . import configuration
62 from . import lldbtest_config
63 from . import lldbutil
64 from . import test_categories
66 from .result_formatter import EventBuilder
68 # dosep.py starts lots and lots of dotest instances
69 # This option helps you find if two (or more) dotest instances are using the same
70 # directory at the same time
71 # Enable it to cause test failures and stderr messages if dotest instances try to run in
72 # the same directory simultaneously
73 # it is disabled by default because it litters the test directories with ".dirlock" files
74 debug_confirm_directory_exclusivity = False
76 # See also dotest.parseOptionsAndInitTestdirs(), where the environment variables
77 # LLDB_COMMAND_TRACE and LLDB_DO_CLEANUP are set from '-t' and '-r dir' options.
79 # By default, traceAlways is False.
80 if "LLDB_COMMAND_TRACE" in os.environ and os.environ["LLDB_COMMAND_TRACE"]=="YES":
85 # By default, doCleanup is True.
86 if "LLDB_DO_CLEANUP" in os.environ and os.environ["LLDB_DO_CLEANUP"]=="NO":
93 # Some commonly used assert messages.
96 COMMAND_FAILED_AS_EXPECTED = "Command has failed as expected"
98 CURRENT_EXECUTABLE_SET = "Current executable set successfully"
100 PROCESS_IS_VALID = "Process is valid"
102 PROCESS_KILLED = "Process is killed successfully"
104 PROCESS_EXITED = "Process exited successfully"
106 PROCESS_STOPPED = "Process status should be stopped"
108 RUN_SUCCEEDED = "Process is launched successfully"
110 RUN_COMPLETED = "Process exited successfully"
112 BACKTRACE_DISPLAYED_CORRECTLY = "Backtrace displayed correctly"
114 BREAKPOINT_CREATED = "Breakpoint created successfully"
116 BREAKPOINT_STATE_CORRECT = "Breakpoint state is correct"
118 BREAKPOINT_PENDING_CREATED = "Pending breakpoint created successfully"
120 BREAKPOINT_HIT_ONCE = "Breakpoint resolved with hit cout = 1"
122 BREAKPOINT_HIT_TWICE = "Breakpoint resolved with hit cout = 2"
124 BREAKPOINT_HIT_THRICE = "Breakpoint resolved with hit cout = 3"
126 MISSING_EXPECTED_REGISTERS = "At least one expected register is unavailable."
128 OBJECT_PRINTED_CORRECTLY = "Object printed correctly"
130 SOURCE_DISPLAYED_CORRECTLY = "Source code displayed correctly"
132 STEP_OUT_SUCCEEDED = "Thread step-out succeeded"
134 STOPPED_DUE_TO_EXC_BAD_ACCESS = "Process should be stopped due to bad access exception"
136 STOPPED_DUE_TO_ASSERT = "Process should be stopped due to an assertion"
138 STOPPED_DUE_TO_BREAKPOINT = "Process should be stopped due to breakpoint"
140 STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS = "%s, %s" % (
141 STOPPED_DUE_TO_BREAKPOINT, "instead, the actual stop reason is: '%s'")
143 STOPPED_DUE_TO_BREAKPOINT_CONDITION = "Stopped due to breakpoint condition"
145 STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT = "Stopped due to breakpoint and ignore count"
147 STOPPED_DUE_TO_SIGNAL = "Process state is stopped due to signal"
149 STOPPED_DUE_TO_STEP_IN = "Process state is stopped due to step in"
151 STOPPED_DUE_TO_WATCHPOINT = "Process should be stopped due to watchpoint"
153 DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly"
155 VALID_BREAKPOINT = "Got a valid breakpoint"
157 VALID_BREAKPOINT_LOCATION = "Got a valid breakpoint location"
159 VALID_COMMAND_INTERPRETER = "Got a valid command interpreter"
161 VALID_FILESPEC = "Got a valid filespec"
163 VALID_MODULE = "Got a valid module"
165 VALID_PROCESS = "Got a valid process"
167 VALID_SYMBOL = "Got a valid symbol"
169 VALID_TARGET = "Got a valid target"
171 VALID_PLATFORM = "Got a valid platform"
173 VALID_TYPE = "Got a valid type"
175 VALID_VARIABLE = "Got a valid variable"
177 VARIABLES_DISPLAYED_CORRECTLY = "Variable(s) displayed correctly"
179 WATCHPOINT_CREATED = "Watchpoint created successfully"
182 '''A generic "Command '%s' returns successfully" message generator.'''
183 return "Command '%s' returns successfully" % str
185 def COMPLETION_MSG(str_before, str_after):
186 '''A generic message generator for the completion mechanism.'''
187 return "'%s' successfully completes to '%s'" % (str_before, str_after)
189 def EXP_MSG(str, exe):
190 '''A generic "'%s' returns expected result" message generator if exe.
191 Otherwise, it generates "'%s' matches expected result" message.'''
192 return "'%s' %s expected result" % (str, 'returns' if exe else 'matches')
194 def SETTING_MSG(setting):
195 '''A generic "Value of setting '%s' is correct" message generator.'''
196 return "Value of setting '%s' is correct" % setting
199 """Returns an env variable array from the os.environ map object."""
200 return list(map(lambda k,v: k+"="+v, list(os.environ.keys()), list(os.environ.values())))
202 def line_number(filename, string_to_match):
203 """Helper function to return the line number of the first matched string."""
204 with open(filename, 'r') as f:
205 for i, line in enumerate(f):
206 if line.find(string_to_match) != -1:
209 raise Exception("Unable to find '%s' within file %s" % (string_to_match, filename))
212 """Return the pointer size of the host system."""
214 a_pointer = ctypes.c_void_p(0xffff)
215 return 8 * ctypes.sizeof(a_pointer)
218 """Returns true if fpath is an executable."""
219 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
222 """Returns the full path to a program; None otherwise."""
223 fpath, fname = os.path.split(program)
228 for path in os.environ["PATH"].split(os.pathsep):
229 exe_file = os.path.join(path, program)
234 class recording(SixStringIO):
236 A nice little context manager for recording the debugger interactions into
237 our session object. If trace flag is ON, it also emits the interactions
240 def __init__(self, test, trace):
241 """Create a SixStringIO instance; record the session obj and trace flag."""
242 SixStringIO.__init__(self)
243 # The test might not have undergone the 'setUp(self)' phase yet, so that
244 # the attribute 'session' might not even exist yet.
245 self.session = getattr(test, "session", None) if test else None
250 Context management protocol on entry to the body of the with statement.
251 Just return the SixStringIO object.
255 def __exit__(self, type, value, tb):
257 Context management protocol on exit from the body of the with statement.
258 If trace is ON, it emits the recordings into stderr. Always add the
259 recordings to our session object. And close the SixStringIO object, too.
262 print(self.getvalue(), file=sys.stderr)
264 print(self.getvalue(), file=self.session)
267 @add_metaclass(abc.ABCMeta)
268 class _BaseProcess(object):
270 @abc.abstractproperty
272 """Returns process PID if has been launched already."""
275 def launch(self, executable, args):
276 """Launches new process with given executable and args."""
280 """Terminates previously launched process.."""
282 class _LocalProcess(_BaseProcess):
284 def __init__(self, trace_on):
286 self._trace_on = trace_on
287 self._delayafterterminate = 0.1
291 return self._proc.pid
293 def launch(self, executable, args):
294 self._proc = Popen([executable] + args,
295 stdout = open(os.devnull) if not self._trace_on else None,
299 if self._proc.poll() == None:
300 # Terminate _proc like it does the pexpect
301 signals_to_try = [sig for sig in ['SIGHUP', 'SIGCONT', 'SIGINT'] if sig in dir(signal)]
302 for sig in signals_to_try:
304 self._proc.send_signal(getattr(signal, sig))
305 time.sleep(self._delayafterterminate)
306 if self._proc.poll() != None:
309 pass # Windows says SIGINT is not a valid signal to send
310 self._proc.terminate()
311 time.sleep(self._delayafterterminate)
312 if self._proc.poll() != None:
315 time.sleep(self._delayafterterminate)
318 return self._proc.poll()
320 class _RemoteProcess(_BaseProcess):
322 def __init__(self, install_remote):
324 self._install_remote = install_remote
330 def launch(self, executable, args):
331 if self._install_remote:
332 src_path = executable
333 dst_path = lldbutil.append_to_process_working_directory(os.path.basename(executable))
335 dst_file_spec = lldb.SBFileSpec(dst_path, False)
336 err = lldb.remote_platform.Install(lldb.SBFileSpec(src_path, True), dst_file_spec)
338 raise Exception("remote_platform.Install('%s', '%s') failed: %s" % (src_path, dst_path, err))
340 dst_path = executable
341 dst_file_spec = lldb.SBFileSpec(executable, False)
343 launch_info = lldb.SBLaunchInfo(args)
344 launch_info.SetExecutableFile(dst_file_spec, True)
345 launch_info.SetWorkingDirectory(lldb.remote_platform.GetWorkingDirectory())
347 # Redirect stdout and stderr to /dev/null
348 launch_info.AddSuppressFileAction(1, False, True)
349 launch_info.AddSuppressFileAction(2, False, True)
351 err = lldb.remote_platform.Launch(launch_info)
353 raise Exception("remote_platform.Launch('%s', '%s') failed: %s" % (dst_path, args, err))
354 self._pid = launch_info.GetProcessID()
357 lldb.remote_platform.Kill(self._pid)
359 # From 2.7's subprocess.check_output() convenience function.
360 # Return a tuple (stdoutdata, stderrdata).
361 def system(commands, **kwargs):
362 r"""Run an os command with arguments and return its output as a byte string.
364 If the exit code was non-zero it raises a CalledProcessError. The
365 CalledProcessError object will have the return code in the returncode
366 attribute and output in the output attribute.
368 The arguments are the same as for the Popen constructor. Example:
370 >>> check_output(["ls", "-l", "/dev/null"])
371 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
373 The stdout argument is not allowed as it is used internally.
374 To capture standard error in the result, use stderr=STDOUT.
376 >>> check_output(["/bin/sh", "-c",
377 ... "ls -l non_existent_file ; exit 0"],
379 'ls: non_existent_file: No such file or directory\n'
382 # Assign the sender object to variable 'test' and remove it from kwargs.
383 test = kwargs.pop('sender', None)
385 # [['make', 'clean', 'foo'], ['make', 'foo']] -> ['make clean foo', 'make foo']
386 commandList = [' '.join(x) for x in commands]
389 for shellCommand in commandList:
390 if 'stdout' in kwargs:
391 raise ValueError('stdout argument not allowed, it will be overridden.')
392 if 'shell' in kwargs and kwargs['shell']==False:
393 raise ValueError('shell=False not allowed')
394 process = Popen(shellCommand, stdout=PIPE, stderr=PIPE, shell=True, universal_newlines=True, **kwargs)
396 this_output, this_error = process.communicate()
397 retcode = process.poll()
399 # Enable trace on failure return while tracking down FreeBSD buildbot issues
401 if not trace and retcode and sys.platform.startswith("freebsd"):
404 with recording(test, trace) as sbuf:
406 print("os command:", shellCommand, file=sbuf)
407 print("with pid:", pid, file=sbuf)
408 print("stdout:", this_output, file=sbuf)
409 print("stderr:", this_error, file=sbuf)
410 print("retcode:", retcode, file=sbuf)
414 cmd = kwargs.get("args")
417 raise CalledProcessError(retcode, cmd)
418 output = output + this_output
419 error = error + this_error
420 return (output, error)
422 def getsource_if_available(obj):
424 Return the text of the source code for an object if available. Otherwise,
425 a print representation is returned.
429 return inspect.getsource(obj)
433 def builder_module():
434 if sys.platform.startswith("freebsd"):
435 return __import__("builder_freebsd")
436 if sys.platform.startswith("netbsd"):
437 return __import__("builder_netbsd")
438 return __import__("builder_" + sys.platform)
440 def run_adb_command(cmd, device_id):
443 device_id_args = ["-s", device_id]
444 full_cmd = ["adb"] + device_id_args + cmd
445 p = Popen(full_cmd, stdout=PIPE, stderr=PIPE)
446 stdout, stderr = p.communicate()
447 return p.returncode, stdout, stderr
449 def append_android_envs(dictionary):
450 if dictionary is None:
452 dictionary["OS"] = "Android"
453 if android_device_api() >= 16:
454 dictionary["PIE"] = 1
457 def target_is_android():
458 if not hasattr(target_is_android, 'result'):
459 triple = lldb.DBG.GetSelectedPlatform().GetTriple()
460 match = re.match(".*-.*-.*-android", triple)
461 target_is_android.result = match is not None
462 return target_is_android.result
464 def android_device_api():
465 if not hasattr(android_device_api, 'result'):
466 assert configuration.lldb_platform_url is not None
468 parsed_url = urlparse.urlparse(configuration.lldb_platform_url)
469 host_name = parsed_url.netloc.split(":")[0]
470 if host_name != 'localhost':
471 device_id = host_name
472 if device_id.startswith('[') and device_id.endswith(']'):
473 device_id = device_id[1:-1]
474 retcode, stdout, stderr = run_adb_command(
475 ["shell", "getprop", "ro.build.version.sdk"], device_id)
477 android_device_api.result = int(stdout)
480 ">>> Unable to determine the API level of the Android device.\n"
482 ">>> stderr:\n%s\n" % (stdout, stderr))
483 return android_device_api.result
485 def check_expected_version(comparison, expected, actual):
486 def fn_leq(x,y): return x <= y
487 def fn_less(x,y): return x < y
488 def fn_geq(x,y): return x >= y
489 def fn_greater(x,y): return x > y
490 def fn_eq(x,y): return x == y
491 def fn_neq(x,y): return x != y
503 expected_str = '.'.join([str(x) for x in expected])
504 actual_str = '.'.join([str(x) for x in actual])
506 return op_lookup[comparison](LooseVersion(actual_str), LooseVersion(expected_str))
509 # Decorators for categorizing test cases.
511 from functools import wraps
513 def add_test_categories(cat):
514 """Add test categories to a TestCase method"""
515 cat = test_categories.validate(cat, True)
517 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
518 raise Exception("@add_test_categories can only be used to decorate a test method")
519 if hasattr(func, "categories"):
520 cat.extend(func.categories)
521 func.categories = cat
526 def benchmarks_test(func):
527 """Decorate the item as a benchmarks test."""
528 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
529 raise Exception("@benchmarks_test can only be used to decorate a test method")
531 def wrapper(self, *args, **kwargs):
532 self.skipTest("benchmarks test")
533 return func(self, *args, **kwargs)
535 # Mark this function as such to separate them from the regular tests.
536 wrapper.__benchmarks_test__ = True
539 def no_debug_info_test(func):
540 """Decorate the item as a test what don't use any debug info. If this annotation is specified
541 then the test runner won't generate a separate test for each debug info format. """
542 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
543 raise Exception("@no_debug_info_test can only be used to decorate a test method")
545 def wrapper(self, *args, **kwargs):
546 return func(self, *args, **kwargs)
548 # Mark this function as such to separate them from the regular tests.
549 wrapper.__no_debug_info_test__ = True
552 def debugserver_test(func):
553 """Decorate the item as a debugserver test."""
554 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
555 raise Exception("@debugserver_test can only be used to decorate a test method")
557 def wrapper(self, *args, **kwargs):
558 if configuration.dont_do_debugserver_test:
559 self.skipTest("debugserver tests")
560 return func(self, *args, **kwargs)
562 # Mark this function as such to separate them from the regular tests.
563 wrapper.__debugserver_test__ = True
567 """Decorate the item as a lldb-server test."""
568 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
569 raise Exception("@llgs_test can only be used to decorate a test method")
571 def wrapper(self, *args, **kwargs):
572 if configuration.dont_do_llgs_test:
573 self.skipTest("llgs tests")
574 return func(self, *args, **kwargs)
576 # Mark this function as such to separate them from the regular tests.
577 wrapper.__llgs_test__ = True
580 def not_remote_testsuite_ready(func):
581 """Decorate the item as a test which is not ready yet for remote testsuite."""
582 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
583 raise Exception("@not_remote_testsuite_ready can only be used to decorate a test method")
585 def wrapper(self, *args, **kwargs):
586 if lldb.remote_platform:
587 self.skipTest("not ready for remote testsuite")
588 return func(self, *args, **kwargs)
590 # Mark this function as such to separate them from the regular tests.
591 wrapper.__not_ready_for_remote_testsuite_test__ = True
594 def expectedFailure(expected_fn, bugnumber=None):
595 def expectedFailure_impl(func):
597 def wrapper(*args, **kwargs):
598 from unittest2 import case
600 if expected_fn(self):
601 if configuration.results_formatter_object is not None:
602 # Mark this test as expected to fail.
603 configuration.results_formatter_object.handle_event(
604 EventBuilder.event_for_mark_test_expected_failure(self))
605 xfail_func = unittest2.expectedFailure(func)
606 xfail_func(*args, **kwargs)
608 func(*args, **kwargs)
610 # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
611 # return decorator in this case, so it will be used to decorating original method
612 if six.callable(bugnumber):
613 return expectedFailure_impl(bugnumber)
615 return expectedFailure_impl
617 # You can also pass not_in(list) to reverse the sense of the test for the arguments that
618 # are simple lists, namely oslist, compiler, and debug_info.
620 def not_in(iterable):
621 return lambda x : x not in iterable
623 def check_list_or_lambda(list_or_lambda, value):
624 if six.callable(list_or_lambda):
625 return list_or_lambda(value)
626 elif isinstance(list_or_lambda, list):
627 for item in list_or_lambda:
631 elif isinstance(list_or_lambda, str):
632 return value is None or value in list_or_lambda
634 return list_or_lambda is None or value is None or list_or_lambda == value
636 def matchArchitectures(archs, actual_arch):
637 retype = type(re.compile('hello, world'))
638 list_passes = isinstance(archs, list) and actual_arch in archs
639 basestring_passes = isinstance(archs, six.string_types) and actual_arch == archs
640 regex_passes = isinstance(archs, retype) and re.match(archs, actual_arch)
642 return (list_passes or basestring_passes or regex_passes)
644 # provide a function to xfail on defined oslist, compiler version, and archs
645 # if none is specified for any argument, that argument won't be checked and thus means for all
647 # @expectedFailureAll, xfail for all platform/compiler/arch,
648 # @expectedFailureAll(compiler='gcc'), xfail for gcc on all platform/architecture
649 # @expectedFailureAll(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), xfail for gcc>=4.9 on linux with i386
650 def expectedFailureAll(bugnumber=None, oslist=None, hostoslist=None, compiler=None, compiler_version=None, archs=None, triple=None, debug_info=None, swig_version=None, py_version=None):
652 oslist_passes = check_list_or_lambda(oslist, self.getPlatform())
653 hostoslist_passes = check_list_or_lambda(hostoslist, getHostPlatform())
654 compiler_passes = check_list_or_lambda(self.getCompiler(), compiler) and self.expectedCompilerVersion(compiler_version)
655 arch_passes = check_list_or_lambda(archs, self.getArchitecture())
656 triple_passes = triple is None or re.match(triple, lldb.DBG.GetSelectedPlatform().GetTriple())
657 debug_info_passes = check_list_or_lambda(debug_info, self.debug_info)
658 swig_version_passes = (swig_version is None) or (not hasattr(lldb, 'swig_version')) or (check_expected_version(swig_version[0], swig_version[1], lldb.swig_version))
659 py_version_passes = (py_version is None) or check_expected_version(py_version[0], py_version[1], sys.version_info)
661 return (oslist_passes and
662 hostoslist_passes and
666 debug_info_passes and
667 swig_version_passes and
669 return expectedFailure(fn, bugnumber)
671 def expectedFailureDwarf(bugnumber=None):
672 return expectedFailureAll(bugnumber=bugnumber, debug_info="dwarf")
674 def expectedFailureDwo(bugnumber=None):
675 return expectedFailureAll(bugnumber=bugnumber, debug_info="dwo")
677 def expectedFailureDsym(bugnumber=None):
678 return expectedFailureAll(bugnumber=bugnumber, debug_info="dsym")
680 def expectedFailureCompiler(compiler, compiler_version=None, bugnumber=None):
681 if compiler_version is None:
682 compiler_version=['=', None]
683 return expectedFailureAll(bugnumber=bugnumber, compiler=compiler, compiler_version=compiler_version)
685 # to XFAIL a specific clang versions, try this
686 # @expectedFailureClang('bugnumber', ['<=', '3.4'])
687 def expectedFailureClang(bugnumber=None, compiler_version=None):
688 return expectedFailureCompiler('clang', compiler_version, bugnumber)
690 def expectedFailureGcc(bugnumber=None, compiler_version=None):
691 return expectedFailureCompiler('gcc', compiler_version, bugnumber)
693 def expectedFailureIcc(bugnumber=None):
694 return expectedFailureCompiler('icc', None, bugnumber)
696 def expectedFailureArch(arch, bugnumber=None):
698 return arch in self.getArchitecture()
699 return expectedFailure(fn, bugnumber)
701 def expectedFailurei386(bugnumber=None):
702 return expectedFailureArch('i386', bugnumber)
704 def expectedFailurex86_64(bugnumber=None):
705 return expectedFailureArch('x86_64', bugnumber)
707 def expectedFailureOS(oslist, bugnumber=None, compilers=None, debug_info=None, archs=None):
709 return (self.getPlatform() in oslist and
710 self.expectedCompiler(compilers) and
711 (archs is None or self.getArchitecture() in archs) and
712 (debug_info is None or self.debug_info in debug_info))
713 return expectedFailure(fn, bugnumber)
715 def expectedFailureHostOS(oslist, bugnumber=None, compilers=None):
717 return (getHostPlatform() in oslist and
718 self.expectedCompiler(compilers))
719 return expectedFailure(fn, bugnumber)
721 def expectedFailureDarwin(bugnumber=None, compilers=None, debug_info=None):
722 # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
723 return expectedFailureOS(getDarwinOSTriples(), bugnumber, compilers, debug_info=debug_info)
725 def expectedFailureFreeBSD(bugnumber=None, compilers=None, debug_info=None):
726 return expectedFailureOS(['freebsd'], bugnumber, compilers, debug_info=debug_info)
728 def expectedFailureLinux(bugnumber=None, compilers=None, debug_info=None, archs=None):
729 return expectedFailureOS(['linux'], bugnumber, compilers, debug_info=debug_info, archs=archs)
731 def expectedFailureNetBSD(bugnumber=None, compilers=None, debug_info=None):
732 return expectedFailureOS(['netbsd'], bugnumber, compilers, debug_info=debug_info)
734 def expectedFailureWindows(bugnumber=None, compilers=None, debug_info=None):
735 return expectedFailureOS(['windows'], bugnumber, compilers, debug_info=debug_info)
737 def expectedFailureHostWindows(bugnumber=None, compilers=None):
738 return expectedFailureHostOS(['windows'], bugnumber, compilers)
740 def matchAndroid(api_levels=None, archs=None):
742 if not target_is_android():
744 if archs is not None and self.getArchitecture() not in archs:
746 if api_levels is not None and android_device_api() not in api_levels:
752 def expectedFailureAndroid(bugnumber=None, api_levels=None, archs=None):
753 """ Mark a test as xfail for Android.
756 bugnumber - The LLVM pr associated with the problem.
757 api_levels - A sequence of numbers specifying the Android API levels
758 for which a test is expected to fail. None means all API level.
759 arch - A sequence of architecture names specifying the architectures
760 for which a test is expected to fail. None means all architectures.
762 return expectedFailure(matchAndroid(api_levels, archs), bugnumber)
764 # Flakey tests get two chances to run. If they fail the first time round, the result formatter
765 # makes sure it is run one more time.
766 def expectedFlakey(expected_fn, bugnumber=None):
767 def expectedFailure_impl(func):
769 def wrapper(*args, **kwargs):
771 if expected_fn(self):
772 # Send event marking test as explicitly eligible for rerunning.
773 if configuration.results_formatter_object is not None:
774 # Mark this test as rerunnable.
775 configuration.results_formatter_object.handle_event(
776 EventBuilder.event_for_mark_test_rerun_eligible(self))
777 func(*args, **kwargs)
779 # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
780 # return decorator in this case, so it will be used to decorating original method
781 if six.callable(bugnumber):
782 return expectedFailure_impl(bugnumber)
784 return expectedFailure_impl
786 def expectedFlakeyDwarf(bugnumber=None):
788 return self.debug_info == "dwarf"
789 return expectedFlakey(fn, bugnumber)
791 def expectedFlakeyDsym(bugnumber=None):
793 return self.debug_info == "dwarf"
794 return expectedFlakey(fn, bugnumber)
796 def expectedFlakeyOS(oslist, bugnumber=None, compilers=None):
798 return (self.getPlatform() in oslist and
799 self.expectedCompiler(compilers))
800 return expectedFlakey(fn, bugnumber)
802 def expectedFlakeyDarwin(bugnumber=None, compilers=None):
803 # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
804 return expectedFlakeyOS(getDarwinOSTriples(), bugnumber, compilers)
806 def expectedFlakeyFreeBSD(bugnumber=None, compilers=None):
807 return expectedFlakeyOS(['freebsd'], bugnumber, compilers)
809 def expectedFlakeyLinux(bugnumber=None, compilers=None):
810 return expectedFlakeyOS(['linux'], bugnumber, compilers)
812 def expectedFlakeyNetBSD(bugnumber=None, compilers=None):
813 return expectedFlakeyOS(['netbsd'], bugnumber, compilers)
815 def expectedFlakeyCompiler(compiler, compiler_version=None, bugnumber=None):
816 if compiler_version is None:
817 compiler_version=['=', None]
819 return compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version)
820 return expectedFlakey(fn, bugnumber)
822 # @expectedFlakeyClang('bugnumber', ['<=', '3.4'])
823 def expectedFlakeyClang(bugnumber=None, compiler_version=None):
824 return expectedFlakeyCompiler('clang', compiler_version, bugnumber)
826 # @expectedFlakeyGcc('bugnumber', ['<=', '3.4'])
827 def expectedFlakeyGcc(bugnumber=None, compiler_version=None):
828 return expectedFlakeyCompiler('gcc', compiler_version, bugnumber)
830 def expectedFlakeyAndroid(bugnumber=None, api_levels=None, archs=None):
831 return expectedFlakey(matchAndroid(api_levels, archs), bugnumber)
833 def skipIfRemote(func):
834 """Decorate the item to skip tests if testing remotely."""
835 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
836 raise Exception("@skipIfRemote can only be used to decorate a test method")
838 def wrapper(*args, **kwargs):
839 from unittest2 import case
840 if lldb.remote_platform:
842 self.skipTest("skip on remote platform")
844 func(*args, **kwargs)
847 def skipUnlessListedRemote(remote_list=None):
849 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
850 raise Exception("@skipIfRemote can only be used to decorate a "
854 def wrapper(*args, **kwargs):
855 if remote_list and lldb.remote_platform:
857 triple = self.dbg.GetSelectedPlatform().GetTriple()
858 for r in remote_list:
860 func(*args, **kwargs)
862 self.skipTest("skip on remote platform %s" % str(triple))
864 func(*args, **kwargs)
869 def skipIfRemoteDueToDeadlock(func):
870 """Decorate the item to skip tests if testing remotely due to the test deadlocking."""
871 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
872 raise Exception("@skipIfRemote can only be used to decorate a test method")
874 def wrapper(*args, **kwargs):
875 from unittest2 import case
876 if lldb.remote_platform:
878 self.skipTest("skip on remote platform (deadlocks)")
880 func(*args, **kwargs)
883 def skipIfNoSBHeaders(func):
884 """Decorate the item to mark tests that should be skipped when LLDB is built with no SB API headers."""
885 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
886 raise Exception("@skipIfNoSBHeaders can only be used to decorate a test method")
888 def wrapper(*args, **kwargs):
889 from unittest2 import case
891 if sys.platform.startswith("darwin"):
892 header = os.path.join(os.environ["LLDB_LIB_DIR"], 'LLDB.framework', 'Versions','Current','Headers','LLDB.h')
894 header = os.path.join(os.environ["LLDB_SRC"], "include", "lldb", "API", "LLDB.h")
895 platform = sys.platform
896 if not os.path.exists(header):
897 self.skipTest("skip because LLDB.h header not found")
899 func(*args, **kwargs)
902 def skipIfiOSSimulator(func):
903 """Decorate the item to skip tests that should be skipped on the iOS Simulator."""
904 return unittest2.skipIf(configuration.lldb_platform_name == 'ios-simulator', 'skip on the iOS Simulator')(func)
906 def skipIfFreeBSD(func):
907 """Decorate the item to skip tests that should be skipped on FreeBSD."""
908 return skipIfPlatform(["freebsd"])(func)
910 def skipIfNetBSD(func):
911 """Decorate the item to skip tests that should be skipped on NetBSD."""
912 return skipIfPlatform(["netbsd"])(func)
914 def getDarwinOSTriples():
915 return ['darwin', 'macosx', 'ios']
917 def skipIfDarwin(func):
918 """Decorate the item to skip tests that should be skipped on Darwin."""
919 return skipIfPlatform(getDarwinOSTriples())(func)
921 def skipIfLinux(func):
922 """Decorate the item to skip tests that should be skipped on Linux."""
923 return skipIfPlatform(["linux"])(func)
925 def skipUnlessHostLinux(func):
926 """Decorate the item to skip tests that should be skipped on any non Linux host."""
927 return skipUnlessHostPlatform(["linux"])(func)
929 def skipIfWindows(func):
930 """Decorate the item to skip tests that should be skipped on Windows."""
931 return skipIfPlatform(["windows"])(func)
933 def skipIfHostWindows(func):
934 """Decorate the item to skip tests that should be skipped on Windows."""
935 return skipIfHostPlatform(["windows"])(func)
937 def skipUnlessWindows(func):
938 """Decorate the item to skip tests that should be skipped on any non-Windows platform."""
939 return skipUnlessPlatform(["windows"])(func)
941 def skipUnlessDarwin(func):
942 """Decorate the item to skip tests that should be skipped on any non Darwin platform."""
943 return skipUnlessPlatform(getDarwinOSTriples())(func)
945 def skipUnlessGoInstalled(func):
946 """Decorate the item to skip tests when no Go compiler is available."""
947 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
948 raise Exception("@skipIfGcc can only be used to decorate a test method")
950 def wrapper(*args, **kwargs):
951 from unittest2 import case
953 compiler = self.getGoCompilerVersion()
955 self.skipTest("skipping because go compiler not found")
957 # Ensure the version is the minimum version supported by
958 # the LLDB go support.
959 match_version = re.search(r"(\d+\.\d+(\.\d+)?)", compiler)
960 if not match_version:
961 # Couldn't determine version.
963 "skipping because go version could not be parsed "
964 "out of {}".format(compiler))
966 from distutils.version import StrictVersion
967 min_strict_version = StrictVersion("1.4.0")
968 compiler_strict_version = StrictVersion(match_version.group(1))
969 if compiler_strict_version < min_strict_version:
971 "skipping because available go version ({}) does "
972 "not meet minimum required go version ({})".format(
973 compiler_strict_version,
975 func(*args, **kwargs)
979 """Returns the target platform which the tests are running on."""
980 platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
981 if platform.startswith('freebsd'):
983 elif platform.startswith('netbsd'):
987 def getHostPlatform():
988 """Returns the host platform running the test suite."""
989 # Attempts to return a platform name matching a target Triple platform.
990 if sys.platform.startswith('linux'):
992 elif sys.platform.startswith('win32'):
994 elif sys.platform.startswith('darwin'):
996 elif sys.platform.startswith('freebsd'):
998 elif sys.platform.startswith('netbsd'):
1003 def platformIsDarwin():
1004 """Returns true if the OS triple for the selected platform is any valid apple OS"""
1005 return getPlatform() in getDarwinOSTriples()
1007 def skipIfHostIncompatibleWithRemote(func):
1008 """Decorate the item to skip tests if binaries built on this host are incompatible."""
1009 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1010 raise Exception("@skipIfHostIncompatibleWithRemote can only be used to decorate a test method")
1012 def wrapper(*args, **kwargs):
1013 from unittest2 import case
1015 host_arch = self.getLldbArchitecture()
1016 host_platform = getHostPlatform()
1017 target_arch = self.getArchitecture()
1018 target_platform = 'darwin' if self.platformIsDarwin() else self.getPlatform()
1019 if not (target_arch == 'x86_64' and host_arch == 'i386') and host_arch != target_arch:
1020 self.skipTest("skipping because target %s is not compatible with host architecture %s" % (target_arch, host_arch))
1021 elif target_platform != host_platform:
1022 self.skipTest("skipping because target is %s but host is %s" % (target_platform, host_platform))
1024 func(*args, **kwargs)
1027 def skipIfHostPlatform(oslist):
1028 """Decorate the item to skip tests if running on one of the listed host platforms."""
1029 return unittest2.skipIf(getHostPlatform() in oslist,
1030 "skip on %s" % (", ".join(oslist)))
1032 def skipUnlessHostPlatform(oslist):
1033 """Decorate the item to skip tests unless running on one of the listed host platforms."""
1034 return unittest2.skipUnless(getHostPlatform() in oslist,
1035 "requires on of %s" % (", ".join(oslist)))
1037 def skipUnlessArch(archs):
1038 """Decorate the item to skip tests unless running on one of the listed architectures."""
1040 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1041 raise Exception("@skipUnlessArch can only be used to decorate a test method")
1044 def wrapper(*args, **kwargs):
1046 if not matchArchitectures(archs, self.getArchitecture()):
1047 self.skipTest("skipping for architecture %s" % (self.getArchitecture()))
1049 func(*args, **kwargs)
1054 def skipIfPlatform(oslist):
1055 """Decorate the item to skip tests if running on one of the listed platforms."""
1056 return unittest2.skipIf(getPlatform() in oslist,
1057 "skip on %s" % (", ".join(oslist)))
1059 def skipUnlessPlatform(oslist):
1060 """Decorate the item to skip tests unless running on one of the listed platforms."""
1061 return unittest2.skipUnless(getPlatform() in oslist,
1062 "requires on of %s" % (", ".join(oslist)))
1064 def skipIfLinuxClang(func):
1065 """Decorate the item to skip tests that should be skipped if building on
1068 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1069 raise Exception("@skipIfLinuxClang can only be used to decorate a test method")
1071 def wrapper(*args, **kwargs):
1072 from unittest2 import case
1074 compiler = self.getCompiler()
1075 platform = self.getPlatform()
1076 if "clang" in compiler and platform == "linux":
1077 self.skipTest("skipping because Clang is used on Linux")
1079 func(*args, **kwargs)
1082 # provide a function to skip on defined oslist, compiler version, and archs
1083 # if none is specified for any argument, that argument won't be checked and thus means for all
1085 # @skipIf, skip for all platform/compiler/arch,
1086 # @skipIf(compiler='gcc'), skip for gcc on all platform/architecture
1087 # @skipIf(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), skip for gcc>=4.9 on linux with i386
1089 # TODO: refactor current code, to make skipIfxxx functions to call this function
1090 def skipIf(bugnumber=None, oslist=None, compiler=None, compiler_version=None, archs=None, debug_info=None, swig_version=None, py_version=None, remote=None):
1092 oslist_passes = check_list_or_lambda(oslist, self.getPlatform())
1093 compiler_passes = check_list_or_lambda(self.getCompiler(), compiler) and self.expectedCompilerVersion(compiler_version)
1094 arch_passes = check_list_or_lambda(archs, self.getArchitecture())
1095 debug_info_passes = check_list_or_lambda(debug_info, self.debug_info)
1096 swig_version_passes = (swig_version is None) or (not hasattr(lldb, 'swig_version')) or (check_expected_version(swig_version[0], swig_version[1], lldb.swig_version))
1097 py_version_passes = (py_version is None) or check_expected_version(py_version[0], py_version[1], sys.version_info)
1098 remote_passes = (remote is None) or (remote == (lldb.remote_platform is not None))
1100 return (oslist_passes and
1103 debug_info_passes and
1104 swig_version_passes and
1105 py_version_passes and
1108 local_vars = locals()
1109 args = [x for x in inspect.getargspec(skipIf).args]
1110 arg_vals = [eval(x, globals(), local_vars) for x in args]
1111 args = [x for x in zip(args, arg_vals) if x[1] is not None]
1112 reasons = ['%s=%s' % (x, str(y)) for (x,y) in args]
1113 return skipTestIfFn(fn, bugnumber, skipReason='skipping because ' + ' && '.join(reasons))
1115 def skipIfDebugInfo(bugnumber=None, debug_info=None):
1116 return skipIf(bugnumber=bugnumber, debug_info=debug_info)
1118 def skipIfDWO(bugnumber=None):
1119 return skipIfDebugInfo(bugnumber, ["dwo"])
1121 def skipIfDwarf(bugnumber=None):
1122 return skipIfDebugInfo(bugnumber, ["dwarf"])
1124 def skipIfDsym(bugnumber=None):
1125 return skipIfDebugInfo(bugnumber, ["dsym"])
1127 def skipTestIfFn(expected_fn, bugnumber=None, skipReason=None):
1128 def skipTestIfFn_impl(func):
1130 def wrapper(*args, **kwargs):
1131 from unittest2 import case
1133 if expected_fn(self):
1134 self.skipTest(skipReason)
1136 func(*args, **kwargs)
1138 if six.callable(bugnumber):
1139 return skipTestIfFn_impl(bugnumber)
1141 return skipTestIfFn_impl
1143 def skipIfGcc(func):
1144 """Decorate the item to skip tests that should be skipped if building with gcc ."""
1145 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1146 raise Exception("@skipIfGcc can only be used to decorate a test method")
1148 def wrapper(*args, **kwargs):
1149 from unittest2 import case
1151 compiler = self.getCompiler()
1152 if "gcc" in compiler:
1153 self.skipTest("skipping because gcc is the test compiler")
1155 func(*args, **kwargs)
1158 def skipIfIcc(func):
1159 """Decorate the item to skip tests that should be skipped if building with icc ."""
1160 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1161 raise Exception("@skipIfIcc can only be used to decorate a test method")
1163 def wrapper(*args, **kwargs):
1164 from unittest2 import case
1166 compiler = self.getCompiler()
1167 if "icc" in compiler:
1168 self.skipTest("skipping because icc is the test compiler")
1170 func(*args, **kwargs)
1173 def skipIfi386(func):
1174 """Decorate the item to skip tests that should be skipped if building 32-bit."""
1175 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1176 raise Exception("@skipIfi386 can only be used to decorate a test method")
1178 def wrapper(*args, **kwargs):
1179 from unittest2 import case
1181 if "i386" == self.getArchitecture():
1182 self.skipTest("skipping because i386 is not a supported architecture")
1184 func(*args, **kwargs)
1187 def skipIfTargetAndroid(api_levels=None, archs=None):
1188 """Decorator to skip tests when the target is Android.
1191 api_levels - The API levels for which the test should be skipped. If
1192 it is None, then the test will be skipped for all API levels.
1193 arch - A sequence of architecture names specifying the architectures
1194 for which a test is skipped. None means all architectures.
1197 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1198 raise Exception("@skipIfTargetAndroid can only be used to "
1199 "decorate a test method")
1201 def wrapper(*args, **kwargs):
1202 from unittest2 import case
1204 if matchAndroid(api_levels, archs)(self):
1205 self.skipTest("skiped on Android target with API %d and architecture %s" %
1206 (android_device_api(), self.getArchitecture()))
1207 func(*args, **kwargs)
1211 def skipUnlessCompilerRt(func):
1212 """Decorate the item to skip tests if testing remotely."""
1213 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1214 raise Exception("@skipUnless can only be used to decorate a test method")
1216 def wrapper(*args, **kwargs):
1217 from unittest2 import case
1219 compilerRtPath = os.path.join(os.path.dirname(__file__), "..", "..", "..", "..", "llvm","projects","compiler-rt")
1220 print(compilerRtPath)
1221 if not os.path.exists(compilerRtPath):
1223 self.skipTest("skip if compiler-rt not found")
1225 func(*args, **kwargs)
1228 class _PlatformContext(object):
1229 """Value object class which contains platform-specific options."""
1231 def __init__(self, shlib_environment_var, shlib_prefix, shlib_extension):
1232 self.shlib_environment_var = shlib_environment_var
1233 self.shlib_prefix = shlib_prefix
1234 self.shlib_extension = shlib_extension
1237 class Base(unittest2.TestCase):
1239 Abstract base for performing lldb (see TestBase) or other generic tests (see
1240 BenchBase for one example). lldbtest.Base works with the test driver to
1245 # The concrete subclass should override this attribute.
1248 # Keep track of the old current working directory.
1252 def compute_mydir(test_file):
1253 '''Subclasses should call this function to correctly calculate the required "mydir" attribute as follows:
1255 mydir = TestBase.compute_mydir(__file__)'''
1256 test_dir = os.path.dirname(test_file)
1257 return test_dir[len(os.environ["LLDB_TEST"])+1:]
1260 """Returns True if we are in trace mode (tracing detailed test execution)."""
1264 def setUpClass(cls):
1266 Python unittest framework class setup fixture.
1267 Do current directory manipulation.
1269 # Fail fast if 'mydir' attribute is not overridden.
1270 if not cls.mydir or len(cls.mydir) == 0:
1271 raise Exception("Subclasses must override the 'mydir' attribute.")
1273 # Save old working directory.
1274 cls.oldcwd = os.getcwd()
1276 # Change current working directory if ${LLDB_TEST} is defined.
1277 # See also dotest.py which sets up ${LLDB_TEST}.
1278 if ("LLDB_TEST" in os.environ):
1279 full_dir = os.path.join(os.environ["LLDB_TEST"], cls.mydir)
1281 print("Change dir to:", full_dir, file=sys.stderr)
1282 os.chdir(os.path.join(os.environ["LLDB_TEST"], cls.mydir))
1284 if debug_confirm_directory_exclusivity:
1286 cls.dir_lock = lock.Lock(os.path.join(full_dir, ".dirlock"))
1288 cls.dir_lock.try_acquire()
1289 # write the class that owns the lock into the lock file
1290 cls.dir_lock.handle.write(cls.__name__)
1291 except IOError as ioerror:
1292 # nothing else should have this directory lock
1293 # wait here until we get a lock
1294 cls.dir_lock.acquire()
1295 # read the previous owner from the lock file
1296 lock_id = cls.dir_lock.handle.read()
1297 print("LOCK ERROR: {} wants to lock '{}' but it is already locked by '{}'".format(cls.__name__, full_dir, lock_id), file=sys.stderr)
1300 # Set platform context.
1301 if platformIsDarwin():
1302 cls.platformContext = _PlatformContext('DYLD_LIBRARY_PATH', 'lib', 'dylib')
1303 elif getPlatform() in ("freebsd", "linux", "netbsd"):
1304 cls.platformContext = _PlatformContext('LD_LIBRARY_PATH', 'lib', 'so')
1306 cls.platformContext = None
1309 def tearDownClass(cls):
1311 Python unittest framework class teardown fixture.
1312 Do class-wide cleanup.
1316 # First, let's do the platform-specific cleanup.
1317 module = builder_module()
1320 # Subclass might have specific cleanup function defined.
1321 if getattr(cls, "classCleanup", None):
1323 print("Call class-specific cleanup function for class:", cls, file=sys.stderr)
1327 exc_type, exc_value, exc_tb = sys.exc_info()
1328 traceback.print_exception(exc_type, exc_value, exc_tb)
1330 if debug_confirm_directory_exclusivity:
1331 cls.dir_lock.release()
1334 # Restore old working directory.
1336 print("Restore dir to:", cls.oldcwd, file=sys.stderr)
1337 os.chdir(cls.oldcwd)
1340 def skipLongRunningTest(cls):
1342 By default, we skip long running test case.
1343 This can be overridden by passing '-l' to the test driver (dotest.py).
1345 if "LLDB_SKIP_LONG_RUNNING_TEST" in os.environ and "NO" == os.environ["LLDB_SKIP_LONG_RUNNING_TEST"]:
1350 def enableLogChannelsForCurrentTest(self):
1351 if len(lldbtest_config.channels) == 0:
1354 # if debug channels are specified in lldbtest_config.channels,
1355 # create a new set of log files for every test
1356 log_basename = self.getLogBasenameForCurrentTest()
1358 # confirm that the file is writeable
1359 host_log_path = "{}-host.log".format(log_basename)
1360 open(host_log_path, 'w').close()
1362 log_enable = "log enable -Tpn -f {} ".format(host_log_path)
1363 for channel_with_categories in lldbtest_config.channels:
1364 channel_then_categories = channel_with_categories.split(' ', 1)
1365 channel = channel_then_categories[0]
1366 if len(channel_then_categories) > 1:
1367 categories = channel_then_categories[1]
1369 categories = "default"
1371 if channel == "gdb-remote":
1372 # communicate gdb-remote categories to debugserver
1373 os.environ["LLDB_DEBUGSERVER_LOG_FLAGS"] = categories
1375 self.ci.HandleCommand(log_enable + channel_with_categories, self.res)
1376 if not self.res.Succeeded():
1377 raise Exception('log enable failed (check LLDB_LOG_OPTION env variable)')
1379 # Communicate log path name to debugserver & lldb-server
1380 server_log_path = "{}-server.log".format(log_basename)
1381 open(server_log_path, 'w').close()
1382 os.environ["LLDB_DEBUGSERVER_LOG_FILE"] = server_log_path
1384 # Communicate channels to lldb-server
1385 os.environ["LLDB_SERVER_LOG_CHANNELS"] = ":".join(lldbtest_config.channels)
1387 if len(lldbtest_config.channels) == 0:
1390 def disableLogChannelsForCurrentTest(self):
1391 # close all log files that we opened
1392 for channel_and_categories in lldbtest_config.channels:
1393 # channel format - <channel-name> [<category0> [<category1> ...]]
1394 channel = channel_and_categories.split(' ', 1)[0]
1395 self.ci.HandleCommand("log disable " + channel, self.res)
1396 if not self.res.Succeeded():
1397 raise Exception('log disable failed (check LLDB_LOG_OPTION env variable)')
1400 """Fixture for unittest test case setup.
1402 It works with the test driver to conditionally skip tests and does other
1405 #traceback.print_stack()
1407 if "LIBCXX_PATH" in os.environ:
1408 self.libcxxPath = os.environ["LIBCXX_PATH"]
1410 self.libcxxPath = None
1412 if "LLDBMI_EXEC" in os.environ:
1413 self.lldbMiExec = os.environ["LLDBMI_EXEC"]
1415 self.lldbMiExec = None
1417 # If we spawn an lldb process for test (via pexpect), do not load the
1418 # init file unless told otherwise.
1419 if "NO_LLDBINIT" in os.environ and "NO" == os.environ["NO_LLDBINIT"]:
1420 self.lldbOption = ""
1422 self.lldbOption = "--no-lldbinit"
1424 # Assign the test method name to self.testMethodName.
1426 # For an example of the use of this attribute, look at test/types dir.
1427 # There are a bunch of test cases under test/types and we don't want the
1428 # module cacheing subsystem to be confused with executable name "a.out"
1429 # used for all the test cases.
1430 self.testMethodName = self._testMethodName
1432 # This is for the case of directly spawning 'lldb'/'gdb' and interacting
1433 # with it using pexpect.
1435 self.child_prompt = "(lldb) "
1436 # If the child is interacting with the embedded script interpreter,
1437 # there are two exits required during tear down, first to quit the
1438 # embedded script interpreter and second to quit the lldb command
1440 self.child_in_script_interpreter = False
1442 # These are for customized teardown cleanup.
1444 self.doTearDownCleanup = False
1445 # And in rare cases where there are multiple teardown cleanups.
1447 self.doTearDownCleanups = False
1449 # List of spawned subproces.Popen objects
1450 self.subprocesses = []
1452 # List of forked process PIDs
1453 self.forkedProcessPids = []
1455 # Create a string buffer to record the session info, to be dumped into a
1456 # test case specific file if test failure is encountered.
1457 self.log_basename = self.getLogBasenameForCurrentTest()
1459 session_file = "{}.log".format(self.log_basename)
1460 # Python 3 doesn't support unbuffered I/O in text mode. Open buffered.
1461 self.session = open(session_file, "w")
1463 # Optimistically set __errored__, __failed__, __expected__ to False
1464 # initially. If the test errored/failed, the session info
1465 # (self.session) is then dumped into a session specific file for
1467 self.__cleanup_errored__ = False
1468 self.__errored__ = False
1469 self.__failed__ = False
1470 self.__expected__ = False
1471 # We are also interested in unexpected success.
1472 self.__unexpected__ = False
1473 # And skipped tests.
1474 self.__skipped__ = False
1476 # See addTearDownHook(self, hook) which allows the client to add a hook
1477 # function to be run during tearDown() time.
1480 # See HideStdout(self).
1481 self.sys_stdout_hidden = False
1483 if self.platformContext:
1484 # set environment variable names for finding shared libraries
1485 self.dylibPath = self.platformContext.shlib_environment_var
1487 # Create the debugger instance if necessary.
1490 except AttributeError:
1491 self.dbg = lldb.SBDebugger.Create()
1494 raise Exception('Invalid debugger instance')
1496 # Retrieve the associated command interpreter instance.
1497 self.ci = self.dbg.GetCommandInterpreter()
1499 raise Exception('Could not get the command interpreter')
1501 # And the result object.
1502 self.res = lldb.SBCommandReturnObject()
1504 self.enableLogChannelsForCurrentTest()
1506 #Initialize debug_info
1507 self.debug_info = None
1509 def setAsync(self, value):
1510 """ Sets async mode to True/False and ensures it is reset after the testcase completes."""
1511 old_async = self.dbg.GetAsync()
1512 self.dbg.SetAsync(value)
1513 self.addTearDownHook(lambda: self.dbg.SetAsync(old_async))
1515 def cleanupSubprocesses(self):
1516 # Ensure any subprocesses are cleaned up
1517 for p in self.subprocesses:
1520 del self.subprocesses[:]
1521 # Ensure any forked processes are cleaned up
1522 for pid in self.forkedProcessPids:
1523 if os.path.exists("/proc/" + str(pid)):
1524 os.kill(pid, signal.SIGTERM)
1526 def spawnSubprocess(self, executable, args=[], install_remote=True):
1527 """ Creates a subprocess.Popen object with the specified executable and arguments,
1528 saves it in self.subprocesses, and returns the object.
1529 NOTE: if using this function, ensure you also call:
1531 self.addTearDownHook(self.cleanupSubprocesses)
1533 otherwise the test suite will leak processes.
1535 proc = _RemoteProcess(install_remote) if lldb.remote_platform else _LocalProcess(self.TraceOn())
1536 proc.launch(executable, args)
1537 self.subprocesses.append(proc)
1540 def forkSubprocess(self, executable, args=[]):
1541 """ Fork a subprocess with its own group ID.
1542 NOTE: if using this function, ensure you also call:
1544 self.addTearDownHook(self.cleanupSubprocesses)
1546 otherwise the test suite will leak processes.
1548 child_pid = os.fork()
1550 # If more I/O support is required, this can be beefed up.
1551 fd = os.open(os.devnull, os.O_RDWR)
1554 # This call causes the child to have its of group ID
1556 os.execvp(executable, [executable] + args)
1557 # Give the child time to get through the execvp() call
1559 self.forkedProcessPids.append(child_pid)
1562 def HideStdout(self):
1563 """Hide output to stdout from the user.
1565 During test execution, there might be cases where we don't want to show the
1566 standard output to the user. For example,
1568 self.runCmd(r'''sc print("\n\n\tHello!\n")''')
1570 tests whether command abbreviation for 'script' works or not. There is no
1571 need to show the 'Hello' output to the user as long as the 'script' command
1572 succeeds and we are not in TraceOn() mode (see the '-t' option).
1574 In this case, the test method calls self.HideStdout(self) to redirect the
1575 sys.stdout to a null device, and restores the sys.stdout upon teardown.
1577 Note that you should only call this method at most once during a test case
1578 execution. Any subsequent call has no effect at all."""
1579 if self.sys_stdout_hidden:
1582 self.sys_stdout_hidden = True
1583 old_stdout = sys.stdout
1584 sys.stdout = open(os.devnull, 'w')
1585 def restore_stdout():
1586 sys.stdout = old_stdout
1587 self.addTearDownHook(restore_stdout)
1589 # =======================================================================
1590 # Methods for customized teardown cleanups as well as execution of hooks.
1591 # =======================================================================
1593 def setTearDownCleanup(self, dictionary=None):
1594 """Register a cleanup action at tearDown() time with a dictinary"""
1595 self.dict = dictionary
1596 self.doTearDownCleanup = True
1598 def addTearDownCleanup(self, dictionary):
1599 """Add a cleanup action at tearDown() time with a dictinary"""
1600 self.dicts.append(dictionary)
1601 self.doTearDownCleanups = True
1603 def addTearDownHook(self, hook):
1605 Add a function to be run during tearDown() time.
1607 Hooks are executed in a first come first serve manner.
1609 if six.callable(hook):
1610 with recording(self, traceAlways) as sbuf:
1611 print("Adding tearDown hook:", getsource_if_available(hook), file=sbuf)
1612 self.hooks.append(hook)
1616 def deletePexpectChild(self):
1617 # This is for the case of directly spawning 'lldb' and interacting with it
1619 if self.child and self.child.isalive():
1621 with recording(self, traceAlways) as sbuf:
1622 print("tearing down the child process....", file=sbuf)
1624 if self.child_in_script_interpreter:
1625 self.child.sendline('quit()')
1626 self.child.expect_exact(self.child_prompt)
1627 self.child.sendline('settings set interpreter.prompt-on-quit false')
1628 self.child.sendline('quit')
1629 self.child.expect(pexpect.EOF)
1630 except (ValueError, pexpect.ExceptionPexpect):
1631 # child is already terminated
1633 except OSError as exception:
1635 if exception.errno != errno.EIO:
1638 # child is already terminated
1641 # Give it one final blow to make sure the child is terminated.
1645 """Fixture for unittest test case teardown."""
1647 #traceback.print_stack()
1649 self.deletePexpectChild()
1651 # Check and run any hook functions.
1652 for hook in reversed(self.hooks):
1653 with recording(self, traceAlways) as sbuf:
1654 print("Executing tearDown hook:", getsource_if_available(hook), file=sbuf)
1656 hook_argc = len(inspect.getargspec(hook).args)
1657 if hook_argc == 0 or getattr(hook,'im_self',None):
1659 elif hook_argc == 1:
1662 hook() # try the plain call and hope it works
1666 # Perform registered teardown cleanup.
1667 if doCleanup and self.doTearDownCleanup:
1668 self.cleanup(dictionary=self.dict)
1670 # In rare cases where there are multiple teardown cleanups added.
1671 if doCleanup and self.doTearDownCleanups:
1673 for dict in reversed(self.dicts):
1674 self.cleanup(dictionary=dict)
1676 self.disableLogChannelsForCurrentTest()
1678 # =========================================================
1679 # Various callbacks to allow introspection of test progress
1680 # =========================================================
1682 def markError(self):
1683 """Callback invoked when an error (unexpected exception) errored."""
1684 self.__errored__ = True
1685 with recording(self, False) as sbuf:
1686 # False because there's no need to write "ERROR" to the stderr twice.
1687 # Once by the Python unittest framework, and a second time by us.
1688 print("ERROR", file=sbuf)
1690 def markCleanupError(self):
1691 """Callback invoked when an error occurs while a test is cleaning up."""
1692 self.__cleanup_errored__ = True
1693 with recording(self, False) as sbuf:
1694 # False because there's no need to write "CLEANUP_ERROR" to the stderr twice.
1695 # Once by the Python unittest framework, and a second time by us.
1696 print("CLEANUP_ERROR", file=sbuf)
1698 def markFailure(self):
1699 """Callback invoked when a failure (test assertion failure) occurred."""
1700 self.__failed__ = True
1701 with recording(self, False) as sbuf:
1702 # False because there's no need to write "FAIL" to the stderr twice.
1703 # Once by the Python unittest framework, and a second time by us.
1704 print("FAIL", file=sbuf)
1706 def markExpectedFailure(self,err,bugnumber):
1707 """Callback invoked when an expected failure/error occurred."""
1708 self.__expected__ = True
1709 with recording(self, False) as sbuf:
1710 # False because there's no need to write "expected failure" to the
1712 # Once by the Python unittest framework, and a second time by us.
1713 if bugnumber == None:
1714 print("expected failure", file=sbuf)
1716 print("expected failure (problem id:" + str(bugnumber) + ")", file=sbuf)
1718 def markSkippedTest(self):
1719 """Callback invoked when a test is skipped."""
1720 self.__skipped__ = True
1721 with recording(self, False) as sbuf:
1722 # False because there's no need to write "skipped test" to the
1724 # Once by the Python unittest framework, and a second time by us.
1725 print("skipped test", file=sbuf)
1727 def markUnexpectedSuccess(self, bugnumber):
1728 """Callback invoked when an unexpected success occurred."""
1729 self.__unexpected__ = True
1730 with recording(self, False) as sbuf:
1731 # False because there's no need to write "unexpected success" to the
1733 # Once by the Python unittest framework, and a second time by us.
1734 if bugnumber == None:
1735 print("unexpected success", file=sbuf)
1737 print("unexpected success (problem id:" + str(bugnumber) + ")", file=sbuf)
1739 def getRerunArgs(self):
1740 return " -f %s.%s" % (self.__class__.__name__, self._testMethodName)
1742 def getLogBasenameForCurrentTest(self, prefix=None):
1744 returns a partial path that can be used as the beginning of the name of multiple
1745 log files pertaining to this test
1747 <session-dir>/<arch>-<compiler>-<test-file>.<test-class>.<test-method>
1749 dname = os.path.join(os.environ["LLDB_TEST"],
1750 os.environ["LLDB_SESSION_DIRNAME"])
1751 if not os.path.isdir(dname):
1754 compiler = self.getCompiler()
1756 if compiler[1] == ':':
1757 compiler = compiler[2:]
1758 if os.path.altsep is not None:
1759 compiler = compiler.replace(os.path.altsep, os.path.sep)
1761 fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), "_".join(compiler.split(os.path.sep)))
1762 if len(fname) > 200:
1763 fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), compiler.split(os.path.sep)[-1])
1765 if prefix is not None:
1766 fname = "{}-{}".format(prefix, fname)
1768 return os.path.join(dname, fname)
1770 def dumpSessionInfo(self):
1772 Dump the debugger interactions leading to a test error/failure. This
1773 allows for more convenient postmortem analysis.
1775 See also LLDBTestResult (dotest.py) which is a singlton class derived
1776 from TextTestResult and overwrites addError, addFailure, and
1777 addExpectedFailure methods to allow us to to mark the test instance as
1781 # We are here because self.tearDown() detected that this test instance
1782 # either errored or failed. The lldb.test_result singleton contains
1783 # two lists (erros and failures) which get populated by the unittest
1784 # framework. Look over there for stack trace information.
1786 # The lists contain 2-tuples of TestCase instances and strings holding
1787 # formatted tracebacks.
1789 # See http://docs.python.org/library/unittest.html#unittest.TestResult.
1791 # output tracebacks into session
1793 if self.__errored__:
1794 pairs = configuration.test_result.errors
1796 elif self.__cleanup_errored__:
1797 pairs = configuration.test_result.cleanup_errors
1798 prefix = 'CleanupError'
1799 elif self.__failed__:
1800 pairs = configuration.test_result.failures
1802 elif self.__expected__:
1803 pairs = configuration.test_result.expectedFailures
1804 prefix = 'ExpectedFailure'
1805 elif self.__skipped__:
1806 prefix = 'SkippedTest'
1807 elif self.__unexpected__:
1808 prefix = 'UnexpectedSuccess'
1812 if not self.__unexpected__ and not self.__skipped__:
1813 for test, traceback in pairs:
1815 print(traceback, file=self.session)
1817 # put footer (timestamp/rerun instructions) into session
1818 testMethod = getattr(self, self._testMethodName)
1819 if getattr(testMethod, "__benchmarks_test__", False):
1825 print("Session info generated @", datetime.datetime.now().ctime(), file=self.session)
1826 print("To rerun this test, issue the following command from the 'test' directory:\n", file=self.session)
1827 print("./dotest.py %s -v %s %s" % (self.getRunOptions(),
1828 ('+b' if benchmarks else '-t'),
1829 self.getRerunArgs()), file=self.session)
1830 self.session.close()
1833 # process the log files
1834 log_files_for_this_test = glob.glob(self.log_basename + "*")
1836 if prefix != 'Success' or lldbtest_config.log_success:
1837 # keep all log files, rename them to include prefix
1838 dst_log_basename = self.getLogBasenameForCurrentTest(prefix)
1839 for src in log_files_for_this_test:
1840 if os.path.isfile(src):
1841 dst = src.replace(self.log_basename, dst_log_basename)
1842 if os.name == "nt" and os.path.isfile(dst):
1843 # On Windows, renaming a -> b will throw an exception if b exists. On non-Windows platforms
1844 # it silently replaces the destination. Ultimately this means that atomic renames are not
1845 # guaranteed to be possible on Windows, but we need this to work anyway, so just remove the
1846 # destination first if it already exists.
1851 # success! (and we don't want log files) delete log files
1852 for log_file in log_files_for_this_test:
1856 # We've seen consistent unlink failures on Windows, perhaps because the
1857 # just-created log file is being scanned by anti-virus. Empirically, this
1858 # sleep-and-retry approach allows tests to succeed much more reliably.
1859 # Attempts to figure out exactly what process was still holding a file handle
1860 # have failed because running instrumentation like Process Monitor seems to
1861 # slow things down enough that the problem becomes much less consistent.
1865 # ====================================================
1866 # Config. methods supported through a plugin interface
1867 # (enables reading of the current test configuration)
1868 # ====================================================
1870 def getArchitecture(self):
1871 """Returns the architecture in effect the test suite is running with."""
1872 module = builder_module()
1873 arch = module.getArchitecture()
1878 def getLldbArchitecture(self):
1879 """Returns the architecture of the lldb binary."""
1880 if not hasattr(self, 'lldbArchitecture'):
1882 # spawn local process
1884 lldbtest_config.lldbExec,
1886 "file " + lldbtest_config.lldbExec,
1891 output = check_output(command)
1892 str = output.decode("utf-8");
1894 for line in str.splitlines():
1895 m = re.search("Current executable set to '.*' \\((.*)\\)\\.", line)
1897 self.lldbArchitecture = m.group(1)
1900 return self.lldbArchitecture
1902 def getCompiler(self):
1903 """Returns the compiler in effect the test suite is running with."""
1904 module = builder_module()
1905 return module.getCompiler()
1907 def getCompilerBinary(self):
1908 """Returns the compiler binary the test suite is running with."""
1909 return self.getCompiler().split()[0]
1911 def getCompilerVersion(self):
1912 """ Returns a string that represents the compiler version.
1913 Supports: llvm, clang.
1915 from .lldbutil import which
1918 compiler = self.getCompilerBinary()
1919 version_output = system([[which(compiler), "-v"]])[1]
1920 for line in version_output.split(os.linesep):
1921 m = re.search('version ([0-9\.]+)', line)
1923 version = m.group(1)
1926 def getGoCompilerVersion(self):
1927 """ Returns a string that represents the go compiler version, or None if go is not found.
1929 compiler = which("go")
1931 version_output = system([[compiler, "version"]])[0]
1932 for line in version_output.split(os.linesep):
1933 m = re.search('go version (devel|go\\S+)', line)
1938 def platformIsDarwin(self):
1939 """Returns true if the OS triple for the selected platform is any valid apple OS"""
1940 return platformIsDarwin()
1942 def getPlatform(self):
1943 """Returns the target platform the test suite is running on."""
1944 return getPlatform()
1946 def isIntelCompiler(self):
1947 """ Returns true if using an Intel (ICC) compiler, false otherwise. """
1948 return any([x in self.getCompiler() for x in ["icc", "icpc", "icl"]])
1950 def expectedCompilerVersion(self, compiler_version):
1951 """Returns True iff compiler_version[1] matches the current compiler version.
1952 Use compiler_version[0] to specify the operator used to determine if a match has occurred.
1953 Any operator other than the following defaults to an equality test:
1954 '>', '>=', "=>", '<', '<=', '=<', '!=', "!" or 'not'
1956 if (compiler_version == None):
1958 operator = str(compiler_version[0])
1959 version = compiler_version[1]
1961 if (version == None):
1963 if (operator == '>'):
1964 return self.getCompilerVersion() > version
1965 if (operator == '>=' or operator == '=>'):
1966 return self.getCompilerVersion() >= version
1967 if (operator == '<'):
1968 return self.getCompilerVersion() < version
1969 if (operator == '<=' or operator == '=<'):
1970 return self.getCompilerVersion() <= version
1971 if (operator == '!=' or operator == '!' or operator == 'not'):
1972 return str(version) not in str(self.getCompilerVersion())
1973 return str(version) in str(self.getCompilerVersion())
1975 def expectedCompiler(self, compilers):
1976 """Returns True iff any element of compilers is a sub-string of the current compiler."""
1977 if (compilers == None):
1980 for compiler in compilers:
1981 if compiler in self.getCompiler():
1986 def expectedArch(self, archs):
1987 """Returns True iff any element of archs is a sub-string of the current architecture."""
1992 if arch in self.getArchitecture():
1997 def getRunOptions(self):
1998 """Command line option for -A and -C to run this test again, called from
1999 self.dumpSessionInfo()."""
2000 arch = self.getArchitecture()
2001 comp = self.getCompiler()
2003 option_str = "-A " + arch
2007 option_str += " -C " + comp
2010 # ==================================================
2011 # Build methods supported through a plugin interface
2012 # ==================================================
2014 def getstdlibFlag(self):
2015 """ Returns the proper -stdlib flag, or empty if not required."""
2016 if self.platformIsDarwin() or self.getPlatform() == "freebsd":
2017 stdlibflag = "-stdlib=libc++"
2018 else: # this includes NetBSD
2022 def getstdFlag(self):
2023 """ Returns the proper stdflag. """
2024 if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
2025 stdflag = "-std=c++0x"
2027 stdflag = "-std=c++11"
2030 def buildDriver(self, sources, exe_name):
2031 """ Platform-specific way to build a program that links with LLDB (via the liblldb.so
2035 stdflag = self.getstdFlag()
2036 stdlibflag = self.getstdlibFlag()
2038 lib_dir = os.environ["LLDB_LIB_DIR"]
2039 if sys.platform.startswith("darwin"):
2040 dsym = os.path.join(lib_dir, 'LLDB.framework', 'LLDB')
2041 d = {'CXX_SOURCES' : sources,
2043 'CFLAGS_EXTRAS' : "%s %s" % (stdflag, stdlibflag),
2044 'FRAMEWORK_INCLUDES' : "-F%s" % lib_dir,
2045 'LD_EXTRAS' : "%s -Wl,-rpath,%s" % (dsym, lib_dir),
2047 elif sys.platform.rstrip('0123456789') in ('freebsd', 'linux', 'netbsd') or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
2048 d = {'CXX_SOURCES' : sources,
2050 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2051 'LD_EXTRAS' : "-L%s -llldb" % lib_dir}
2052 elif sys.platform.startswith('win'):
2053 d = {'CXX_SOURCES' : sources,
2055 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2056 'LD_EXTRAS' : "-L%s -lliblldb" % os.environ["LLDB_IMPLIB_DIR"]}
2058 print("Building LLDB Driver (%s) from sources %s" % (exe_name, sources))
2060 self.buildDefault(dictionary=d)
2062 def buildLibrary(self, sources, lib_name):
2063 """Platform specific way to build a default library. """
2065 stdflag = self.getstdFlag()
2067 lib_dir = os.environ["LLDB_LIB_DIR"]
2068 if self.platformIsDarwin():
2069 dsym = os.path.join(lib_dir, 'LLDB.framework', 'LLDB')
2070 d = {'DYLIB_CXX_SOURCES' : sources,
2071 'DYLIB_NAME' : lib_name,
2072 'CFLAGS_EXTRAS' : "%s -stdlib=libc++" % stdflag,
2073 'FRAMEWORK_INCLUDES' : "-F%s" % lib_dir,
2074 'LD_EXTRAS' : "%s -Wl,-rpath,%s -dynamiclib" % (dsym, lib_dir),
2076 elif self.getPlatform() in ('freebsd', 'linux', 'netbsd') or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
2077 d = {'DYLIB_CXX_SOURCES' : sources,
2078 'DYLIB_NAME' : lib_name,
2079 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2080 'LD_EXTRAS' : "-shared -L%s -llldb" % lib_dir}
2081 elif self.getPlatform() == 'windows':
2082 d = {'DYLIB_CXX_SOURCES' : sources,
2083 'DYLIB_NAME' : lib_name,
2084 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2085 'LD_EXTRAS' : "-shared -l%s\liblldb.lib" % self.os.environ["LLDB_IMPLIB_DIR"]}
2087 print("Building LLDB Library (%s) from sources %s" % (lib_name, sources))
2089 self.buildDefault(dictionary=d)
2091 def buildProgram(self, sources, exe_name):
2092 """ Platform specific way to build an executable from C/C++ sources. """
2093 d = {'CXX_SOURCES' : sources,
2095 self.buildDefault(dictionary=d)
2097 def buildDefault(self, architecture=None, compiler=None, dictionary=None, clean=True):
2098 """Platform specific way to build the default binaries."""
2099 module = builder_module()
2100 if target_is_android():
2101 dictionary = append_android_envs(dictionary)
2102 if not module.buildDefault(self, architecture, compiler, dictionary, clean):
2103 raise Exception("Don't know how to build default binary")
2105 def buildDsym(self, architecture=None, compiler=None, dictionary=None, clean=True):
2106 """Platform specific way to build binaries with dsym info."""
2107 module = builder_module()
2108 if not module.buildDsym(self, architecture, compiler, dictionary, clean):
2109 raise Exception("Don't know how to build binary with dsym")
2111 def buildDwarf(self, architecture=None, compiler=None, dictionary=None, clean=True):
2112 """Platform specific way to build binaries with dwarf maps."""
2113 module = builder_module()
2114 if target_is_android():
2115 dictionary = append_android_envs(dictionary)
2116 if not module.buildDwarf(self, architecture, compiler, dictionary, clean):
2117 raise Exception("Don't know how to build binary with dwarf")
2119 def buildDwo(self, architecture=None, compiler=None, dictionary=None, clean=True):
2120 """Platform specific way to build binaries with dwarf maps."""
2121 module = builder_module()
2122 if target_is_android():
2123 dictionary = append_android_envs(dictionary)
2124 if not module.buildDwo(self, architecture, compiler, dictionary, clean):
2125 raise Exception("Don't know how to build binary with dwo")
2128 """Build the default go binary.
2130 system([[which('go'), 'build -gcflags "-N -l" -o a.out main.go']])
2132 def signBinary(self, binary_path):
2133 if sys.platform.startswith("darwin"):
2134 codesign_cmd = "codesign --force --sign lldb_codesign %s" % (binary_path)
2135 call(codesign_cmd, shell=True)
2137 def findBuiltClang(self):
2138 """Tries to find and use Clang from the build directory as the compiler (instead of the system compiler)."""
2140 "llvm-build/Release+Asserts/x86_64/Release+Asserts/bin/clang",
2141 "llvm-build/Debug+Asserts/x86_64/Debug+Asserts/bin/clang",
2142 "llvm-build/Release/x86_64/Release/bin/clang",
2143 "llvm-build/Debug/x86_64/Debug/bin/clang",
2145 lldb_root_path = os.path.join(os.path.dirname(__file__), "..", "..", "..", "..")
2146 for p in paths_to_try:
2147 path = os.path.join(lldb_root_path, p)
2148 if os.path.exists(path):
2151 # Tries to find clang at the same folder as the lldb
2152 path = os.path.join(os.path.dirname(lldbtest_config.lldbExec), "clang")
2153 if os.path.exists(path):
2156 return os.environ["CC"]
2158 def getBuildFlags(self, use_cpp11=True, use_libcxx=False, use_libstdcxx=False):
2159 """ Returns a dictionary (which can be provided to build* functions above) which
2160 contains OS-specific build flags.
2165 # On Mac OS X, unless specifically requested to use libstdc++, use libc++
2166 if not use_libstdcxx and self.platformIsDarwin():
2169 if use_libcxx and self.libcxxPath:
2170 cflags += "-stdlib=libc++ "
2172 libcxxInclude = os.path.join(self.libcxxPath, "include")
2173 libcxxLib = os.path.join(self.libcxxPath, "lib")
2174 if os.path.isdir(libcxxInclude) and os.path.isdir(libcxxLib):
2175 cflags += "-nostdinc++ -I%s -L%s -Wl,-rpath,%s " % (libcxxInclude, libcxxLib, libcxxLib)
2179 if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
2183 if self.platformIsDarwin() or self.getPlatform() == "freebsd":
2184 cflags += " -stdlib=libc++"
2185 elif self.getPlatform() == "netbsd":
2186 cflags += " -stdlib=libstdc++"
2187 elif "clang" in self.getCompiler():
2188 cflags += " -stdlib=libstdc++"
2190 return {'CFLAGS_EXTRAS' : cflags,
2191 'LD_EXTRAS' : ldflags,
2194 def cleanup(self, dictionary=None):
2195 """Platform specific way to do cleanup after build."""
2196 module = builder_module()
2197 if not module.cleanup(self, dictionary):
2198 raise Exception("Don't know how to do cleanup with dictionary: "+dictionary)
2200 def getLLDBLibraryEnvVal(self):
2201 """ Returns the path that the OS-specific library search environment variable
2202 (self.dylibPath) should be set to in order for a program to find the LLDB
2203 library. If an environment variable named self.dylibPath is already set,
2204 the new path is appended to it and returned.
2206 existing_library_path = os.environ[self.dylibPath] if self.dylibPath in os.environ else None
2207 lib_dir = os.environ["LLDB_LIB_DIR"]
2208 if existing_library_path:
2209 return "%s:%s" % (existing_library_path, lib_dir)
2210 elif sys.platform.startswith("darwin"):
2211 return os.path.join(lib_dir, 'LLDB.framework')
2215 def getLibcPlusPlusLibs(self):
2216 if self.getPlatform() in ('freebsd', 'linux', 'netbsd'):
2217 return ['libc++.so.1']
2219 return ['libc++.1.dylib','libc++abi.dylib']
2221 # Metaclass for TestBase to change the list of test metods when a new TestCase is loaded.
2222 # We change the test methods to create a new test method for each test for each debug info we are
2223 # testing. The name of the new test method will be '<original-name>_<debug-info>' and with adding
2224 # the new test method we remove the old method at the same time.
2225 class LLDBTestCaseFactory(type):
2226 def __new__(cls, name, bases, attrs):
2228 for attrname, attrvalue in attrs.items():
2229 if attrname.startswith("test") and not getattr(attrvalue, "__no_debug_info_test__", False):
2230 target_platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
2232 # If any debug info categories were explicitly tagged, assume that list to be
2233 # authoritative. If none were specified, try with all debug info formats.
2234 all_dbginfo_categories = set(test_categories.debug_info_categories)
2235 categories = set(getattr(attrvalue, "categories", [])) & all_dbginfo_categories
2237 categories = all_dbginfo_categories
2239 supported_categories = [x for x in categories
2240 if test_categories.is_supported_on_platform(x, target_platform)]
2241 if "dsym" in supported_categories:
2242 @add_test_categories(["dsym"])
2244 def dsym_test_method(self, attrvalue=attrvalue):
2245 self.debug_info = "dsym"
2246 return attrvalue(self)
2247 dsym_method_name = attrname + "_dsym"
2248 dsym_test_method.__name__ = dsym_method_name
2249 newattrs[dsym_method_name] = dsym_test_method
2251 if "dwarf" in supported_categories:
2252 @add_test_categories(["dwarf"])
2254 def dwarf_test_method(self, attrvalue=attrvalue):
2255 self.debug_info = "dwarf"
2256 return attrvalue(self)
2257 dwarf_method_name = attrname + "_dwarf"
2258 dwarf_test_method.__name__ = dwarf_method_name
2259 newattrs[dwarf_method_name] = dwarf_test_method
2261 if "dwo" in supported_categories:
2262 @add_test_categories(["dwo"])
2264 def dwo_test_method(self, attrvalue=attrvalue):
2265 self.debug_info = "dwo"
2266 return attrvalue(self)
2267 dwo_method_name = attrname + "_dwo"
2268 dwo_test_method.__name__ = dwo_method_name
2269 newattrs[dwo_method_name] = dwo_test_method
2271 newattrs[attrname] = attrvalue
2272 return super(LLDBTestCaseFactory, cls).__new__(cls, name, bases, newattrs)
2274 # Setup the metaclass for this class to change the list of the test methods when a new class is loaded
2275 @add_metaclass(LLDBTestCaseFactory)
2276 class TestBase(Base):
2278 This abstract base class is meant to be subclassed. It provides default
2279 implementations for setUpClass(), tearDownClass(), setUp(), and tearDown(),
2282 Important things for test class writers:
2284 - Overwrite the mydir class attribute, otherwise your test class won't
2285 run. It specifies the relative directory to the top level 'test' so
2286 the test harness can change to the correct working directory before
2289 - The setUp method sets up things to facilitate subsequent interactions
2290 with the debugger as part of the test. These include:
2291 - populate the test method name
2292 - create/get a debugger set with synchronous mode (self.dbg)
2293 - get the command interpreter from with the debugger (self.ci)
2294 - create a result object for use with the command interpreter
2298 - The tearDown method tries to perform some necessary cleanup on behalf
2299 of the test to return the debugger to a good state for the next test.
2301 - execute any tearDown hooks registered by the test method with
2302 TestBase.addTearDownHook(); examples can be found in
2303 settings/TestSettings.py
2304 - kill the inferior process associated with each target, if any,
2305 and, then delete the target from the debugger's target list
2306 - perform build cleanup before running the next test method in the
2307 same test class; examples of registering for this service can be
2308 found in types/TestIntegerTypes.py with the call:
2309 - self.setTearDownCleanup(dictionary=d)
2311 - Similarly setUpClass and tearDownClass perform classwise setup and
2312 teardown fixtures. The tearDownClass method invokes a default build
2313 cleanup for the entire test class; also, subclasses can implement the
2314 classmethod classCleanup(cls) to perform special class cleanup action.
2316 - The instance methods runCmd and expect are used heavily by existing
2317 test cases to send a command to the command interpreter and to perform
2318 string/pattern matching on the output of such command execution. The
2319 expect method also provides a mode to peform string/pattern matching
2320 without running a command.
2322 - The build methods buildDefault, buildDsym, and buildDwarf are used to
2323 build the binaries used during a particular test scenario. A plugin
2324 should be provided for the sys.platform running the test suite. The
2325 Mac OS X implementation is located in plugins/darwin.py.
2328 # Maximum allowed attempts when launching the inferior process.
2329 # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
2332 # Time to wait before the next launching attempt in second(s).
2333 # Can be overridden by the LLDB_TIME_WAIT_NEXT_LAUNCH environment variable.
2334 timeWaitNextLaunch = 1.0;
2336 # Returns the list of categories to which this test case belongs
2337 # by default, look for a ".categories" file, and read its contents
2338 # if no such file exists, traverse the hierarchy - we guarantee
2339 # a .categories to exist at the top level directory so we do not end up
2340 # looping endlessly - subclasses are free to define their own categories
2341 # in whatever way makes sense to them
2342 def getCategories(self):
2345 folder = inspect.getfile(self.__class__)
2346 folder = os.path.dirname(folder)
2347 while folder != '/':
2348 categories_file_name = os.path.join(folder,".categories")
2349 if os.path.exists(categories_file_name):
2350 categories_file = open(categories_file_name,'r')
2351 categories = categories_file.readline()
2352 categories_file.close()
2353 categories = str.replace(categories,'\n','')
2354 categories = str.replace(categories,'\r','')
2355 return categories.split(',')
2357 folder = os.path.dirname(folder)
2362 #traceback.print_stack()
2364 # Works with the test driver to conditionally skip tests via decorators.
2367 if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
2368 self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])
2370 if "LLDB_TIME_WAIT_NEXT_LAUNCH" in os.environ:
2371 self.timeWaitNextLaunch = float(os.environ["LLDB_TIME_WAIT_NEXT_LAUNCH"])
2373 # We want our debugger to be synchronous.
2374 self.dbg.SetAsync(False)
2376 # Retrieve the associated command interpreter instance.
2377 self.ci = self.dbg.GetCommandInterpreter()
2379 raise Exception('Could not get the command interpreter')
2381 # And the result object.
2382 self.res = lldb.SBCommandReturnObject()
2384 if lldb.remote_platform and configuration.lldb_platform_working_dir:
2385 remote_test_dir = lldbutil.join_remote_paths(
2386 configuration.lldb_platform_working_dir,
2387 self.getArchitecture(),
2388 str(self.test_number),
2390 error = lldb.remote_platform.MakeDirectory(remote_test_dir, 448) # 448 = 0o700
2392 lldb.remote_platform.SetWorkingDirectory(remote_test_dir)
2394 # This function removes all files from the current working directory while leaving
2395 # the directories in place. The cleaup is required to reduce the disk space required
2396 # by the test suit while leaving the directories untached is neccessary because
2397 # sub-directories might belong to an other test
2398 def clean_working_directory():
2399 # TODO: Make it working on Windows when we need it for remote debugging support
2400 # TODO: Replace the heuristic to remove the files with a logic what collects the
2401 # list of files we have to remove during test runs.
2402 shell_cmd = lldb.SBPlatformShellCommand("rm %s/*" % remote_test_dir)
2403 lldb.remote_platform.Run(shell_cmd)
2404 self.addTearDownHook(clean_working_directory)
2406 print("error: making remote directory '%s': %s" % (remote_test_dir, error))
2408 def registerSharedLibrariesWithTarget(self, target, shlibs):
2409 '''If we are remotely running the test suite, register the shared libraries with the target so they get uploaded, otherwise do nothing
2411 Any modules in the target that have their remote install file specification set will
2412 get uploaded to the remote host. This function registers the local copies of the
2413 shared libraries with the target and sets their remote install locations so they will
2414 be uploaded when the target is run.
2416 if not shlibs or not self.platformContext:
2419 shlib_environment_var = self.platformContext.shlib_environment_var
2420 shlib_prefix = self.platformContext.shlib_prefix
2421 shlib_extension = '.' + self.platformContext.shlib_extension
2423 working_dir = self.get_process_working_directory()
2424 environment = ['%s=%s' % (shlib_environment_var, working_dir)]
2425 # Add any shared libraries to our target if remote so they get
2426 # uploaded into the working directory on the remote side
2428 # The path can be a full path to a shared library, or a make file name like "Foo" for
2429 # "libFoo.dylib" or "libFoo.so", or "Foo.so" for "Foo.so" or "libFoo.so", or just a
2430 # basename like "libFoo.so". So figure out which one it is and resolve the local copy
2431 # of the shared library accordingly
2432 if os.path.exists(name):
2433 local_shlib_path = name # name is the full path to the local shared library
2435 # Check relative names
2436 local_shlib_path = os.path.join(os.getcwd(), shlib_prefix + name + shlib_extension)
2437 if not os.path.exists(local_shlib_path):
2438 local_shlib_path = os.path.join(os.getcwd(), name + shlib_extension)
2439 if not os.path.exists(local_shlib_path):
2440 local_shlib_path = os.path.join(os.getcwd(), name)
2442 # Make sure we found the local shared library in the above code
2443 self.assertTrue(os.path.exists(local_shlib_path))
2445 # Add the shared library to our target
2446 shlib_module = target.AddModule(local_shlib_path, None, None, None)
2447 if lldb.remote_platform:
2448 # We must set the remote install location if we want the shared library
2449 # to get uploaded to the remote target
2450 remote_shlib_path = lldbutil.append_to_process_working_directory(os.path.basename(local_shlib_path))
2451 shlib_module.SetRemoteInstallFileSpec(lldb.SBFileSpec(remote_shlib_path, False))
2455 # utility methods that tests can use to access the current objects
2458 raise Exception('Invalid debugger instance')
2459 return self.dbg.GetSelectedTarget()
2463 raise Exception('Invalid debugger instance')
2464 return self.dbg.GetSelectedTarget().GetProcess()
2468 raise Exception('Invalid debugger instance')
2469 return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread()
2473 raise Exception('Invalid debugger instance')
2474 return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
2476 def get_process_working_directory(self):
2477 '''Get the working directory that should be used when launching processes for local or remote processes.'''
2478 if lldb.remote_platform:
2479 # Remote tests set the platform working directory up in TestBase.setUp()
2480 return lldb.remote_platform.GetWorkingDirectory()
2482 # local tests change directory into each test subdirectory
2487 #traceback.print_stack()
2489 # Ensure all the references to SB objects have gone away so that we can
2490 # be sure that all test-specific resources have been freed before we
2491 # attempt to delete the targets.
2494 # Delete the target(s) from the debugger as a general cleanup step.
2495 # This includes terminating the process for each target, if any.
2496 # We'd like to reuse the debugger for our next test without incurring
2497 # the initialization overhead.
2499 for target in self.dbg:
2501 targets.append(target)
2502 process = target.GetProcess()
2504 rc = self.invoke(process, "Kill")
2505 self.assertTrue(rc.Success(), PROCESS_KILLED)
2506 for target in targets:
2507 self.dbg.DeleteTarget(target)
2509 # Do this last, to make sure it's in reverse order from how we setup.
2512 # This must be the last statement, otherwise teardown hooks or other
2513 # lines might depend on this still being active.
2516 def switch_to_thread_with_stop_reason(self, stop_reason):
2518 Run the 'thread list' command, and select the thread with stop reason as
2519 'stop_reason'. If no such thread exists, no select action is done.
2521 from .lldbutil import stop_reason_to_str
2522 self.runCmd('thread list')
2523 output = self.res.GetOutput()
2524 thread_line_pattern = re.compile("^[ *] thread #([0-9]+):.*stop reason = %s" %
2525 stop_reason_to_str(stop_reason))
2526 for line in output.splitlines():
2527 matched = thread_line_pattern.match(line)
2529 self.runCmd('thread select %s' % matched.group(1))
2531 def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False):
2533 Ask the command interpreter to handle the command and then check its
2536 # Fail fast if 'cmd' is not meaningful.
2537 if not cmd or len(cmd) == 0:
2538 raise Exception("Bad 'cmd' parameter encountered")
2540 trace = (True if traceAlways else trace)
2542 if cmd.startswith("target create "):
2543 cmd = cmd.replace("target create ", "file ")
2545 running = (cmd.startswith("run") or cmd.startswith("process launch"))
2547 for i in range(self.maxLaunchCount if running else 1):
2548 self.ci.HandleCommand(cmd, self.res, inHistory)
2550 with recording(self, trace) as sbuf:
2551 print("runCmd:", cmd, file=sbuf)
2553 print("check of return status not required", file=sbuf)
2554 if self.res.Succeeded():
2555 print("output:", self.res.GetOutput(), file=sbuf)
2557 print("runCmd failed!", file=sbuf)
2558 print(self.res.GetError(), file=sbuf)
2560 if self.res.Succeeded():
2563 # For process launch, wait some time before possible next try.
2564 time.sleep(self.timeWaitNextLaunch)
2565 with recording(self, trace) as sbuf:
2566 print("Command '" + cmd + "' failed!", file=sbuf)
2569 self.assertTrue(self.res.Succeeded(),
2570 msg if msg else CMD_MSG(cmd))
2572 def match (self, str, patterns, msg=None, trace=False, error=False, matching=True, exe=True):
2573 """run command in str, and match the result against regexp in patterns returning the match object for the first matching pattern
2575 Otherwise, all the arguments have the same meanings as for the expect function"""
2577 trace = (True if traceAlways else trace)
2580 # First run the command. If we are expecting error, set check=False.
2581 # Pass the assert message along since it provides more semantic info.
2582 self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error)
2584 # Then compare the output against expected strings.
2585 output = self.res.GetError() if error else self.res.GetOutput()
2587 # If error is True, the API client expects the command to fail!
2589 self.assertFalse(self.res.Succeeded(),
2590 "Command '" + str + "' is expected to fail!")
2592 # No execution required, just compare str against the golden input.
2594 with recording(self, trace) as sbuf:
2595 print("looking at:", output, file=sbuf)
2597 # The heading says either "Expecting" or "Not expecting".
2598 heading = "Expecting" if matching else "Not expecting"
2600 for pattern in patterns:
2601 # Match Objects always have a boolean value of True.
2602 match_object = re.search(pattern, output)
2603 matched = bool(match_object)
2604 with recording(self, trace) as sbuf:
2605 print("%s pattern: %s" % (heading, pattern), file=sbuf)
2606 print("Matched" if matched else "Not matched", file=sbuf)
2610 self.assertTrue(matched if matching else not matched,
2611 msg if msg else EXP_MSG(str, exe))
2615 def expect(self, str, msg=None, patterns=None, startstr=None, endstr=None, substrs=None, trace=False, error=False, matching=True, exe=True, inHistory=False):
2617 Similar to runCmd; with additional expect style output matching ability.
2619 Ask the command interpreter to handle the command and then check its
2620 return status. The 'msg' parameter specifies an informational assert
2621 message. We expect the output from running the command to start with
2622 'startstr', matches the substrings contained in 'substrs', and regexp
2623 matches the patterns contained in 'patterns'.
2625 If the keyword argument error is set to True, it signifies that the API
2626 client is expecting the command to fail. In this case, the error stream
2627 from running the command is retrieved and compared against the golden
2630 If the keyword argument matching is set to False, it signifies that the API
2631 client is expecting the output of the command not to match the golden
2634 Finally, the required argument 'str' represents the lldb command to be
2635 sent to the command interpreter. In case the keyword argument 'exe' is
2636 set to False, the 'str' is treated as a string to be matched/not-matched
2637 against the golden input.
2639 trace = (True if traceAlways else trace)
2642 # First run the command. If we are expecting error, set check=False.
2643 # Pass the assert message along since it provides more semantic info.
2644 self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error, inHistory=inHistory)
2646 # Then compare the output against expected strings.
2647 output = self.res.GetError() if error else self.res.GetOutput()
2649 # If error is True, the API client expects the command to fail!
2651 self.assertFalse(self.res.Succeeded(),
2652 "Command '" + str + "' is expected to fail!")
2654 # No execution required, just compare str against the golden input.
2655 if isinstance(str,lldb.SBCommandReturnObject):
2656 output = str.GetOutput()
2659 with recording(self, trace) as sbuf:
2660 print("looking at:", output, file=sbuf)
2662 # The heading says either "Expecting" or "Not expecting".
2663 heading = "Expecting" if matching else "Not expecting"
2665 # Start from the startstr, if specified.
2666 # If there's no startstr, set the initial state appropriately.
2667 matched = output.startswith(startstr) if startstr else (True if matching else False)
2670 with recording(self, trace) as sbuf:
2671 print("%s start string: %s" % (heading, startstr), file=sbuf)
2672 print("Matched" if matched else "Not matched", file=sbuf)
2674 # Look for endstr, if specified.
2675 keepgoing = matched if matching else not matched
2677 matched = output.endswith(endstr)
2678 with recording(self, trace) as sbuf:
2679 print("%s end string: %s" % (heading, endstr), file=sbuf)
2680 print("Matched" if matched else "Not matched", file=sbuf)
2682 # Look for sub strings, if specified.
2683 keepgoing = matched if matching else not matched
2684 if substrs and keepgoing:
2686 matched = output.find(str) != -1
2687 with recording(self, trace) as sbuf:
2688 print("%s sub string: %s" % (heading, str), file=sbuf)
2689 print("Matched" if matched else "Not matched", file=sbuf)
2690 keepgoing = matched if matching else not matched
2694 # Search for regular expression patterns, if specified.
2695 keepgoing = matched if matching else not matched
2696 if patterns and keepgoing:
2697 for pattern in patterns:
2698 # Match Objects always have a boolean value of True.
2699 matched = bool(re.search(pattern, output))
2700 with recording(self, trace) as sbuf:
2701 print("%s pattern: %s" % (heading, pattern), file=sbuf)
2702 print("Matched" if matched else "Not matched", file=sbuf)
2703 keepgoing = matched if matching else not matched
2707 self.assertTrue(matched if matching else not matched,
2708 msg if msg else EXP_MSG(str, exe))
2710 def invoke(self, obj, name, trace=False):
2711 """Use reflection to call a method dynamically with no argument."""
2712 trace = (True if traceAlways else trace)
2714 method = getattr(obj, name)
2716 self.assertTrue(inspect.ismethod(method),
2717 name + "is a method name of object: " + str(obj))
2719 with recording(self, trace) as sbuf:
2720 print(str(method) + ":", result, file=sbuf)
2723 def build(self, architecture=None, compiler=None, dictionary=None, clean=True):
2724 """Platform specific way to build the default binaries."""
2725 module = builder_module()
2726 if target_is_android():
2727 dictionary = append_android_envs(dictionary)
2728 if self.debug_info is None:
2729 return self.buildDefault(architecture, compiler, dictionary, clean)
2730 elif self.debug_info == "dsym":
2731 return self.buildDsym(architecture, compiler, dictionary, clean)
2732 elif self.debug_info == "dwarf":
2733 return self.buildDwarf(architecture, compiler, dictionary, clean)
2734 elif self.debug_info == "dwo":
2735 return self.buildDwo(architecture, compiler, dictionary, clean)
2737 self.fail("Can't build for debug info: %s" % self.debug_info)
2739 # =================================================
2740 # Misc. helper methods for debugging test execution
2741 # =================================================
2743 def DebugSBValue(self, val):
2744 """Debug print a SBValue object, if traceAlways is True."""
2745 from .lldbutil import value_type_to_str
2751 err.write(val.GetName() + ":\n")
2752 err.write('\t' + "TypeName -> " + val.GetTypeName() + '\n')
2753 err.write('\t' + "ByteSize -> " + str(val.GetByteSize()) + '\n')
2754 err.write('\t' + "NumChildren -> " + str(val.GetNumChildren()) + '\n')
2755 err.write('\t' + "Value -> " + str(val.GetValue()) + '\n')
2756 err.write('\t' + "ValueAsUnsigned -> " + str(val.GetValueAsUnsigned())+ '\n')
2757 err.write('\t' + "ValueType -> " + value_type_to_str(val.GetValueType()) + '\n')
2758 err.write('\t' + "Summary -> " + str(val.GetSummary()) + '\n')
2759 err.write('\t' + "IsPointerType -> " + str(val.TypeIsPointerType()) + '\n')
2760 err.write('\t' + "Location -> " + val.GetLocation() + '\n')
2762 def DebugSBType(self, type):
2763 """Debug print a SBType object, if traceAlways is True."""
2768 err.write(type.GetName() + ":\n")
2769 err.write('\t' + "ByteSize -> " + str(type.GetByteSize()) + '\n')
2770 err.write('\t' + "IsPointerType -> " + str(type.IsPointerType()) + '\n')
2771 err.write('\t' + "IsReferenceType -> " + str(type.IsReferenceType()) + '\n')
2773 def DebugPExpect(self, child):
2774 """Debug the spwaned pexpect object."""
2781 def RemoveTempFile(cls, file):
2782 if os.path.exists(file):