Skip to content

Commit 5d146c6

Browse files
authored
[compiler-rt][rtsan] Introduce rtsan_interface.h and ScopedDisabler (#106736)
1 parent 0745219 commit 5d146c6

File tree

4 files changed

+131
-4
lines changed

4 files changed

+131
-4
lines changed

compiler-rt/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ if (COMPILER_RT_BUILD_SANITIZERS)
1010
sanitizer/lsan_interface.h
1111
sanitizer/msan_interface.h
1212
sanitizer/netbsd_syscall_hooks.h
13+
sanitizer/rtsan_interface.h
1314
sanitizer/scudo_interface.h
1415
sanitizer/tsan_interface.h
1516
sanitizer/tsan_interface_atomic.h
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
//===-- sanitizer/rtsan_interface.h -----------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file is a part of RealtimeSanitizer.
10+
//
11+
// Public interface header.
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef SANITIZER_RTSAN_INTERFACE_H
15+
#define SANITIZER_RTSAN_INTERFACE_H
16+
17+
#include <sanitizer/common_interface_defs.h>
18+
19+
#ifdef __cplusplus
20+
extern "C" {
21+
#endif // __cplusplus
22+
23+
// Disable all RTSan error reporting.
24+
// Must be paired with a call to `__rtsan_enable`
25+
void SANITIZER_CDECL __rtsan_disable(void);
26+
27+
// Re-enable all RTSan error reporting.
28+
// Must follow a call to `__rtsan_disable`.
29+
void SANITIZER_CDECL __rtsan_enable(void);
30+
31+
#ifdef __cplusplus
32+
} // extern "C"
33+
34+
namespace __rtsan {
35+
#if defined(__has_feature) && __has_feature(realtime_sanitizer)
36+
37+
class ScopedDisabler {
38+
public:
39+
ScopedDisabler() { __rtsan_disable(); }
40+
~ScopedDisabler() { __rtsan_enable(); }
41+
42+
#if __cplusplus >= 201103L
43+
ScopedDisabler(const ScopedDisabler &) = delete;
44+
ScopedDisabler &operator=(const ScopedDisabler &) = delete;
45+
ScopedDisabler(ScopedDisabler &&) = delete;
46+
ScopedDisabler &operator=(ScopedDisabler &&) = delete;
47+
#else
48+
private:
49+
ScopedDisabler(const ScopedDisabler &);
50+
ScopedDisabler &operator=(const ScopedDisabler &);
51+
#endif // __cplusplus >= 201103L
52+
};
53+
54+
#else
55+
56+
class ScopedDisabler {
57+
public:
58+
ScopedDisabler() {}
59+
#if __cplusplus >= 201103L
60+
ScopedDisabler(const ScopedDisabler &) = delete;
61+
ScopedDisabler &operator=(const ScopedDisabler &) = delete;
62+
ScopedDisabler(ScopedDisabler &&) = delete;
63+
ScopedDisabler &operator=(ScopedDisabler &&) = delete;
64+
#else
65+
private:
66+
ScopedDisabler(const ScopedDisabler &);
67+
ScopedDisabler &operator=(const ScopedDisabler &);
68+
#endif // __cplusplus >= 201103L
69+
};
70+
71+
#endif // defined(__has_feature) && __has_feature(realtime_sanitizer)
72+
} // namespace __rtsan
73+
#endif // __cplusplus
74+
75+
#endif // SANITIZER_RTSAN_INTERFACE_H

compiler-rt/lib/rtsan/rtsan.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,10 @@ SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_realtime_enter();
3636
// intercepted method calls to the real methods.
3737
SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_realtime_exit();
3838

39-
// Disable all RTSan error reporting.
40-
// Injected into the code if "nosanitize(realtime)" is on a function.
39+
// See documentation in rtsan_interface.h.
4140
SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_disable();
4241

43-
// Re-enable all RTSan error reporting.
44-
// The counterpart to `__rtsan_disable`.
42+
// See documentation in rtsan_interface.h.
4543
SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_enable();
4644

4745
SANITIZER_INTERFACE_ATTRIBUTE void

compiler-rt/test/rtsan/disabler.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// RUN: %clangxx -fsanitize=realtime %s -o %t
2+
// RUN: not %run %t 2>&1 | FileCheck %s
3+
// RUN: %clangxx %s -fsanitize=realtime -o - -S -emit-llvm | FileCheck %s --check-prefix=CHECK-ENABLED-IR
4+
// RUN: %clangxx %s -o - -S -emit-llvm | FileCheck %s --check-prefix=CHECK-DISABLED-IR
5+
// UNSUPPORTED: ios
6+
7+
#include <stdio.h>
8+
#include <stdlib.h>
9+
10+
#include "sanitizer/rtsan_interface.h"
11+
12+
void violation() [[clang::nonblocking]] {
13+
void *ptr;
14+
{
15+
__rtsan::ScopedDisabler disabler{};
16+
ptr = malloc(2);
17+
fprintf(stderr, "Allocated pointer %p in disabled context\n", ptr);
18+
}
19+
20+
// ensure nested disablers don't interfere with one another
21+
{
22+
void *ptr2;
23+
__rtsan::ScopedDisabler disabler{};
24+
{
25+
__rtsan::ScopedDisabler disabler2{};
26+
ptr2 = malloc(2);
27+
fprintf(stderr, "Allocated second pointer %p in disabled context\n",
28+
ptr2);
29+
}
30+
31+
free(ptr2);
32+
fprintf(stderr, "Free'd second pointer in disabled context\n");
33+
}
34+
35+
free(ptr);
36+
}
37+
38+
int main() {
39+
violation();
40+
return 0;
41+
// CHECK: Allocated pointer {{.*}} in disabled context
42+
// CHECK: Allocated second pointer {{.*}} in disabled context
43+
// CHECK: Free'd second pointer in disabled context
44+
// CHECK: {{.*Real-time violation.*}}
45+
// CHECK-NOT: {{.*malloc*}}
46+
// CHECK-NEXT: {{.*free.*}}
47+
}
48+
49+
// CHECK-ENABLED-IR: {{.*@__rtsan_disable.*}}
50+
// CHECK-ENABLED-IR: {{.*@__rtsan_enable.*}}
51+
52+
// CHECK-DISABLED-IR-NOT: {{.*__rtsan_disable.*}}
53+
// CHECK-DISABLED-IR-NOT: {{.*__rtsan_enable.*}}

0 commit comments

Comments
 (0)