AddressSanitizer and the GC

Johan Engelen via Digitalmars-d digitalmars-d at puremagic.com
Fri Jul 21 12:06:21 PDT 2017


Hi all,
   I've added AddressSanitizer [1] support to LDC, and it is able 
to nicely catch bugs like this one:
```
void foo(int* arr) {
     arr[10] = 1;
}

void main() {
     int[10] a;
     foo(&a[0]);
}
```

It works for malloc'ed memory, but not yet for GC'd memory. Our 
GC pool memory is malloc'ed, so it is "safe" to access from 
ASan's current point of view. To make it work with our GC, we 
have to mark all GC pool memory (malloc'ed) as poisoned, such 
that access to that memory will trigger an ASan error. Then when 
a user asks memory from the pool (e.g. `new int`), we should 
allocate a little more GC'd memory than what the user requests 
(red zone), and then mark only the user size as unpoisoned. By 
allocating a little more, we make sure that user allocated memory 
blocks are separated by at least an amount of red zone that helps 
detect read/write memory overflows.
Pieces of the solution:
a. Call __asan_poison_memory_region on all memory internally 
allocated by the GC
b. ptr = GC.alloc(user_request_size+redzone)
c. Call __asan_unpoison_memory_region on ptr[0..user_request_size]

I've already been toying with several options but would like your 
opinion: what is the best way for me to add this to the GC?

1. What are the best places to modify the conservative GC with 
the above pieces?

2. Should I create a new GC type "asan"? We now have 
"conservative" (default) and "manual". Adding an option to the 
default GC is made hard because of linking problems (need to link 
with asan library, but I can define @weak function stubs), but I 
am worried about slow down in non-asan mode (which is the 
99.9999999% use case).

Thanks,
   Johan


[1] https://github.com/google/sanitizers/wiki/AddressSanitizer


More information about the Digitalmars-d mailing list