xref: /llvm-project/compiler-rt/lib/sanitizer_common/tests/sanitizer_stoptheworld_testlib.cpp (revision d6d569fc06361cb2324abf5f36192063ce0b4289)
1*d6d569fcSNico Weber //===-- sanitizer_stoptheworld_testlib.cpp --------------------------------===//
2*d6d569fcSNico Weber //
3*d6d569fcSNico Weber // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*d6d569fcSNico Weber // See https://llvm.org/LICENSE.txt for license information.
5*d6d569fcSNico Weber // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*d6d569fcSNico Weber //
7*d6d569fcSNico Weber //===----------------------------------------------------------------------===//
8*d6d569fcSNico Weber // Dynamic library to test StopTheWorld functionality.
9*d6d569fcSNico Weber // When loaded with LD_PRELOAD, it will periodically suspend all threads.
10*d6d569fcSNico Weber //===----------------------------------------------------------------------===//
11*d6d569fcSNico Weber /* Usage:
12*d6d569fcSNico Weber clang++ -fno-exceptions -g -fPIC -I. \
13*d6d569fcSNico Weber  sanitizer_common/tests/sanitizer_stoptheworld_testlib.cpp \
14*d6d569fcSNico Weber  sanitizer_common/sanitizer_*.cpp -shared -lpthread -o teststoptheworld.so
15*d6d569fcSNico Weber LD_PRELOAD=`pwd`/teststoptheworld.so /your/app
16*d6d569fcSNico Weber */
17*d6d569fcSNico Weber 
18*d6d569fcSNico Weber #include "sanitizer_common/sanitizer_platform.h"
19*d6d569fcSNico Weber #if SANITIZER_LINUX
20*d6d569fcSNico Weber 
21*d6d569fcSNico Weber #include <dlfcn.h>
22*d6d569fcSNico Weber #include <stddef.h>
23*d6d569fcSNico Weber #include <stdio.h>
24*d6d569fcSNico Weber #include <pthread.h>
25*d6d569fcSNico Weber #include <unistd.h>
26*d6d569fcSNico Weber 
27*d6d569fcSNico Weber #include "sanitizer_common/sanitizer_stoptheworld.h"
28*d6d569fcSNico Weber 
29*d6d569fcSNico Weber namespace {
30*d6d569fcSNico Weber const uptr kSuspendDuration = 3;
31*d6d569fcSNico Weber const uptr kRunDuration = 3;
32*d6d569fcSNico Weber 
Callback(const SuspendedThreadsList & suspended_threads_list,void * argument)33*d6d569fcSNico Weber void Callback(const SuspendedThreadsList &suspended_threads_list,
34*d6d569fcSNico Weber               void *argument) {
35*d6d569fcSNico Weber   sleep(kSuspendDuration);
36*d6d569fcSNico Weber }
37*d6d569fcSNico Weber 
SuspenderThread(void * argument)38*d6d569fcSNico Weber void *SuspenderThread(void *argument) {
39*d6d569fcSNico Weber   while (true) {
40*d6d569fcSNico Weber     sleep(kRunDuration);
41*d6d569fcSNico Weber     StopTheWorld(Callback, NULL);
42*d6d569fcSNico Weber   }
43*d6d569fcSNico Weber   return NULL;
44*d6d569fcSNico Weber }
45*d6d569fcSNico Weber 
StopTheWorldTestLibConstructor(void)46*d6d569fcSNico Weber __attribute__((constructor)) void StopTheWorldTestLibConstructor(void) {
47*d6d569fcSNico Weber   pthread_t thread_id;
48*d6d569fcSNico Weber   pthread_create(&thread_id, NULL, SuspenderThread, NULL);
49*d6d569fcSNico Weber }
50*d6d569fcSNico Weber }  // namespace
51*d6d569fcSNico Weber 
52*d6d569fcSNico Weber #endif  // SANITIZER_LINUX
53