Home | History | Annotate | Download | only in TestCases
      1 // RUN: %clangxx_asan -fexceptions -O %s -o %t && %run %t
      2 //
      3 // Test __sanitizer_annotate_contiguous_container.
      4 
      5 #include <stdlib.h>
      6 #include <stdio.h>
      7 #include <string.h>
      8 #include <assert.h>
      9 #include <sanitizer/asan_interface.h>
     10 
     11 void TestContainer(size_t capacity) {
     12   char *beg = new char[capacity];
     13   char *end = beg + capacity;
     14   char *mid = beg + capacity;
     15   char *old_mid = 0;
     16 
     17   for (int i = 0; i < 10000; i++) {
     18     size_t size = rand() % (capacity + 1);
     19     assert(size <= capacity);
     20     old_mid = mid;
     21     mid = beg + size;
     22     __sanitizer_annotate_contiguous_container(beg, end, old_mid, mid);
     23 
     24     for (size_t idx = 0; idx < size; idx++)
     25         assert(!__asan_address_is_poisoned(beg + idx));
     26     for (size_t idx = size; idx < capacity; idx++)
     27         assert(__asan_address_is_poisoned(beg + idx));
     28     assert(__sanitizer_verify_contiguous_container(beg, mid, end));
     29     assert(NULL ==
     30            __sanitizer_contiguous_container_find_bad_address(beg, mid, end));
     31     if (mid != beg) {
     32       assert(!__sanitizer_verify_contiguous_container(beg, mid - 1, end));
     33       assert(mid - 1 == __sanitizer_contiguous_container_find_bad_address(
     34                             beg, mid - 1, end));
     35     }
     36     if (mid != end) {
     37       assert(!__sanitizer_verify_contiguous_container(beg, mid + 1, end));
     38       assert(mid == __sanitizer_contiguous_container_find_bad_address(
     39                         beg, mid + 1, end));
     40     }
     41   }
     42 
     43   // Don't forget to unpoison the whole thing before destroing/reallocating.
     44   __sanitizer_annotate_contiguous_container(beg, end, mid, end);
     45   for (size_t idx = 0; idx < capacity; idx++)
     46     assert(!__asan_address_is_poisoned(beg + idx));
     47   delete[] beg;
     48 }
     49 
     50 __attribute__((noinline))
     51 void Throw() { throw 1; }
     52 
     53 __attribute__((noinline))
     54 void ThrowAndCatch() {
     55   try {
     56     Throw();
     57   } catch(...) {
     58   }
     59 }
     60 
     61 void TestThrow() {
     62   char x[32];
     63   __sanitizer_annotate_contiguous_container(x, x + 32, x + 32, x + 14);
     64   assert(!__asan_address_is_poisoned(x + 13));
     65   assert(__asan_address_is_poisoned(x + 14));
     66   ThrowAndCatch();
     67   assert(!__asan_address_is_poisoned(x + 13));
     68   // FIXME: invert the assertion below once we fix
     69   // https://code.google.com/p/address-sanitizer/issues/detail?id=258
     70   // This assertion works only w/o UAR.
     71   if (!__asan_get_current_fake_stack())
     72     assert(!__asan_address_is_poisoned(x + 14));
     73   __sanitizer_annotate_contiguous_container(x, x + 32, x + 14, x + 32);
     74   assert(!__asan_address_is_poisoned(x + 13));
     75   assert(!__asan_address_is_poisoned(x + 14));
     76 }
     77 
     78 int main(int argc, char **argv) {
     79   int n = argc == 1 ? 128 : atoi(argv[1]);
     80   for (int i = 0; i <= n; i++)
     81     TestContainer(i);
     82   TestThrow();
     83 }
     84