Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AddressSanitizerInterface.GetAllocatedSizeAndOwnershipTest is flaky #86

Closed
ramosian-glider opened this issue Aug 31, 2015 · 8 comments
Closed

Comments

@ramosian-glider
Copy link
Member

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
Copy link
Member Author

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
Copy link
Member Author

$ 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

  • Status changed: Started

@ramosian-glider
Copy link
Member Author

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
Copy link
Member Author

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
Copy link
Member Author

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
Copy link
Member Author

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

  • Status changed: Fixed

@ramosian-glider
Copy link
Member Author

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

  • Labels added: OpSys-All

@ramosian-glider
Copy link
Member Author

Adding Project:AddressSanitizer as part of GitHub migration.

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

  • Labels added: ProjectAddressSanitizer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant