Bug 100120 - Mesa fails to build with gcc address sanitizer (-fsanitize=address -lasan)
Summary: Mesa fails to build with gcc address sanitizer (-fsanitize=address -lasan)
Status: RESOLVED MOVED
Alias: None
Product: Mesa
Classification: Unclassified
Component: Mesa core (show other bugs)
Version: git
Hardware: All All
: medium major
Assignee: mesa-dev
QA Contact: mesa-dev
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-03-08 18:53 UTC by Vedran Miletić
Modified: 2019-09-18 20:25 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments

Description Vedran Miletić 2017-03-08 18:53:32 UTC
$ git clone ...
$ ./autogen.sh CFLAGS="-fsanitize=address" CXXFLAGS="-fsanitize=address" LIBS="-lasan"
$ make -j
(...)
make[4]: Entering directory '/home/vedranm/workspace/mesa/src/glx'
  CCLD     libGL.la
./.libs/libglx.a(dri_common.o): In function `driOpenDriver':
dri_common.c:(.text+0x528): undefined reference to `dlerror'
./.libs/libglx.a(dri_common.o): In function `driGetDriverExtensions':
dri_common.c:(.text+0x6b8): undefined reference to `dlsym'
dri_common.c:(.text+0x6dc): undefined reference to `dlerror'
dri_common.c:(.text+0x71e): undefined reference to `dlsym'
dri_common.c:(.text+0x72e): undefined reference to `dlerror'
./.libs/libglx.a(dri_glx.o): In function `glXGetDriverConfig':
dri_glx.c:(.text+0x76f): undefined reference to `dlsym'
./.libs/libglx.a(dri_glx.o): In function `driCreateScreen':
dri_glx.c:(.text+0x3977): undefined reference to `dlsym'
dri_glx.c:(.text+0x398d): undefined reference to `dlerror'
collect2: error: ld returned 1 exit status
Makefile:808: recipe for target 'libGL.la' failed
make[4]: *** [libGL.la] Error 1
make[4]: Leaving directory '/home/vedranm/workspace/mesa/src/glx'
Makefile:902: recipe for target 'all-recursive' failed
make[3]: *** [all-recursive] Error 1
make[3]: Leaving directory '/home/vedranm/workspace/mesa/src/glx'
Makefile:856: recipe for target 'all-recursive' failed
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory '/home/vedranm/workspace/mesa/src'
Makefile:647: recipe for target 'all' failed
make[1]: *** [all] Error 2
make[1]: Leaving directory '/home/vedranm/workspace/mesa/src'
Makefile:644: recipe for target 'all-recursive' failed
make: *** [all-recursive] Error 1
Comment 1 Jeff Smith 2017-03-08 22:33:14 UTC
While you shouldn't have needed LIBS="..." at all, there is a deficiency in libtool that was fixed in 2015: http://git.savannah.gnu.org/cgit/libtool.git/commit/?id=a5c6466528c060cc4660ad0319c00740db0e42ba, but no release has been made since.

That said, with LIBS="-lasan -dl" it does build for me.
Comment 2 Hi-Angel 2017-03-09 05:14:14 UTC
FWIW, build with 

	CFLAGS="-fsanitize=address" CXXFLAGS="-fsanitize=address" LIBS="-ldl -lasan" ./autogen.sh CC="gcc -m32" CXX="g++ -m32" --build=x86_64-pc-linux-gnu --host=i686-pc-linux-gnu --enable-nine --with-dri-drivers="" --disable-xvmc --disable-va --disable-vdpau --with-gallium-drivers="r600,swrast" --enable-dri3 --enable-profile --with-clang-libdir=/usr/lib32

ends up for me with a bunch of undefined references about nir_* object files for building d3dadapter9.
Comment 3 Vedran Miletić 2017-03-09 13:04:35 UTC
(In reply to Jeff Smith from comment #1)
> While you shouldn't have needed LIBS="..." at all, there is a deficiency in
> libtool that was fixed in 2015:
> http://git.savannah.gnu.org/cgit/libtool.git/commit/
> ?id=a5c6466528c060cc4660ad0319c00740db0e42ba, but no release has been made
> since.
> 
> That said, with LIBS="-lasan -dl" it does build for me.

Interesting. Shouldn't -ldl already be a part of the linker commandline?

$ ldd /usr/local/lib64/libGL.so | grep dl
	libdl.so.2 => /lib64/libdl.so.2 (0x00007f3a9fbc8000)
Comment 4 Emil Velikov 2017-03-09 14:00:42 UTC
-dl is (module bugs of course) already passed then libGL/libGLX_mesa is build.

As pointed out we don't have a libtool which honours fsanitize, so I'd suggest adding it to the CC/CXX variables like below.

./autogen.sh CC="gcc -fsanitize=address" CXX="g++ -fsanitize=address"

Note: I'm wondering if the explicit -lasan isn't agcc/clang bug. Can we get a reference reading why we need it, considering the explicit -f.... toggle we pass to gcc/clang.
Comment 5 Jeff Smith 2017-03-09 14:58:50 UTC
(In reply to Emil Velikov from comment #4)
> Note: I'm wondering if the explicit -lasan isn't agcc/clang bug. Can we get
> a reference reading why we need it, considering the explicit -f.... toggle
> we pass to gcc/clang.

I don't have a reference, but from observation, -fsanitize=address does two things:
 - in the compile stage, it instruments the code, which adds references to symbols in libasan.
 - in the link stage, it adds libasan (and libdl and possibly others) to the set of libraries to link.
Since libtool is not passing -fsanitize=address on to the compiler at link time, the -lasan use is just one work-around.

Also, -fsanitize=address messes with configure's detection of libdl.  Again, if -fsanitize=address was working properly at link-time, it probably would not matter.
Comment 6 Vedran Miletić 2017-03-09 15:09:21 UTC
(In reply to Emil Velikov from comment #4)
> Note: I'm wondering if the explicit -lasan isn't agcc/clang bug. Can we get
> a reference reading why we need it, considering the explicit -f.... toggle
> we pass to gcc/clang.

It's not required, it's added automatically. I started with the wrong assumption here.

> -dl is (module bugs of course) already passed then libGL/libGLX_mesa is
> build.
> 
> As pointed out we don't have a libtool which honours fsanitize, so I'd
> suggest adding it to the CC/CXX variables like below.
> 
> ./autogen.sh CC="gcc -fsanitize=address" CXX="g++ -fsanitize=address"
> 

This fails the same way as the ./autogen.sh CFLAGS="-fsanitize=address" CXXFLAGS="-fsanitize=address"
Comment 7 Vedran Miletić 2017-03-09 15:31:52 UTC
(In reply to Vedran Miletić from comment #6)
> (In reply to Emil Velikov from comment #4)
> > Note: I'm wondering if the explicit -lasan isn't agcc/clang bug. Can we get
> > a reference reading why we need it, considering the explicit -f.... toggle
> > we pass to gcc/clang.
> 
> It's not required, it's added automatically. I started with the wrong
> assumption here.
> 

Correction: it is not required when building something that is not Mesa (e.g. a simple one file C/C++ program). When building Mesa specifying -lasan is required.
Comment 8 Vedran Miletić 2017-03-09 15:33:23 UTC
That is, the compile error result of these two configurations is equivalent:
$ ./autogen.sh CFLAGS="-fsanitize=address" CXXFLAGS="-fsanitize=address" LIBS="-lasan"
$ ./autogen.sh CC="gcc -fsanitize=address" CXX="g++ -fsanitize=address"
Comment 9 Jeff Smith 2017-03-10 17:08:32 UTC
A few more things I found...

Either with or without a fixed libtool, libdl detection is still affected when -fsanitize=address is set.  A more precise way to handle this than adding -ldl to LIBS, is to set DLOPEN_LIBS="-ldl"

Regarding the problems in d3dadapter9, it seems that there are other things going on:
 - Linking with "-Wl,--no-undefined" seems to interfere with "-fsanitize=address", making LIBS="-lasan" necessary in this case.
 - Building with "-fsanitize=address" seems to affect the building of libgallium.a such that when combined with using "-Wl,--no-undefined", "$(top_builddir)/src/compiler/nir/libnir.la" must be added to d3dadapter9_la_LIBADD in the d3dadapter9 Makefile.
Comment 10 Emil Velikov 2017-03-13 17:43:10 UTC
Right, if we set CFLAGS/CC or friends at autogen.sh/configure stage interacts strange with the test in configure - now sure who's to "blame" there.

On the other hand, overriding the CC/CXX at make times proves of little worth since, the compiler (seems deliberately) leaves out the -lasan link (be that static or shared).

Overriding LDFLAGS="-Wl,-fsanitize=address" makes things even worse since a) the static objects (nouveau compiler, gen_matypes) error at link time, and as we side stepping this, a ton of nir related unresolved symbols even on targets which do not use NIR. Plus we still get the unresolved asan symbols.


For example:
$ ../autogen.sh --without-dri-drivers --without-vulkan-drivers --disable-egl --disable-gbm --disable-gles1 --disable-gles2 --with-gallium-drivers=nouveau,swrast --disable-vdpau --disable-xvmc --disable-va --enable-nine

$ make V=1 CC="gcc -fsanitize=address" CXX="g++ -fsanitize=address" LDFLAGS="-Wl,-fsanitize=address" LIBS="-lasan"


.../src/gallium/auxiliary/.libs/libgallium.a(tgsi_to_nir.o): In function `nir_build_imm':
.../src/compiler/nir/nir_builder.h:196: undefined reference to `nir_load_const_instr_create'
.../src/gallium/auxiliary/.libs/libgallium.a(tgsi_to_nir.o): In function `nir_builder_instr_insert':
.../src/compiler/nir/nir_builder.h:65: undefined reference to `nir_instr_insert'
.../src/gallium/auxiliary/.libs/libgallium.a(tgsi_to_nir.o): In function `nir_imov_alu':

and so on.

Hence I'm thinking about:
 - why/how we don't get the NIR related issues w/o the sanitizer ? Seems like gcc/clang is having some strange change of behaviour.
 - we might want to track and build the ttn (tgsi to nir) parts only as needed, but it will be very fragile
 - gcc/clang should really have a way to pull the asan symbols into the final object without the special LIBS="-lasan"
Comment 11 GitLab Migration User 2019-09-18 20:25:50 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/mesa/mesa/issues/1008.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.