17c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar// RUN: %clangxx -O1 %s -o %t && TSAN_OPTIONS="flush_memory_ms=1 memory_limit_mb=1" ASAN_OPTIONS="handle_segv=0 allow_user_segv_handler=1" %run %t 2>&1 | FileCheck %s 286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// JVM uses SEGV to preempt threads. All threads do a load from a known address 486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// periodically. When runtime needs to preempt threads, it unmaps the page. 586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// Threads start triggering SEGV one by one. The signal handler blocks 686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// threads while runtime does its thing. Then runtime maps the page again 786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// and resumes the threads. 886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// Previously this pattern conflicted with stop-the-world machinery, 986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// because it briefly reset SEGV handler to SIG_DFL. 1086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// As the consequence JVM just silently died. 1186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 1286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// This test sets memory flushing rate to maximum, then does series of 1386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// "benign" SEGVs that are handled by signal handler, and ensures that 1486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// the process survive. 1586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 167c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar#include <stdio.h> 177c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar#include <stdlib.h> 1886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#include <signal.h> 1986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#include <sys/mman.h> 203d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#include <string.h> 213d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#include <unistd.h> 2286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 233d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainarunsigned long page_size; 2486277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesvoid *guard; 2586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 2686277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesvoid handler(int signo, siginfo_t *info, void *uctx) { 273d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar mprotect(guard, page_size, PROT_READ | PROT_WRITE); 2886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines} 2986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 3086277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesint main() { 313d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar page_size = sysconf(_SC_PAGESIZE); 327c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar struct sigaction a, old; 333d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar memset(&a, 0, sizeof(a)); 343d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar memset(&old, 0, sizeof(old)); 3586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines a.sa_sigaction = handler; 3686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines a.sa_flags = SA_SIGINFO; 377c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar sigaction(SIGSEGV, &a, &old); 383d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar guard = mmap(0, 3 * page_size, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0); 393d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar guard = (char*)guard + page_size; // work around a kernel bug 4086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines for (int i = 0; i < 1000000; i++) { 413d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar mprotect(guard, page_size, PROT_NONE); 4286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines *(int*)guard = 1; 4386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 447c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar sigaction(SIGSEGV, &old, 0); 4586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines fprintf(stderr, "DONE\n"); 4686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines} 4786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 4886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// CHECK: DONE 49