https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68016
--- Comment #4 from Maxim Ostapenko <chefmax at gcc dot gnu.org> --- Actualy, LLVM is not better here (perhaps even worse). Consider the following testcase (it's the same Jakub provided in PR63888): max@max:/tmp$ cat libfoo.c long f = 4; long foo (long *p) { return *p; } max@max:/tmp$ cat libbar.c long h = 12; long i = 13; max@max:/tmp$ cat main.c extern void abort (void); extern long f; extern long h; extern long i; long foo (long *); int main () { if (foo (&f) != 4 || foo (&h) != 12 || foo (&i) != 13) abort (); return 0; } max@max:/tmp$ clang libfoo.c -shared -fpic -o libfoo.so -g max@max:/tmp$ clang libbar.c -shared -fpic -o libbar.so -g max@max:/tmp$ clang main.c -c -o main.o -g max@max:/tmp$ clang main.o ./libfoo.so ./libbar.so -o main -fsanitize=address max@max:/tmp$ ./main max@max:/tmp$ echo $? 0 max@max:/tmp$ clang libfoo.c -shared -fpic -o libfoo.so -g -fsanitize=address max@max:/tmp$ ./main ./main: Symbol `f' has different size in shared object, consider re-linking ================================================================= ==19089==ERROR: AddressSanitizer: global-buffer-overflow on address 0x00000070fb10 at pc 0x7f0e0b65c931 bp 0x7ffc67828000 sp 0x7ffc67827ff8 READ of size 8 at 0x00000070fb10 thread T0 #0 0x7f0e0b65c930 in foo /tmp/libfoo.c:2:29 #1 0x4e166f in main /tmp/main.c:9:42 #2 0x7f0e0a570ec4 in __libc_start_main /build/buildd/eglibc-2.19/csu/libc-start.c:287 #3 0x418fd5 in _start (/tmp/main+0x418fd5) 0x00000070fb10 is located 0 bytes to the right of global variable 'f' defined in 'libfoo.c:1:6' (0x70fb08) of size 8 SUMMARY: AddressSanitizer: global-buffer-overflow /tmp/libfoo.c:2:29 in foo Shadow bytes around the buggy address: 0x0000800d9f10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0000800d9f20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0000800d9f30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0000800d9f40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0000800d9f50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0000800d9f60: 00 00[f9]f9 f9 f9 f9 f9 f9 00 00 00 00 00 00 00 0x0000800d9f70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0000800d9f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0000800d9f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0000800d9fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0000800d9fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==19089==ABORTING This happens because in LLVM case ASan changes symbols size ('f' in our case) and just breaks ABI for the library. Relinking binary each time we replace non-sanitized library with sanitized one is undesirable for large package oriented systems (e.g. distributives), so we need a general solution for the problem.