Adding the @skipIfAddressSanitizerUnsupported decorator, which detects whether
the compiler supports "-fsanitize=address", and skips the marked tests if not.
Getting rid of the stupid "findBuiltClang" logic, in favor of just using the
same compiler that you use for the rest of the tests.
Related to http://reviews.llvm.org/D6205. I also updated the ASan test cases to
react more properly to the "stop reason = exec", which is probably a OS X only
thing, on Linux where ASan is a static library, the relaunch doesn't happen.
Doug, could you try this patch on Ubuntu, if it resolves the test failure you
were seeing?
http://reviews.llvm.org/D6272
Files:
functionalities/asan/Makefile
functionalities/asan/TestMemoryHistory.py
functionalities/asan/TestReportData.py
lldbtest.py
Index: functionalities/asan/Makefile
===================================================================
--- functionalities/asan/Makefile
+++ functionalities/asan/Makefile
@@ -1,6 +1,5 @@
LEVEL = ../../make
C_SOURCES := main.c
-CFLAGS := $(CFLAGS) -fsanitize=address -g
include $(LEVEL)/Makefile.rules
Index: functionalities/asan/TestMemoryHistory.py
===================================================================
--- functionalities/asan/TestMemoryHistory.py
+++ functionalities/asan/TestMemoryHistory.py
@@ -12,24 +12,20 @@
mydir = TestBase.compute_mydir(__file__)
- # The default compiler ("clang") may not support Address Sanitizer or it
- # may not have the debugging API which was recently added, so we're calling
- # self.useBuiltClang() to use clang from the llvm-build directory instead
-
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@skipIfRemote
+ @skipIfAddressSanitizerUnsupported
@dsym_test
def test_with_dsym (self):
- compiler = self.findBuiltClang ()
- self.buildDsym (None, compiler)
+ self.buildDsym (None, None, {"CFLAGS": "-fsanitize=address -g"})
self.asan_tests ()
@skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
@skipIfRemote
+ @skipIfAddressSanitizerUnsupported
@dwarf_test
def test_with_dwarf (self):
- compiler = self.findBuiltClang ()
- self.buildDwarf (None, compiler)
+ self.buildDwarf (None, None, {"CFLAGS": "-fsanitize=address -g"})
self.asan_tests ()
def setUp(self):
@@ -53,11 +49,14 @@
self.runCmd("run")
- # ASan will relaunch the process to insert its library.
- self.expect("thread list", "Process should be stopped due to exec.",
- substrs = ['stopped', 'stop reason = exec'])
-
- self.runCmd("continue")
+ process = self.dbg.GetSelectedTarget().process
+ thread = process.GetSelectedThread()
+ stop_reason = thread.GetStopReason()
+ if stop_reason == lldb.eStopReasonExec:
+ # On OS X, ASan will relaunch the process to insert its library.
+ self.expect("thread list", "Process should be stopped due to exec.",
+ substrs = ['stopped', 'stop reason = exec'])
+ self.runCmd("continue")
# the stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
@@ -74,7 +73,6 @@
'Memory deallocated at', 'a.out`f2', 'main.c:%d' % self.line_free])
# do the same using SB API
- process = self.dbg.GetSelectedTarget().process
val = process.GetSelectedThread().GetSelectedFrame().EvaluateExpression("pointer")
addr = val.GetValueAsUnsigned()
threads = process.GetHistoryThreads(addr);
Index: functionalities/asan/TestReportData.py
===================================================================
--- functionalities/asan/TestReportData.py
+++ functionalities/asan/TestReportData.py
@@ -13,24 +13,20 @@
mydir = TestBase.compute_mydir(__file__)
- # The default compiler ("clang") may not support Address Sanitizer or it
- # may not have the debugging API which was recently added, so we're calling
- # self.useBuiltClang() to use clang from the llvm-build directory instead
-
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@skipIfRemote
+ @skipIfAddressSanitizerUnsupported
@dsym_test
def test_with_dsym (self):
- compiler = self.findBuiltClang ()
- self.buildDsym (None, compiler)
+ self.buildDsym (None, None, {"CFLAGS": "-fsanitize=address -g"})
self.asan_tests ()
@skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
@skipIfRemote
+ @skipIfAddressSanitizerUnsupported
@dwarf_test
def test_with_dwarf (self):
- compiler = self.findBuiltClang ()
- self.buildDwarf (None, compiler)
+ self.buildDwarf (None, None, {"CFLAGS": "-fsanitize=address -g"})
self.asan_tests ()
def setUp(self):
@@ -45,11 +41,23 @@
def asan_tests (self):
exe = os.path.join (os.getcwd(), "a.out")
self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ])
+
+ self.runCmd("breakpoint set -f main.c -l %d" % self.line_breakpoint)
+
self.runCmd("run")
- # ASan will relaunch the process to insert its library.
- self.expect("thread list", "Process should be stopped due to exec.",
- substrs = ['stopped', 'stop reason = exec'])
+ process = self.dbg.GetSelectedTarget().process
+ thread = process.GetSelectedThread()
+ stop_reason = thread.GetStopReason()
+ if stop_reason == lldb.eStopReasonExec:
+ # On OS X, ASan will relaunch the process to insert its library.
+ self.expect("thread list", "Process should be stopped due to exec.",
+ substrs = ['stopped', 'stop reason = exec'])
+ self.runCmd("continue")
+
+ # the stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped', 'stop reason = breakpoint'])
# no extended info when we have no ASan report
thread = self.dbg.GetSelectedTarget().process.GetSelectedThread()
Index: lldbtest.py
===================================================================
--- lldbtest.py
+++ lldbtest.py
@@ -669,6 +669,22 @@
func(*args, **kwargs)
return wrapper
+def skipIfAddressSanitizerUnsupported(func):
+ """
+ Decorate the item to skip tests that should skipped when the compiler we're using doesn't
+ support compiling with AddressSanitizer.
+ """
+ if isinstance(func, type) and issubclass(func, unittest2.TestCase):
+ raise Exception("@skipIfAddressSanitizerUnsupported can only be used to decorate a test method")
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ from unittest2 import case
+ self = args[0]
+ if not self.compilerSupportsAddressSanitizer():
+ self.skipTest("skipping because compiler doesn't support AddressSanitizer")
+ else:
+ func(*args, **kwargs)
+ return wrapper
class Base(unittest2.TestCase):
"""
@@ -864,6 +880,8 @@
# See HideStdout(self).
self.sys_stdout_hidden = False
+ self.cachedCompilerSupportsAddressSanitizer = None
+
# set environment variable names for finding shared libraries
if sys.platform.startswith("darwin"):
self.dylibPath = 'DYLD_LIBRARY_PATH'
@@ -1363,22 +1381,6 @@
if not module.buildDwarf(self, architecture, compiler, dictionary, clean):
raise Exception("Don't know how to build binary with dwarf")
- def findBuiltClang(self):
- """Tries to find and use Clang from the build directory as the compiler (instead of the system compiler)."""
- paths_to_try = [
- "llvm-build/Release+Asserts/x86_64/Release+Asserts/bin/clang",
- "llvm-build/Debug+Asserts/x86_64/Debug+Asserts/bin/clang",
- "llvm-build/Release/x86_64/Release/bin/clang",
- "llvm-build/Debug/x86_64/Debug/bin/clang",
- ]
- lldb_root_path = os.path.join(os.path.dirname(__file__), "..")
- for p in paths_to_try:
- path = os.path.join(lldb_root_path, p)
- if os.path.exists(path):
- return path
-
- return os.environ["CC"]
-
def getBuildFlags(self, use_cpp11=True, use_libcxx=False, use_libstdcxx=False, use_pthreads=True):
""" Returns a dictionary (which can be provided to build* functions above) which
contains OS-specific build flags.
@@ -1443,6 +1445,33 @@
else:
return ['libc++.1.dylib','libc++abi.dylib']
+ def compilerSupportsAddressSanitizer(self):
+ if self.cachedCompilerSupportsAddressSanitizer != None:
+ return self.cachedCompilerSupportsAddressSanitizer
+
+ self.cachedCompilerSupportsAddressSanitizer = False
+
+ # Save old working directory.
+ oldcwd = os.getcwd()
+
+ os.chdir(os.path.dirname(__file__) + "/functionalities/asan")
+
+ # This should always work
+ self.buildDefault();
+
+ # This will fail if the compiler doesn't have AddressSanitizer
+ try:
+ self.buildDefault (None, None, {"CFLAGS": "-fsanitize=address"})
+ self.cachedCompilerSupportsAddressSanitizer = True
+ except CalledProcessError:
+ pass
+
+ # Clean up
+ self.cleanup();
+ os.chdir(oldcwd)
+
+ return self.cachedCompilerSupportsAddressSanitizer
+
class TestBase(Base):
"""
This abstract base class is meant to be subclassed. It provides default
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits