How to enable address sanitizer for multiple C++ binaries - gcc

I am working on a product that is composed of multiple C++ executables and libraries that have various dependencies on one another. I am building them all with GCC and -fsanitize-address.
From what I understand, if I want to use address sanitizer with a library I have to build it as a shared object (which is the default option for GCC). Because of this, I thought the best option would be to build address sanitizer statically with -static-libasan for the executables and build it dinamically for the libraries. However, when I do that I get a link error when building one of the C++ executables:
==10823==Your application is linked against incompatible ASan runtimes
This makes me think that static and dynamic version of address sanitizer cannot be mixed with GCC, am I right? I was not able to find any information about this on the sanitizers GitHub page.

TLDR:
If you use GCC/Clang and both main executable and shlibs are sanitized, you don't need to do anything special - just stick with default -fsanitize=address.
If you use GCC and only shlibs are sanitized, again keep using -fsanitize=address and additionally export LD_PRELOAD=$(gcc -print-file-name=libasan.so) when running your application.
If you use Clang and only shlibs are sanitized, compile/link with -fsanitize-address -shared-libasan and additionally export LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so) when running the app.
Now some explanations. Originally Asan existed only in Clang which by default used (and still uses) -static-libasan. When it was ported to GCC, GCC developers decided that shared runtime is preferred (e.g. because it allows one to sanitize just one shared library and keep main executable unsanitized e.g. sanitize Python module without recompiling python.exe, see wiki for other examples). Both approaches are binary incompatible so you can't link part of your applications with static runtime and part with dynamic runtime.
Roughly
GCCs -fsanitize=address is equivalent to Clangs -fsanitize=address -shared-libasan (and -shared-libasan is second-class citizen in Clang so not as well supported)
Clangs -fsanitize=address is equivalent to GCCs -fsanitize=address -static-libasan (and again, -static-libasan is second-class citizen in GCC so has some issues)
As a side note, for other GCC/Clang Asan differences see this helpful wiki.

Related

Create a statically linked shared library

Is it possible to create a shared library which is itself statically linked, i.e. it does not depend on other shared libraries?
Let me be a little bit more concrete..
I want to create a shared library, say mylib.so, which makes use of some other special libraries (in my case its intel mkl and openMP). Since I have installed these libraries I can build mylib.so and include it in other programs without any problem.
However, if I want to use the library (or the executables including it) on another machine I first have to install all the intel stuff. Is there a way to avoid this? My first try was to add the option -static when building mylib.so but this doesn't seem to do anything..
I'm using icc..
Is it possible to create a shared library which is itself statically linked, i.e. it does not depend on other shared libraries?
Not on Linux, not when using GLIBC (your shared library will always depend on at least ld-linux*.so*).
I want to create a shared library, say mylib.so, which makes use of some other special libraries (in my case its intel mkl and openMP).
There is no problem1 statically linking Intel MKL and OpenMP libraries into mylib.so -- you just don't want to depend on these libraries dynamically (in other words, you are asking for an impossible thing which you don't actually need).
To do so, you need two things:
Link mylib.so with archive versions of the libraries you don't want to depend on dynamically, e.g. gcc -o mylib.so -shared mylib.c .../libmkl.a ...
The libraries which you want to statically link into mylib.so must have been built with position-independent code (i.e. with -fPIC flag).
Update:
What if the archived version isn't available?
Then you can't link it into your library.
Eg I'm using intel/oneapi/intelpython/latest/lib/libstdc++.so and there is no corresponding .a file..
This is a special case: you wouldn't want to link that version into your library even if it were available.
Instead, your program should use the version installed on the target system.
Having two separate versions of libstdc++ (e.g. one statically linked, and the other dynamically linked) into a single process will end very badly -- either with a crash, or with silent stack or heap corruption.
1 Note that linking in somebody else's library and distributing it may have licensing implications.

Compile single static library for Cortex M3, M4, M23 and M33

I'm currently working on a rather generic communication stack. It gets bytes in on one end, parses the packet and calls a callback.
I want to have this stack in a static library (i.e. libcommstack.a).
The library is aimed towards embedded ARM Cortex-M devices. At the moment we have specified that at least a Cortex-M3 should be used (but it should also work for an M4 or M33).
Right now I'm integrating it into another application to verify that linking it is possible. In the future the idea is that we will ship this .a file to customers so they can build their application around it, without having direct access to our sources (to encapsulate our IP).
We are using GCC ARM v7.2.1 to compile both the library and the application that is linked to it.
The application I'm trying to integrate it with is compiled for a Cortex M33 with -mfloat-abi=hard -mfpu-fpv6-sp-d16.
The code for the library does not use any floating points and is compiled using -march=archv7-m (both have the -mthumb flag).
Linking seemed to all go well, until I actually called a function from the lib. At that point the linker starts to complain:
application.elf uses VFP register arguments, libcommstack.a(somefile.c.obj) does not
failed to merge target specific data of file libcommstack.a(somefile.c.obj)
Since I'm not using floating points in the library and I don't know (upfront) if the target application does or does not have an FPU (or even uses floats), I'm not sure how to approach this.
I figured there would be two approaches:
Compile a single version of the lib, using an instruction set that all of the microcontrollers understand. I was hoping that this would be the case with ARMv7 (although I'm not yet 100% confident that the M23/M33 also support this).
Compile a lot of different libs for the different flavors based on the different architectures, FPU, etc.
As you can imagine, I would prefer to keep it simple and go for option 1, but I'm not sure how to "convince" the linker to link these two (or perhaps how to convince the compiler NOT to care about floating points for the lib).
Does anyone know if option 1 is feasible and how it can be achieved?
If it is not feasible, what would be the variables to keep in mind to determine the different build flavors?
Does anyone know if option 1 is feasible
Well, feasible, probably.
how it can be achieved?
Get all the processors you want to support and determine the instructions sets available on all these processors. Then compile for that instruction set.
But, please don't, that is a workaround.
If it is not feasible, what would be the variables to keep in mind to determine the different build flavors?
Gcc has something like "multilib profiles". See arm-none-eabi-gcc --print-multi-lib output. If you have newlib installed, you can go to /usr/arm-none-eabi/lib/thumb/ and see the directories there - newlib is compiled for each profile and installs separate library for it and different library is picked up depending on configuration. Compile for each of those profiles, and package your library by putting libraries in proper /usr/arm-none-eabi/lib/proper/directory/here and compiler will pick them up by itself (see gcc -v output for library search paths). For an example search newlib sources where it happens, can't find it. (Here's my example). With cmake as a backend as a example you could compile and install as follows:
arm-none-eabi-gcc --print-multi-lib |
while IFS=';' read -r dir opts; do
cmake -B builddir CMAKE_C_FLAGS="$opts" CMAKE_INSTALL_LIBDIR="$dir"
cmake --build builddir
cmake --install builddir --prefix "/usr/arm-none-eabi/"
done

how do I choose desired symbol when linking 2 different versions of the same library?

Background:
I am trying to provide a library wrapped within an interface, to be used in a third party application (MATLAB).
My problem is that both my library and the third party application rely on Boost libraries.
To make things even worse, not only they rely on two different versions of Boost, but my library is built against a patched version of Boost, and they are statically linked. Third party libraries are instead dynamically linked against Boost.
This is how I link (simplified output of make -n)
g++ -fPIC ${CPPFLAGS} -shared -lc -ldl ... -Wl,-h,mylib.so -o mylib.so \
${MYSTATICLIBS} \
-L${MATLABLIBSPATH} -lmx -lmex \
-L${MYBOOSTVERSIONPATH} -lboost_thread-gcc49-mt-1_52 ...
When I run the library fron within MATLAB then, the wrong boost functions are called from my internal functions (and everything crashes).
My naive intuition was that since i statically linked my Boost, all calls to them from within my library should point to my Boost, while calls from within libmx.so or libmex.so would point to their dynamically loaded dependencies. However this proves my naive intuition was very wrong.
I found different hints here on SO and around the web describing how linking order may break similar situations, however everything describes either all static or all dynamic linking of conflicting symbols.
Suggested solutions are
using -Bsymbolic -Bsymbolic-functions
upgrade my library to the same boost version
changing linking order ( first boost, then -lmx -lmex )
sell all my earthly possessions, buy a bar on the beach somewhere hot and try making a living out of it
other??
Can someone explain if and why these solution can work?
( my other problem is, I am not able to test with MATLAB myself, as I have no access to the machines on which it is installed. this is why I'm also asking "if" the proposed solutions would work)
First of all, welcome to the wonderful world of Linux symbol interposition ;)
I think what happens is your library exports all symbols from Boost library it has been linked with (can be verified with readelf --dyn-syms -W). At runtime, dynamic linker will note that and instead rebind symbols to a different version of Boost (because it happens to be loaded earlier and so overrides symbols used by your library).
What you want to do is to tell gcc that you do not want to export Boost symbols or you do not want them to be interposable at runtime. There are several solutions for this, the best being to compile and link with -fvisibility=hidden (note that Boost will also need to be linked with this flag). This will prevent any functions from being exported from your library unless you explicitly mark them with __attribute__((visibility("hidden"))) (you'll need to annotate library interface functions of course).
Another option is -Bsymbolic - this would not prevent spurious Boost exports from your library but would at least prevent dynamic linker from overriding them with random versions of Boost functions which happen to be loaded by other libraries.
Now to remaining questions.
upgrade my library to the same boost version
You could do that but this may break if 3-rd party upgrades their Boost at some point.
changing linking order ( first boost, then -lmx -lmex )
Does not make much sense... Have you tried?

G++ equivalents for VisualC++ /vmg /vms

I want to compile a plugin for an application as a dynamic library. Usually, plugins are compiled with VisualC++, but I'd like to use G++. The SDK Documentation explicitly states
The compiler options for Pointer-to-member representation must be set to "General-Purpose Always" and "Point to Single-Inheritance Classes" in C++ tab/C++ language (/vmg /vms). If not set the plugin will crash instantly!
And indeed, it does crash instantly as soon as I pass values from my plugin to the application. Are there any options that result in the same behaviour as /vmg /vms in VisualC++?
Platform: Windows 7 x64
Compiler: MingW32 G++ 4.6.2
Since pointer-to-member representation is an implementation detail, and GCC ABI is not designed to be compatible with that of MSVC, there is never going to be an equivalent.
You will not be able to mix binaries compiled with said compilers as long as the working depends on implementation-specific (unspecified) details like the pointer representations.

How to remove libgcc_s.so dependencies from uclibc

My understanding is that libgcc shouldn't be used in embedded systems and uclibc need to be used wherever possible. During buildroot build it is seen that it is generating libgcc as well. If I have to remove libgcc dependency completely (no static as well as shared) and only rely on uclibc, is it possible ? Is there any configuration which can effect this change ?
Thanks.
You are confusing glibc with libgcc. The latter contains helper functions for your architecture (e.g. integer division on ARM Application Profile) and not the standard C library functions. These functions may be part of the "run-time ABI" and might be required regardless of the C library you are using (even when compiling for bare-metal).
The uClibc is a drop-in replacement for glibc, not for libgcc.

Resources