diff --git a/compiler-rt/lib/rtsan/CMakeLists.txt b/compiler-rt/lib/rtsan/CMakeLists.txt index bd7358e86e59b..3f146a757a97e 100644 --- a/compiler-rt/lib/rtsan/CMakeLists.txt +++ b/compiler-rt/lib/rtsan/CMakeLists.txt @@ -3,6 +3,7 @@ include_directories(..) set(RTSAN_CXX_SOURCES rtsan.cpp rtsan_context.cpp + rtsan_flags.cpp rtsan_stack.cpp rtsan_interceptors.cpp) @@ -12,7 +13,10 @@ set(RTSAN_PREINIT_SOURCES set(RTSAN_HEADERS rtsan.h rtsan_context.h - rtsan_stack.h) + rtsan_flags.h + rtsan_flags.inc + rtsan_stack.h + ) set(RTSAN_DEPS) diff --git a/compiler-rt/lib/rtsan/rtsan.cpp b/compiler-rt/lib/rtsan/rtsan.cpp index 1388ce66cbde2..f929c9ae81c11 100644 --- a/compiler-rt/lib/rtsan/rtsan.cpp +++ b/compiler-rt/lib/rtsan/rtsan.cpp @@ -10,9 +10,11 @@ #include #include +#include #include #include "sanitizer_common/sanitizer_atomic.h" +#include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_mutex.h" using namespace __rtsan; @@ -29,7 +31,11 @@ extern "C" { SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_init() { CHECK(!__rtsan_is_initialized()); + + SanitizerToolName = "RealtimeSanitizer"; + InitializeFlags(); InitializeInterceptors(); + SetInitialized(); } diff --git a/compiler-rt/lib/rtsan/rtsan_context.cpp b/compiler-rt/lib/rtsan/rtsan_context.cpp index 97f18dfbbcca8..a49b70360babb 100644 --- a/compiler-rt/lib/rtsan/rtsan_context.cpp +++ b/compiler-rt/lib/rtsan/rtsan_context.cpp @@ -8,6 +8,7 @@ // //===----------------------------------------------------------------------===// +#include #include #include @@ -75,6 +76,7 @@ void __rtsan::Context::BypassPop() { bypass_depth_--; } void __rtsan::ExpectNotRealtime(Context &context, const char *intercepted_function_name) { + CHECK(__rtsan_is_initialized()); if (context.InRealtimeContext() && !context.IsBypassed()) { context.BypassPush(); diff --git a/compiler-rt/lib/rtsan/rtsan_flags.cpp b/compiler-rt/lib/rtsan/rtsan_flags.cpp new file mode 100644 index 0000000000000..beab2a2fc5d89 --- /dev/null +++ b/compiler-rt/lib/rtsan/rtsan_flags.cpp @@ -0,0 +1,58 @@ +//===--- rtsan_flags.cpp - Realtime Sanitizer -------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of RealtimeSanitizer. +// +//===----------------------------------------------------------------------===// + +#include "rtsan/rtsan_flags.h" +#include "sanitizer_common/sanitizer_flag_parser.h" +#include "sanitizer_common/sanitizer_flags.h" + +using namespace __sanitizer; +using namespace __rtsan; + +Flags __rtsan::flags_data; + +SANITIZER_INTERFACE_WEAK_DEF(const char *, __rtsan_default_options, void) { + return ""; +} + +static void RegisterRtsanFlags(FlagParser *parser, Flags *f) { +#define RTSAN_FLAG(Type, Name, DefaultValue, Description) \ + RegisterFlag(parser, #Name, Description, &f->Name); +#include "rtsan_flags.inc" +#undef RTSAN_FLAG +} + +void __rtsan::InitializeFlags() { + SetCommonFlagsDefaults(); + { + CommonFlags cf; + cf.CopyFrom(*common_flags()); + cf.external_symbolizer_path = GetEnv("RTSAN_SYMBOLIZER_PATH"); + OverrideCommonFlags(cf); + } + + FlagParser parser; + RegisterRtsanFlags(&parser, &flags()); + RegisterCommonFlags(&parser); + + // Override from user-specified string. + parser.ParseString(__rtsan_default_options()); + + parser.ParseStringFromEnv("RTSAN_OPTIONS"); + + InitializeCommonFlags(); + + if (Verbosity()) + ReportUnrecognizedFlags(); + + if (common_flags()->help) + parser.PrintFlagDescriptions(); +} diff --git a/compiler-rt/lib/rtsan/rtsan_flags.h b/compiler-rt/lib/rtsan/rtsan_flags.h new file mode 100644 index 0000000000000..29025c29b6fc2 --- /dev/null +++ b/compiler-rt/lib/rtsan/rtsan_flags.h @@ -0,0 +1,28 @@ +//===----------------------- rtsan_flags.h ----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of RealtimeSanitizer. +// +//===----------------------------------------------------------------------===// +#pragma once + +namespace __rtsan { + +struct Flags { +#define RTSAN_FLAG(Type, Name, DefaultValue, Description) \ + Type Name{DefaultValue}; +#include "rtsan_flags.inc" +#undef RTSAN_FLAG +}; + +extern Flags flags_data; +inline Flags &flags() { return flags_data; } + +void InitializeFlags(); + +} // namespace __rtsan diff --git a/compiler-rt/lib/rtsan/rtsan_flags.inc b/compiler-rt/lib/rtsan/rtsan_flags.inc new file mode 100644 index 0000000000000..93b0294313672 --- /dev/null +++ b/compiler-rt/lib/rtsan/rtsan_flags.inc @@ -0,0 +1,20 @@ +//===------------------------ rtsan_flags.inc -------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// RTSan runtime flags. +// +//===----------------------------------------------------------------------===// +#ifndef RTSAN_FLAG +#error "Define RTSAN_FLAG prior to including this file!" +#endif + +// RTSAN_FLAG(Type, Name, DefaultValue, Description) +// See COMMON_FLAG in sanitizer_flags.inc for more details. + +// Example flag, until we get a real one +// RTSAN_FLAG(bool, halt_on_error, true, "If true, halt the program on error") diff --git a/compiler-rt/lib/rtsan/rtsan_stack.cpp b/compiler-rt/lib/rtsan/rtsan_stack.cpp index 0598af2337ed1..aeb6a2a3cbd7e 100644 --- a/compiler-rt/lib/rtsan/rtsan_stack.cpp +++ b/compiler-rt/lib/rtsan/rtsan_stack.cpp @@ -29,21 +29,9 @@ void BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, void *context, } } // namespace __sanitizer -static void SetGlobalStackTraceFormat() { - SetCommonFlagsDefaults(); - CommonFlags cf; - cf.CopyFrom(*common_flags()); - cf.stack_trace_format = "DEFAULT"; - cf.external_symbolizer_path = GetEnv("RTSAN_SYMBOLIZER_PATH"); - OverrideCommonFlags(cf); -} - void __rtsan::PrintStackTrace(uptr pc, uptr bp) { - BufferedStackTrace stack{}; stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal); - - SetGlobalStackTraceFormat(); stack.Print(); } diff --git a/compiler-rt/lib/rtsan/tests/rtsan_test_context.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_context.cpp index cad8cf2d53996..6b9d7e2df123c 100644 --- a/compiler-rt/lib/rtsan/tests/rtsan_test_context.cpp +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_context.cpp @@ -10,31 +10,37 @@ #include "rtsan_test_utilities.h" -#include "rtsan_context.h" +#include "rtsan/rtsan.h" +#include "rtsan/rtsan_context.h" -TEST(TestRtsanContext, CanCreateContext) { __rtsan::Context context{}; } +#include -TEST(TestRtsanContext, ExpectNotRealtimeDoesNotDieBeforeRealtimePush) { +class TestRtsanContext : public ::testing::Test { +protected: + void SetUp() override { __rtsan_ensure_initialized(); } +}; + +TEST_F(TestRtsanContext, ExpectNotRealtimeDoesNotDieBeforeRealtimePush) { __rtsan::Context context{}; ExpectNotRealtime(context, "do_some_stuff"); } -TEST(TestRtsanContext, ExpectNotRealtimeDoesNotDieAfterPushAndPop) { +TEST_F(TestRtsanContext, ExpectNotRealtimeDoesNotDieAfterPushAndPop) { __rtsan::Context context{}; context.RealtimePush(); context.RealtimePop(); ExpectNotRealtime(context, "do_some_stuff"); } -TEST(TestRtsanContext, ExpectNotRealtimeDiesAfterRealtimePush) { +TEST_F(TestRtsanContext, ExpectNotRealtimeDiesAfterRealtimePush) { __rtsan::Context context{}; context.RealtimePush(); EXPECT_DEATH(ExpectNotRealtime(context, "do_some_stuff"), ""); } -TEST(TestRtsanContext, - ExpectNotRealtimeDiesAfterRealtimeAfterMorePushesThanPops) { +TEST_F(TestRtsanContext, + ExpectNotRealtimeDiesAfterRealtimeAfterMorePushesThanPops) { __rtsan::Context context{}; context.RealtimePush(); @@ -45,7 +51,7 @@ TEST(TestRtsanContext, EXPECT_DEATH(ExpectNotRealtime(context, "do_some_stuff"), ""); } -TEST(TestRtsanContext, ExpectNotRealtimeDoesNotDieAfterBypassPush) { +TEST_F(TestRtsanContext, ExpectNotRealtimeDoesNotDieAfterBypassPush) { __rtsan::Context context{}; context.RealtimePush(); @@ -53,8 +59,8 @@ TEST(TestRtsanContext, ExpectNotRealtimeDoesNotDieAfterBypassPush) { ExpectNotRealtime(context, "do_some_stuff"); } -TEST(TestRtsanContext, - ExpectNotRealtimeDoesNotDieIfBypassDepthIsGreaterThanZero) { +TEST_F(TestRtsanContext, + ExpectNotRealtimeDoesNotDieIfBypassDepthIsGreaterThanZero) { __rtsan::Context context{}; context.RealtimePush(); diff --git a/compiler-rt/test/rtsan/unrecognized_flags.cpp b/compiler-rt/test/rtsan/unrecognized_flags.cpp new file mode 100644 index 0000000000000..9e44e9f429936 --- /dev/null +++ b/compiler-rt/test/rtsan/unrecognized_flags.cpp @@ -0,0 +1,11 @@ +// RUN: %clangxx -fsanitize=realtime %s -o %t +// RUN: RTSAN_OPTIONS="verbosity=1,asdf=1" %run %t 2>&1 | FileCheck %s +// UNSUPPORTED: ios + +// Intent: Make sure we are respecting some basic common flags + +int main() { + return 0; + // CHECK: WARNING: found 1 unrecognized flag(s): + // CHECK-NEXT: {{.*asdf*}} +} diff --git a/llvm/test/Unit/lit.cfg.py b/llvm/test/Unit/lit.cfg.py index 61296d7ea0032..f1646d1b894cd 100644 --- a/llvm/test/Unit/lit.cfg.py +++ b/llvm/test/Unit/lit.cfg.py @@ -47,6 +47,7 @@ "ASAN_OPTIONS", "HWASAN_OPTIONS", "MSAN_OPTIONS", + "RTSAN_OPTIONS", "TSAN_OPTIONS", "UBSAN_OPTIONS", ]: diff --git a/llvm/utils/lit/lit/TestingConfig.py b/llvm/utils/lit/lit/TestingConfig.py index 9d8e93460933d..f81b07baeeaed 100644 --- a/llvm/utils/lit/lit/TestingConfig.py +++ b/llvm/utils/lit/lit/TestingConfig.py @@ -41,6 +41,7 @@ def fromdefaults(litConfig): "LSAN_OPTIONS", "HWASAN_OPTIONS", "MSAN_OPTIONS", + "RTSAN_OPTIONS", "TSAN_OPTIONS", "UBSAN_OPTIONS", "ADB", diff --git a/llvm/utils/lit/lit/llvm/config.py b/llvm/utils/lit/lit/llvm/config.py index 8a6a0c2ed8089..5f762ec7f3514 100644 --- a/llvm/utils/lit/lit/llvm/config.py +++ b/llvm/utils/lit/lit/llvm/config.py @@ -83,6 +83,7 @@ def __init__(self, lit_config, config): "UBSAN_SYMBOLIZER_PATH" "ASAN_OPTIONS", "HWASAN_OPTIONS", "MSAN_OPTIONS", + "RTSAN_OPTIONS", "TSAN_OPTIONS", "UBSAN_OPTIONS", ]