ramosian-glider / sanitizer-issues

test
0 stars 0 forks source link

AddressSanitizerInterface.GetAllocatedSizeAndOwnershipTest is flaky #86

Closed ramosian-glider closed 9 years ago

ramosian-glider commented 9 years ago

Originally reported on Google Code with ID 86

This tests rarely fails on Mac OS x64 (though there should be nothing OS-specific, so
I expect similar failures on other systems):

[ RUN      ] AddressSanitizerInterface.GetAllocatedSizeAndOwnershipTest
tests/asan_noinst_test.cc:359: Failure
Value of: __asan_get_ownership(array + kArraySize / 2)
  Actual: true
Expected: false
[  FAILED  ] AddressSanitizerInterface.GetAllocatedSizeAndOwnershipTest (1510 ms)

Reported by ramosian.glider on 2012-07-03 14:53:22

ramosian-glider commented 9 years ago
after quite a few runs I've got this:
[ RUN      ] AddressSanitizerInterface.GetAllocatedSizeAndOwnershipTest
tests/asan_noinst_test.cc:361: Failure
Death test: __asan_get_allocated_size(array + kArraySize / 2)
    Result: died but not with expected error.
  Expected: attempting to call __asan_get_allocated_size()
Actual msg: ASAN:SIGSEGV
==99711== ERROR: AddressSanitizer crashed on unknown address 0x000000000000

Reported by konstantin.s.serebryany on 2012-07-04 08:05:55

ramosian-glider commented 9 years ago
$ cat t.cc
#include <stdio.h>
#include <assert.h>
#include <unistd.h>

extern "C"
bool __asan_get_ownership(void *ptr);

int main() {
  const size_t kArraySize = 100;
  char *array = (char*)malloc(kArraySize);
  char *p = array + kArraySize / 2;
  printf("__asan_get_ownership(%p): %d\n", p, __asan_get_ownership(p));
  if (__asan_get_ownership(p)) {
    fprintf(stderr, "pid: %d\n", getpid());
    sleep(1000);
  }
  return 0;
}
$ rm log; while true; do ASAN_OPTIONS=sleep_before_dying=1000 ./t 2>&1 | tee -a log;
done

...
__asan_get_ownership(0x10c39bfb2): 0
__asan_get_ownership(0x110933fb2): 0
__asan_get_ownership(0x107db8fb2): 0
__asan_get_ownership(0x10ca1bfb2): 0
__asan_get_ownership(0x104195fb2): 0
__asan_get_ownership(0x111a9ffb2): 0
__asan_get_ownership(0x109095fb2): 0
__asan_get_ownership(0x105d8efb2): 0
__asan_get_ownership(0x10c121fb2): 0
ASAN:SIGSEGV
==10282== ERROR: AddressSanitizer crashed on unknown address 0xffffff0103249ea9 (pc
0x000100dd0ccb sp 0x7fff5ee32ab0 bp 0x000000000001 T0)
AddressSanitizer can not provide additional info. ABORTING
    #0 0x100dd0ccb (/Users/glider/src/asan/llvm/projects/compiler-rt/lib/asan/./t+0x3ccb)
Stats: 0M malloced (0M for red zones) by 1 calls
Stats: 0M realloced by 0 calls
Stats: 0M freed by 0 calls
Stats: 0M really freed by 0 calls
Stats: 4M (1024 full pages) mmaped in 1 calls
  mmaps   by size class: 8:16383; 
  mallocs by size class: 8:1; 
  frees   by size class: 
  rfrees  by size class: 
Stats: malloc large: 0 small slow: 1
==10282== Sleeping for 1000 second(s)

Reported by ramosian.glider on 2012-08-06 09:49:01

ramosian-glider commented 9 years ago
ASan is unable to unwind past main() in ./t, but I'm getting the following stack from
gdb each time the crash occurs:

#0  0x00007fff87133386 in __semwait_signal ()
#1  0x00007fff89f29828 in nanosleep ()
#2  0x00007fff89f296b2 in sleep ()
#3  0x000000010edd3ee5 in __sanitizer::Die ()
#4  0x00007fff6e9d056e in __dyld__ZN4dyldL12registerDOFsERKNSt3__16vectorIN11ImageLoader7DOFInfoENS0_9allocatorIS3_EEEE
()

Looks like the crash in dyld::registerDOFs happens before the main().

Reported by ramosian.glider on 2012-08-06 10:58:31

ramosian-glider commented 9 years ago
Apart from the above problem, for the same test __asan_get_ownership() sometimes incorrectly
returns 1 (this is the case described in comment #1).
This happens because the following function:

 376   uptr AllocationSize(uptr ptr) {
 377     if (!ptr) return 0;
 378     ScopedLock lock(&mu_);
 379 
 380     // first, check if this is our memory
 381     PageGroup *g = FindPageGroupUnlocked(ptr);
 382     if (!g) return 0;
 383     AsanChunk *m = PtrToChunk(ptr);
 384     if (m->chunk_state == CHUNK_ALLOCATED) {
 385       return m->used_size;
 386     } else {
 387       return 0;
 388     }
 389   }

returns some random value as m->used_size.
I've inserted two CHECKs into the CHUNK_ALLOCATED branch:

       CHECK(m->alloc_tid >= 0);
       CHECK(m->free_tid == kInvalidTid);

, and the second one has started failing.

This means that for some reason AllocationSize() does not bail out after a call to
FindPageGroupUnlocked() for an invalid ptr. As a result, an invalid chunk pointer is
calculated, which accidentally has chunk_state==CHUNK_ALLOCATED, but other fields are
incorrect.

Reported by ramosian.glider on 2012-08-06 11:13:15

ramosian-glider commented 9 years ago
After a discussion with Alexey we've decided to look up for the chunk containing |ptr|
and check whether |ptr| is actually the beginning of this chunk.
Clang r161320 should fix this issue.

Reported by ramosian.glider on 2012-08-06 12:25:29

ramosian-glider commented 9 years ago

Reported by ramosian.glider on 2012-08-06 12:25:38

ramosian-glider commented 9 years ago

Reported by ramosian.glider on 2012-09-13 13:43:12

ramosian-glider commented 9 years ago
Adding Project:AddressSanitizer as part of GitHub migration.

Reported by ramosian.glider on 2015-07-30 09:12:59