Skip to content

Commit 7c85caf

Browse files
committed
Init check
1 parent b634e05 commit 7c85caf

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

compiler-rt/lib/rtsan/rtsan.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,24 @@
1212
#include <rtsan/rtsan_context.h>
1313
#include <rtsan/rtsan_interceptors.h>
1414

15+
using namespace __rtsan;
16+
17+
bool __rtsan::rtsan_initialized;
18+
bool __rtsan::rtsan_init_is_running;
19+
20+
1521
extern "C" {
1622

1723
SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_init() {
18-
__rtsan::InitializeInterceptors();
24+
CHECK(!rtsan_init_is_running);
25+
if (rtsan_initialized)
26+
return;
27+
rtsan_init_is_running = true;
28+
29+
InitializeInterceptors();
30+
31+
rtsan_init_is_running = false;
32+
rtsan_initialized = true;
1933
}
2034

2135
SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_realtime_enter() {

compiler-rt/lib/rtsan/rtsan.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@
1414

1515
extern "C" {
1616

17+
namespace __rtsan {
18+
19+
extern bool rtsan_initialized;
20+
extern bool rtsan_init_is_running;
21+
22+
} // namespace __rtsan
23+
24+
1725
// Initialise rtsan interceptors.
1826
// A call to this method is added to the preinit array on Linux systems.
1927
SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_init();

compiler-rt/lib/rtsan/rtsan_interceptors.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "sanitizer_common/sanitizer_platform_interceptors.h"
1515

1616
#include "interception/interception.h"
17+
#include "rtsan/rtsan.h"
1718
#include "rtsan/rtsan_context.h"
1819

1920
#if SANITIZER_APPLE
@@ -35,6 +36,30 @@
3536

3637
using namespace __sanitizer;
3738

39+
using __rtsan::rtsan_init_is_running;
40+
using __rtsan::rtsan_initialized;
41+
42+
constexpr uptr kEarlyAllocBufSize = 16384;
43+
static uptr allocated_bytes;
44+
static char early_alloc_buf[kEarlyAllocBufSize];
45+
46+
static bool IsInEarlyAllocBuf(const void *ptr) {
47+
return ((uptr)ptr >= (uptr)early_alloc_buf &&
48+
((uptr)ptr - (uptr)early_alloc_buf) < sizeof(early_alloc_buf));
49+
}
50+
51+
template <typename T> T min(T a, T b) { return a < b ? a : b; }
52+
53+
// Handle allocation requests early (before all interceptors are setup). dlsym,
54+
// for example, calls calloc.
55+
static void *HandleEarlyAlloc(uptr size) {
56+
void *Mem = (void *)&early_alloc_buf[allocated_bytes];
57+
allocated_bytes += size;
58+
CHECK_LT(allocated_bytes, kEarlyAllocBufSize);
59+
return Mem;
60+
}
61+
62+
3863
void ExpectNotRealtime(const char *intercepted_function_name) {
3964
__rtsan::GetContextForThisThread().ExpectNotRealtime(
4065
intercepted_function_name);
@@ -238,18 +263,30 @@ INTERCEPTOR(int, nanosleep, const struct timespec *rqtp,
238263
// Memory
239264

240265
INTERCEPTOR(void *, calloc, SIZE_T num, SIZE_T size) {
266+
if (rtsan_init_is_running && REAL(calloc) == nullptr) {
267+
// Note: EarlyAllocBuf is initialized with zeros.
268+
return HandleEarlyAlloc(num * size);
269+
}
270+
241271
ExpectNotRealtime("calloc");
242272
return REAL(calloc)(num, size);
243273
}
244274

245275
INTERCEPTOR(void, free, void *ptr) {
276+
if (IsInEarlyAllocBuf(ptr))
277+
return;
278+
246279
if (ptr != NULL) {
247280
ExpectNotRealtime("free");
248281
}
249282
return REAL(free)(ptr);
250283
}
251284

252285
INTERCEPTOR(void *, malloc, SIZE_T size) {
286+
if (rtsan_init_is_running && REAL(malloc) == nullptr) {
287+
return HandleEarlyAlloc(size);
288+
}
289+
253290
ExpectNotRealtime("malloc");
254291
return REAL(malloc)(size);
255292
}

0 commit comments

Comments
 (0)