Be aware of AddressSanitizer’s shadow memory usage

The following is excerpted from AddressSanitizerAlgorithm:

AddressSanitizer maps 8 bytes of the application memory into 1 byte of the shadow memory.

It means if you use ASAN_POISON_MEMORY_REGION/ASAN_UNPOISON_MEMORY_REGION (please refer AddressSanitizerManualPoisoning), you should take shadow memory usage into account if application memory is huge. E.g., my application occupies ~216 GiB, the shadow memory will occupy about 216 / 8 = 27 GiB.

Fix “cannot find libasan_preinit.o” issue in Void Linux

In my Void Linux, using clang with -fsanitize=address option is OK:

$ clang -std=c11 -fsanitize=address test.c
$

Whilst gcc reports following error:

$ gcc -std=c11 -fsanitize=address test.c
/usr/bin/ld: cannot find libasan_preinit.o: No such file or directory
/usr/bin/ld: cannot find -lasan
collect2: error: ld returned 1 exit status

The solution is to install libsanitizer-devel:

$ sudo xbps-install -Su libsanitizer-devel
$ gcc -std=c11 -fsanitize=address test.c
$

Check the linked libraries of executalbe file:

$ ldd a.out
    linux-vdso.so.1 (0x00007fff1a58b000)
    libasan.so.5 => /usr/lib/libasan.so.5 (0x00007fc1f0f02000)
    libc.so.6 => /usr/lib/libc.so.6 (0x00007fc1f0d3f000)
    libdl.so.2 => /usr/lib/../lib/libdl.so.2 (0x00007fc1f0d3a000)
    librt.so.1 => /usr/lib/../lib/librt.so.1 (0x00007fc1f0d2f000)
    libpthread.so.0 => /usr/lib/../lib/libpthread.so.0 (0x00007fc1f0d0e000)
    libstdc++.so.6 => /usr/lib/../lib/libstdc++.so.6 (0x00007fc1f0a99000)
    libm.so.6 => /usr/lib/../lib/libm.so.6 (0x00007fc1f0952000)
    libgcc_s.so.1 => /usr/lib/../lib/libgcc_s.so.1 (0x00007fc1f0938000)
    /lib/ld-linux-x86-64.so.2 (0x00007fc1f193d000)

Reference:
How to use gcc with sanitizers in Void Linux?.

Use alignof in gcc

alignof is defined in stdalign.h for gcc:

$ cat /usr/lib/gcc/x86_64-unknown-linux-gnu/9.1.0/include/stdalign.h
......
#ifndef _STDALIGN_H
#define _STDALIGN_H

#ifndef __cplusplus

#define alignas _Alignas
#define alignof _Alignof

#define __alignas_is_defined 1
#define __alignof_is_defined 1

#endif

#endif  /* stdalign.h */

To use alignofstdalign.h must be included, otherwise following errors will be reported:

......
warning: implicit declaration of function 'alignof' [-Wimplicit-function-declaration]
    3 |  return alignof(int);
      |         ^~~~~~~
 error: expected expression before

It is no need to include any header files to use _Alignof and __alignof__.

Empty struct in C

Empty struct in C is undefined behaviour (refer C17 spec, section 6.7.2.1):

If the struct-declaration-list does not contain any named members, either directly or via an anonymous structure or anonymous union, the behavior is undefined.

On my Linux, I use both gcc (v9.1.0) and clang (v8.0.0) to compile following code:

$ cat test.c
#include <stdio.h>

typedef struct A {} A;

int main()
{
    printf("%zu\n", sizeof(A));
}

No warnings, and both ouput:
0

Reference:
C empty struct — what does this mean/do?.

Fix “identifier “__builtin_is_constant_evaluated” is undefined” error on Arch Linux

The Arch Linux has shipped gcc 9, but the newest CUDA V10.1.168 still only supports gcc 8. So I met following error after upgrading Arch Linux:

......
/usr/include/c++/9.1.0/bits/stl_function.h(437): error: identifier "__builtin_is_constant_evaluated" is undefined
......

Unfortunately, gcc-8 package is not ready now. So I fell back to gcc-7:

SET(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -ccbin=gcc-7"}

Although the CUDA release note claims it already supports clang 8, I indeed bumped into some compile errors when using clang 8. So using gcc-7 is a feasible work-around for me.