Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions compiler-rt/test/tsan/java_heap_init2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
// XFAIL: *

#include "java.h"
#include <errno.h>
#include <sys/mman.h>

int main() {
// Test a non-regular kHeapSize
// Previously __tsan_java_init failed because it encountered non-zero meta
// shadow for the destination.
size_t const kPageSize = sysconf(_SC_PAGESIZE);
int const kSize = kPageSize - 1;
jptr jheap2 = (jptr)mmap(0, kSize, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, -1, 0);
if (jheap2 == (jptr)MAP_FAILED)
return printf("mmap failed with %d\n", errno);
__atomic_store_n((int *)(jheap2 + kSize - 3), 1, __ATOMIC_RELEASE);
// Due to the previous incorrect meta-end calculation, the following munmap
// did not clear the tail meta shadow.
munmap((void *)jheap2, kSize);
int const kHeapSize2 = kSize + 1;
jheap2 = (jptr)mmap((void *)jheap2, kHeapSize2, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, -1, 0);
if (jheap2 == (jptr)MAP_FAILED)
return printf("second mmap failed with %d\n", errno);
__tsan_java_init(jheap2, kHeapSize2);
__tsan_java_move(jheap2, jheap2 + kHeapSize2 - 8, 8);
fprintf(stderr, "DONE\n");
return __tsan_java_fini();
}

// CHECK-NOT: WARNING: ThreadSanitizer: data race
// CHECK: DONE
59 changes: 59 additions & 0 deletions compiler-rt/test/tsan/munmap_clear_shadow.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// RUN: %clang_tsan %s -o %t && %run %t | FileCheck %s
// XFAIL: *

#include "test.h"
#include <assert.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>

void __tsan_read1(void *addr);

struct thread_params {
char *buf;
unsigned int size;
};

static void *thread_func(void *arg) {
struct thread_params *p = (struct thread_params *)arg;
// Access 1
p->buf[0] = 0x42;
p->buf[p->size - 1] = 0x42;
barrier_wait(&barrier);
return 0;
}

int main() {
const unsigned int kPageSize = sysconf(_SC_PAGESIZE);
// The relevant shadow memory size should be exactly multiple of kPageSize,
// even if Size = kPageSize - 1.
const unsigned int Size = kPageSize - 1;

barrier_init(&barrier, 2);
char *buf = (char *)mmap(NULL, Size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
assert(buf != MAP_FAILED);
assert(((uintptr_t)buf % kPageSize) == 0);

pthread_t t;
struct thread_params p = {buf, Size};
pthread_create(&t, 0, thread_func, &p);

barrier_wait(&barrier);
// Should clear all the shadow memory related to the mmaped memory.
munmap(buf, Size);

// If the shadow memory is cleared completely, the following reads should not
// cause races and behave the same. However, previously, __tsan_read1(&buf[0])
// would not report a race, while __tsan_read1(&buf[Size - 1]) did.
// CHECK-NOT: WARNING: ThreadSanitizer: data race
__tsan_read1(&buf[0]); // Access 2
__tsan_read1(&buf[Size - 1]); // Access 2
pthread_join(t, 0);

puts("DONE");

return 0;
}
Loading