scons: Allow building with Address Sanitizer.

libasan is never linked to shared objects (which doesn't go well with
-z,defs).  It must either be linked to the main executable, or (more
practically for OpenGL drivers) be pre-loaded via LD_PRELOAD.

Otherwise works.

I didn't find anything with llvmpipe.  I suspect the fact that the
JIT compiled code isn't instrumented means there are lots of errors it
can't catch.

But for non-JIT drivers, the Address/Leak Sanitizers seem like a faster
alternative to Valgrind.

Usage (Ubuntu 15.10):

   scons asan=1 libgl-xlib
   export LD_LIBRARY_PATH=$PWD/build/linux-x86_64-debug/gallium/targets/libgl-xlib
   LD_PRELOAD=libasan.so.2 any-opengl-application

Acked-by: Roland Scheidegger <sroland@vmware.com>
This commit is contained in:
Jose Fonseca
2016-04-09 20:26:42 +01:00
parent d1c89f6005
commit fa46848e51
4 changed files with 26 additions and 7 deletions

View File

@@ -97,6 +97,7 @@ def AddOptions(opts):
opts.Add(BoolOption('embedded', 'embedded build', 'no')) opts.Add(BoolOption('embedded', 'embedded build', 'no'))
opts.Add(BoolOption('analyze', opts.Add(BoolOption('analyze',
'enable static code analysis where available', 'no')) 'enable static code analysis where available', 'no'))
opts.Add(BoolOption('asan', 'enable Address Sanitizer', 'no'))
opts.Add('toolchain', 'compiler toolchain', default_toolchain) opts.Add('toolchain', 'compiler toolchain', default_toolchain)
opts.Add(BoolOption('gles', 'EXPERIMENTAL: enable OpenGL ES support', opts.Add(BoolOption('gles', 'EXPERIMENTAL: enable OpenGL ES support',
'no')) 'no'))

View File

@@ -410,7 +410,7 @@ def generate(env):
# Work around aliasing bugs - developers should comment this out # Work around aliasing bugs - developers should comment this out
ccflags += ['-fno-strict-aliasing'] ccflags += ['-fno-strict-aliasing']
ccflags += ['-g'] ccflags += ['-g']
if env['build'] in ('checked', 'profile'): if env['build'] in ('checked', 'profile') or env['asan']:
# See http://code.google.com/p/jrfonseca/wiki/Gprof2Dot#Which_options_should_I_pass_to_gcc_when_compiling_for_profiling? # See http://code.google.com/p/jrfonseca/wiki/Gprof2Dot#Which_options_should_I_pass_to_gcc_when_compiling_for_profiling?
ccflags += [ ccflags += [
'-fno-omit-frame-pointer', '-fno-omit-frame-pointer',
@@ -540,6 +540,16 @@ def generate(env):
# scan-build will produce more comprehensive output # scan-build will produce more comprehensive output
env.Append(CCFLAGS = ['--analyze']) env.Append(CCFLAGS = ['--analyze'])
# https://github.com/google/sanitizers/wiki/AddressSanitizer
if env['asan']:
if gcc_compat:
env.Append(CCFLAGS = [
'-fsanitize=address',
])
env.Append(LINKFLAGS = [
'-fsanitize=address',
])
# Assembler options # Assembler options
if gcc_compat: if gcc_compat:
if env['machine'] == 'x86': if env['machine'] == 'x86':

View File

@@ -48,11 +48,15 @@ if env['llvm']:
env.Prepend(LIBS = [llvmpipe]) env.Prepend(LIBS = [llvmpipe])
if env['platform'] != 'darwin': if env['platform'] != 'darwin':
# Disallow undefined symbols, except with Address Sanitizer, since libasan
# is not linked on shared libs, as it should be LD_PRELOAD'ed instead
if not env['asan']:
env.Append(SHLINKFLAGS = [
'-Wl,-z,defs',
])
env.Append(SHLINKFLAGS = [ env.Append(SHLINKFLAGS = [
# Disallow undefined symbols # Restrict exported symbols
'-Wl,-z,defs', '-Wl,--version-script=%s' % File("libgl-xlib.sym").srcnode().path,
# Restrict exported symbols
'-Wl,--version-script=%s' % File("libgl-xlib.sym").srcnode().path,
]) ])
# libGL.so.1.5 # libGL.so.1.5

View File

@@ -34,9 +34,13 @@ sources = [
'xm_tri.c', 'xm_tri.c',
] ]
# Disallow undefined symbols
if env['platform'] != 'darwin': if env['platform'] != 'darwin':
env.Append(SHLINKFLAGS = ['-Wl,-z,defs']) # Disallow undefined symbols, except with Address Sanitizer, since libasan
# is not linked on shared libs, as it should be LD_PRELOAD'ed instead
if not env['asan']:
env.Append(SHLINKFLAGS = [
'-Wl,-z,defs',
])
# libGL.so.1.6 # libGL.so.1.6
libgl_1_6 = env.SharedLibrary( libgl_1_6 = env.SharedLibrary(