Getting ASAN to work with Ignition Gazebo


I’m adding this as a reminder for myself.

To get ASAN to work with Ignition Gazebo we first need to modify CMakeLists.txt to build with ASAN.

For every module (e.g. ign-gazebo, ign-rendering, ign-gui, etc) you wish to have full ASAN analysis, write this at the top of each CMakeLists.txt:

set( CMAKE_C_FLAGS_DEBUG
	"${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address" )
set( CMAKE_CXX_FLAGS_DEBUG
	"${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address" )
set( CMAKE_LINKER_FLAGS_DEBUG
	"${CMAKE_LINKER_FLAGS_DEBUG} -fsanitize=address" )

Running w/ Ruby

If you try to execute ign -v4 shapes.sdf you’ll encounter the following error:

==12043==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.

This is because ign is actually just a Ruby script and Ruby is not loading asan first (unless you’ve compiled ruby yourself with ASAN).

But preloading only libasan will result in check errors:

==21465==AddressSanitizer CHECK failed: ../../../../src/libsanitizer/asan/asan_interceptors.cc:313 "((__interception::real___cxa_throw)) != (0)" (0x0, 0x0)

To fix it we need we need to LD_PRELOAD libasan and libstdc++ which is where ___cxa_throw is defined. Just execute:

LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.5:/usr/lib/x86_64-linux-gnu/libstdc++.so.6 ign gazebo shapes.sdf

I’m linking against libasan5 and libstdc++6 because that’s what’s GCC 8 uses (the officially supported compiler by default as per documentation). If you’re unsure which lib versions are needed you can use ldd command to see what the libraries are being linked to (e.g. ldd libignition-gazebo5.so)

And that’s it!

Happy bug hunting!

Bonus: Lib error diagnosis

I didn’t magically know that libstdc++ was missing. I used LD_DEBUG=libs to debug the problem:

LD_DEBUG=libs LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.5 ign gazebo shapes.sdf 2> stderr.log

After inspecting stderr.log, I noticed the Linux loader was having errors when loading libasan because ___cxa_throw symbol could not be found. That’s how I knew libstdc++ had to be preloaded as well. And after inclusion, it started working!