Could someone help me understand, why after generating the object file with using ASan flag (compiler flag), when linking the object file still needs the same flag? (linker flag)
For example
clang -fsanitize=address -c test.c
clang -fsanitize=address test.o -o test.exe
CodePudding user response:
When you compile your program with Address Sanitizer, it instruments every memory access and prefixes it with a check and includes the function calls to report memory access errors.
For e.g.
Sample program which leaks memory and try to access array beyond its size:
#include <stdio.h>
#include <stdlib.h>
void fun (void) {
void *p = malloc(1);
char a[] = "abc";
printf ("%c\n", a[4]);
}
int main (void) {
fun();
return 0;
}
Compiling:
# gcc -fsanitize=address -g -c test.c
# ls
test.c test.o
Linking without -fsanitize=address
:
# gcc -g test.o -o test.exe
test.o: In function `fun':
/root/mywork/asan/sample7/test.c:4: undefined reference to `__asan_option_detect_stack_use_after_return'
/root/mywork/asan/sample7/test.c:4: undefined reference to `__asan_stack_malloc_1'
/root/mywork/asan/sample7/test.c:6: undefined reference to `__asan_report_store4'
/root/mywork/asan/sample7/test.c:8: undefined reference to `__asan_report_load1'
test.o: In function `_GLOBAL__sub_D_00099_0_fun':
/root/mywork/asan/sample7/test.c:14: undefined reference to `__asan_unregister_globals'
test.o: In function `_GLOBAL__sub_I_00099_1_fun':
/root/mywork/asan/sample7/test.c:14: undefined reference to `__asan_init'
/root/mywork/asan/sample7/test.c:14: undefined reference to `__asan_version_mismatch_check_v8'
/root/mywork/asan/sample7/test.c:14: undefined reference to `__asan_register_globals'
collect2: error: ld returned 1 exit status
The code of test.o
is instrumented by Address Sanitizer. The Address Sanitizer runtime library replaces malloc()
call with its own malloc()
function call (which allocate requested amount of memory with redzone around it) and provides error reporting function like __asan_report_load1()
, __asan_report_store4()
etc. In order to resolve these functions, the -fsanitize=address
flag is required at the time of linking to tell linker to check the ASan runtime library to resolve the references.
Linking with -fsanitize=address
:
# gcc -fsanitize=address -g test.o -o test.exe
# ls
test.c test.exe test.o
If you don't want to use -fsanitize=address
flag with linker, you can provide the Address Sanitizer library to the linker which it can use to resolve the references:
# ls
test.c test.o
# gcc -lasan -g test.o -o test.exe
# ls
test.c test.exe test.o