Commit 2b59ba68 authored by Ben Cooksley's avatar Ben Cooksley

Add support for injecting ASAN.

Note that this is only useful on Linux, as FreeBSD seems to do ASAN differently (statically) so that doesn't hit the breakage we are working around here
parent ab832f5d
......@@ -58,6 +58,13 @@ Devel:
# Defaults to True
launch-dbus-session: True
# force-inject-asan: Determines whether we'll attempt to forcibly inject the ASAN library into all processes launched as part of the testing process.
# Due to the way in which ASAN works, any binaries built without being linked to ASAN which use plugins/libraries built using ASAN will bail out immediately
# To workaround this we use LD_PRELOAD and other similar variables to ensure ASAN gets loaded first into processes.
# This is pretty crap, but until the ASAN developers sort their stuff out it's our only option when using external tools (like the qmlrunner from Qt)
# Defaults to False
force-inject-asan: False
# ctest-arguments: Additional arguments which should be passed to CTest when invoking it.
# This can be used to customise the behaviour of CTest in executing tests for a project.
ctest-arguments: ''
......
......@@ -63,6 +63,7 @@ class Loader(object):
'per-test-timeout': 600,
'setup-x-environment': True,
'launch-dbus-session': True,
'force-inject-asan': False,
'ctest-arguments': '',
'run-cppcheck': True,
'cppcheck-arguments': '',
......
......@@ -31,6 +31,21 @@ def firstPresentFile( searchRoot, filesToFind ):
# Return the first hit we found, returning an empty string if none were found
return next( iter(availableFiles), '' )
# Determines where the first of a given set of files is in a given set of directories
def firstPresentFileInPaths( searchRoots, filesToFind ):
# Start searching...
validPaths = []
for rootPath in searchRoots:
# Look in this directory
foundFile = firstPresentFile( rootPath, filesToFind )
# If we found something, we're finished
if foundFile != '':
# Make a usable path and return it
return os.path.join( rootPath, foundFile )
# If we failed to find anything, return blank
return ''
# Converts a path to a relative one, to allow for it to be passed to os.path.join
# This is primarily relevant on Windows, where full paths have the drive letter, and thus can be simply joined together as you can on Unix systems
def makePathRelative(path):
......
......@@ -56,6 +56,25 @@ if sys.platform != 'win32' and sys.platform != 'darwin':
# And lock down it's permissions
os.chmod( buildEnvironment['XDG_RUNTIME_DIR'], stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR )
# Are we being asked to ensure ASAN is forcibly injected?
# On FreeBSD their ASAN is different it behaves properly
# So we only need to force inject on Linux
if sys.platform =='linux' and buildSpecification['force-inject-asan']:
# Where could the ASAN library live?
knownAsanLocations = [
'/lib64/',
'/usr/lib64/',
'/usr/lib/x86_64-linux-gnu/'
]
# And what names could it be hiding under?
knownAsanNames = [
'libasan.so.4',
'libasan.so.3',
'libasan.so.2'
]
# Knowing all of that, let's find ASAN's library and set it up to be injected
buildEnvironment['LD_PRELOAD'] = CommonUtils.firstPresentFileInPaths( knownAsanLocations, knownAsanNames )
# Spawn a X windowing system if needed
# We'll also launch a Window Manager at the same time as some tests often need or unknowingly rely on one being present
# As X doesn't belong on Windows or OSX we don't run it there
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment