Blacklists (Clang Sanitizers)
A blacklist file contains the names of source files and/or functions whose issues (races, leaks, …) should not be reported. Such blacklist files can be placed anywhere on the system. For the sake of simplicity, this article will focus on working with the ThreadSanitizer. However, the same concepts and rules apply for all Clang sanitizers when used in combination with Mono.
The simplest approach (an empty blacklist) would look like this:
$ touch /home/some/path/blacklist $ cd /home/root/of/mono $ ./autogen.sh --prefix=/usr/local CC=clang CFLAGS="-fsanitize=thread -fsanitize-blacklist=/home/some/path/blacklist" LDFLAGS=-fsanitize=thread CXX=clang $ make ...
Content of Blacklist Files
The easiest way of blocking everything is to simply put
src:* into a blacklist file:
$ cat /home/some/path/blacklist src:*
However, a finer granularity (toggling the reporting of functions instead of the reporting of whole source files) is often desirable. While
fun: can be used to achieve that, only top level functions (where the races occur) can be blacklisted. For example, the following race could only be blacklisted if the C standard library was built from source, as the top level function is
calloc (). Blacklisting
monoeg_g_calloc () or
monoeg_malloc0 () would not blacklist this specific race.
#0 calloc <null> (mono-sgen+0x43a477) #1 monoeg_g_calloc /home/root/of/mono/mono/eglib/src/gmem.c:114:9 (mono-sgen+0xf2081b) #2 monoeg_malloc0 /home/root/of/mono/mono/eglib/src/gmem.c:121:9 (mono-sgen+0xf208bf) #3 inflate_generic_signature_checked /home/root/of/mono/mono/mono/metadata/loader.c:537:31 (mono-sgen+0xb9 ...
fun: instructions can be used in the same blacklist file and the usage of wildcards (
*) is supported. Please have a look at the official documentation for more details.
Changes of blacklist files are detected automatically. The first
make command after changing a blacklist file recompiles all source files that use that specific blacklist file for compilation. While this is very useful, it wastes a lot of CPU and time to recompile the whole project when only debugging / toggling a few functions of a specific module. One way of working with blacklists more efficiently is to partition the blocked functions and source files into dedicated files. To link those dedicated blacklists to Clang, all corresponding
Makefile files have to be altered.
For example, if
mono/sgen/ was to be debugged, a setup could look like this:
$ cd /home/root/of/mono $ ./autogen.sh --prefix=/usr/local CC=clang CFLAGS="-fsanitize=thread -fsanitize-blacklist=/home/some/path/blacklist" LDFLAGS=-fsanitize=thread CXX=clang $ cat /home/some/path/blacklist-sgen fun:sweep_block fun:sweep_block_for_size $ # alter mono/sgen/Makefile $ cat mono/sgen/Makefile ... CCASFLAGS = -fsanitize=thread -fsanitize-blacklist=/home/some/path/blacklist-sgen ... ... CFLAGS = -fsanitize=thread -fsanitize-blacklist=/home/some/path/blacklist-sgen ... ... CFLAGS_FOR_BUILD = -fsanitize=thread -fsanitize-blacklist=/home/some/path/blacklist-sgen ... ... $ make