]>
git.proxmox.com Git - rustc.git/blob - src/compiler-rt/test/sanitizer_common/TestCases/Linux/signal_segv_handler.cc
1 // 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
3 // JVM uses SEGV to preempt threads. All threads do a load from a known address
4 // periodically. When runtime needs to preempt threads, it unmaps the page.
5 // Threads start triggering SEGV one by one. The signal handler blocks
6 // threads while runtime does its thing. Then runtime maps the page again
7 // and resumes the threads.
8 // Previously this pattern conflicted with stop-the-world machinery,
9 // because it briefly reset SEGV handler to SIG_DFL.
10 // As the consequence JVM just silently died.
12 // This test sets memory flushing rate to maximum, then does series of
13 // "benign" SEGVs that are handled by signal handler, and ensures that
14 // the process survive.
23 unsigned long page_size
;
26 void handler(int signo
, siginfo_t
*info
, void *uctx
) {
27 mprotect(guard
, page_size
, PROT_READ
| PROT_WRITE
);
31 page_size
= sysconf(_SC_PAGESIZE
);
32 struct sigaction a
, old
;
33 memset(&a
, 0, sizeof(a
));
34 memset(&old
, 0, sizeof(old
));
35 a
.sa_sigaction
= handler
;
36 a
.sa_flags
= SA_SIGINFO
;
37 sigaction(SIGSEGV
, &a
, &old
);
38 guard
= mmap(0, 3 * page_size
, PROT_NONE
, MAP_ANON
| MAP_PRIVATE
, -1, 0);
39 guard
= (char*)guard
+ page_size
; // work around a kernel bug
40 for (int i
= 0; i
< 1000000; i
++) {
41 mprotect(guard
, page_size
, PROT_NONE
);
44 sigaction(SIGSEGV
, &old
, 0);
45 fprintf(stderr
, "DONE\n");