[vm] Make some IgnoreRace functions inlinable.

Fix GCC TSAN build.
Cleanup sanitizer includes.

TEST=ci
Change-Id: Ib68bbfa701b4309c03514ed689391051094208e4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/452226
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
This commit is contained in:
Ryan Macnak
2025-10-01 09:41:26 -07:00
committed by Commit Queue
parent 1f99459069
commit f1ba8ceacf
27 changed files with 60 additions and 77 deletions
+1 -2
View File
@@ -16,8 +16,7 @@ extern "C" void _sanitizer_options_link_helper() {}
// callbacks are not sanitizer-instrumented, and that they aren't stripped by
// the linker.
#define SANITIZER_HOOK_ATTRIBUTE \
extern "C" __attribute__((no_sanitize_address)) \
__attribute__((no_sanitize_memory)) __attribute__((no_sanitize_thread)) \
extern "C" __attribute__((no_sanitize_thread)) \
__attribute__((visibility("default"))) __attribute__((used))
#endif
+1
View File
@@ -8,6 +8,7 @@
#include <atomic>
#include "platform/assert.h"
#include "platform/globals.h"
namespace dart {
namespace bin {
-18
View File
@@ -11,7 +11,6 @@ library_for_all_configs("libdart_platform") {
sources = platform_sources
include_dirs = [ ".." ]
extra_deps = []
configurable_deps = [ ":libdart_platform_no_tsan" ]
if (is_fuchsia) {
extra_deps += [
@@ -20,20 +19,3 @@ library_for_all_configs("libdart_platform") {
]
}
}
config("no_tsan_config") {
if (!is_win) {
cflags = [ "-fno-sanitize=thread" ]
}
}
library_for_all_configs("libdart_platform_no_tsan") {
target_type = "source_set"
public_configs = [ "../vm:libdart_vm_config" ]
extra_configs = [ ":no_tsan_config" ]
sources = [
"no_tsan.cc",
"no_tsan.h",
]
include_dirs = [ ".." ]
}
+1 -1
View File
@@ -19,7 +19,7 @@
#if defined(USING_ADDRESS_SANITIZER)
extern "C" void __asan_unpoison_memory_region(void const volatile*, size_t);
#define NO_SANITIZE_ADDRESS __attribute__((no_sanitize("address")))
#define NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
#define ASAN_UNPOISON(ptr, len) __asan_unpoison_memory_region(ptr, len)
#else // defined(USING_ADDRESS_SANITIZER)
#define NO_SANITIZE_ADDRESS
-1
View File
@@ -6,7 +6,6 @@
#define RUNTIME_PLATFORM_ASSERT_H_
#include "platform/globals.h"
#include "platform/memory_sanitizer.h"
#if !defined(DEBUG) && !defined(NDEBUG)
#error neither DEBUG nor NDEBUG defined
+1 -1
View File
@@ -36,7 +36,7 @@ extern "C" void __msan_check_mem_is_initialized(const volatile void*, size_t);
#define MSAN_UNPOISON(ptr, len) __msan_unpoison(ptr, len)
#define MSAN_CHECK_INITIALIZED(ptr, len) \
__msan_check_mem_is_initialized(ptr, len)
#define NO_SANITIZE_MEMORY __attribute__((no_sanitize("memory")))
#define NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
#else // defined(USING_MEMORY_SANITIZER)
#define MSAN_POISON(ptr, len) \
do { \
-33
View File
@@ -1,33 +0,0 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "platform/no_tsan.h"
namespace dart {
#if defined(__clang__)
#if defined(__has_feature)
#if __has_feature(thread_sanitizer)
#error Misconfigured build
#endif
#endif
uintptr_t FetchAndRelaxedIgnoreRace(std::atomic<uintptr_t>* ptr,
uintptr_t value) {
return ptr->fetch_and(value, std::memory_order_relaxed);
}
uintptr_t FetchOrRelaxedIgnoreRace(std::atomic<uintptr_t>* ptr,
uintptr_t value) {
return ptr->fetch_or(value, std::memory_order_relaxed);
}
uintptr_t LoadRelaxedIgnoreRace(const std::atomic<uintptr_t>* ptr) {
return ptr->load(std::memory_order_relaxed);
}
#endif // defined(__clang__)
} // namespace dart
+22 -17
View File
@@ -9,34 +9,39 @@
#include <atomic>
#include "platform/thread_sanitizer.h"
namespace dart {
#if defined(__clang__)
// Clang does not honor no_sanitize(thread) for std::atomic, so we place
// the implementation in a separate compilation unit with TSAN disabled.
uintptr_t FetchAndRelaxedIgnoreRace(std::atomic<uintptr_t>* ptr,
uintptr_t value);
uintptr_t FetchOrRelaxedIgnoreRace(std::atomic<uintptr_t>* ptr,
uintptr_t value);
uintptr_t LoadRelaxedIgnoreRace(const std::atomic<uintptr_t>* ptr);
#else
#if defined(__GNUC__)
__attribute__((no_sanitize("thread")))
#endif
// GCC will do what we want with no_sanitize("thread") and std::atomic, but for
// Clang will need to use disable_sanitizer_instrumentation and the atomic
// builtins.
NO_SANITIZE_THREAD DISABLE_SANITIZER_INSTRUMENTATION inline uintptr_t
FetchAndRelaxedIgnoreRace(std::atomic<uintptr_t>* ptr, uintptr_t value) {
return __atomic_fetch_and(reinterpret_cast<uintptr_t*>(ptr), value,
__ATOMIC_RELAXED);
}
NO_SANITIZE_THREAD DISABLE_SANITIZER_INSTRUMENTATION inline uintptr_t
FetchOrRelaxedIgnoreRace(std::atomic<uintptr_t>* ptr, uintptr_t value) {
return __atomic_fetch_or(reinterpret_cast<uintptr_t*>(ptr), value,
__ATOMIC_RELAXED);
}
NO_SANITIZE_THREAD DISABLE_SANITIZER_INSTRUMENTATION inline uintptr_t
LoadRelaxedIgnoreRace(const std::atomic<uintptr_t>* ptr) {
return __atomic_load_n(reinterpret_cast<const uintptr_t*>(ptr),
__ATOMIC_RELAXED);
}
#else
// MSVC doesn't support TSAN.
inline uintptr_t FetchAndRelaxedIgnoreRace(std::atomic<uintptr_t>* ptr,
uintptr_t value) {
return ptr->fetch_and(value, std::memory_order_relaxed);
}
#if defined(__GNUC__)
__attribute__((no_sanitize("thread")))
#endif
inline uintptr_t FetchOrRelaxedIgnoreRace(std::atomic<uintptr_t>* ptr,
uintptr_t value) {
return ptr->fetch_or(value, std::memory_order_relaxed);
}
#if defined(__GNUC__)
__attribute__((no_sanitize("thread")))
#endif
inline uintptr_t LoadRelaxedIgnoreRace(const std::atomic<uintptr_t>* ptr) {
return ptr->load(std::memory_order_relaxed);
}
+1
View File
@@ -21,6 +21,7 @@ platform_sources = [
"list_queue.h",
"lockers.h",
"memory_sanitizer.h",
"no_tsan.h",
"safe_stack.h",
"signal_blocker.h",
"synchronization.h",
+9 -1
View File
@@ -16,7 +16,14 @@
#endif
#if defined(USING_THREAD_SANITIZER)
#define NO_SANITIZE_THREAD __attribute__((no_sanitize("thread")))
#define NO_SANITIZE_THREAD __attribute__((no_sanitize_thread))
#if defined(__clang__)
#define DISABLE_SANITIZER_INSTRUMENTATION \
__attribute__((disable_sanitizer_instrumentation))
#else
#define DISABLE_SANITIZER_INSTRUMENTATION
#endif
extern "C" uint32_t __tsan_atomic32_load(uint32_t* addr, int order);
extern "C" void __tsan_atomic32_store(uint32_t* addr,
uint32_t value,
@@ -49,6 +56,7 @@ extern "C" void __tsan_func_entry(void* pc);
extern "C" void __tsan_func_exit();
#else
#define NO_SANITIZE_THREAD
#define DISABLE_SANITIZER_INSTRUMENTATION
#endif
#if defined(USING_THREAD_SANITIZER)
@@ -12,7 +12,7 @@ import "package:expect/expect.dart";
import '../dylib_utils.dart';
class Box {
@pragma("vm:no-sanitize-thread") // __attribute__((no_sanitize("thread")))
@pragma("vm:no-sanitize-thread") // __attribute__((no_sanitize_thread)))
int foo = 0;
}
@@ -5,6 +5,7 @@
#include "vm/globals.h"
#if defined(TARGET_ARCH_ARM64)
#include "platform/thread_sanitizer.h"
#include "vm/compiler/assembler/assembler.h"
#include "vm/compiler/assembler/assembler_test.h"
#include "vm/compiler/backend/locations.h"
+1
View File
@@ -8,6 +8,7 @@
#include <vector>
#include "platform/text_buffer.h"
#include "platform/thread_sanitizer.h"
#include "platform/utils.h"
#include "vm/class_id.h"
#include "vm/compiler/assembler/disassembler.h"
@@ -4,6 +4,7 @@
#include <vector>
#include "platform/thread_sanitizer.h"
#include "vm/compiler/backend/il.h"
#include "vm/compiler/backend/il_printer.h"
#include "vm/compiler/backend/il_test_helper.h"
+1
View File
@@ -4,6 +4,7 @@
#include "vm/compiler/jit/compiler.h"
#include "platform/assert.h"
#include "platform/thread_sanitizer.h"
#include "vm/class_finalizer.h"
#include "vm/code_patcher.h"
#include "vm/dart_api_impl.h"
+2
View File
@@ -6,6 +6,8 @@
#define RUNTIME_VM_FLAGS_H_
#include "platform/assert.h"
#include "platform/memory_sanitizer.h"
#include "platform/thread_sanitizer.h"
#include "vm/flag_list.h"
#include "vm/globals.h"
+1
View File
@@ -11,6 +11,7 @@
#include "platform/assert.h"
#include "platform/no_tsan.h"
#include "platform/thread_sanitizer.h"
#include "vm/class_finalizer.h"
#include "vm/dart_api_impl.h"
#include "vm/globals.h"
+1
View File
@@ -6,6 +6,7 @@
#include "platform/assert.h"
#include "platform/atomic.h"
#include "platform/thread_sanitizer.h"
#include "vm/allocation.h"
#include "vm/dart_api_state.h"
#include "vm/heap/gc_shared.h"
+1
View File
@@ -6,6 +6,7 @@
#define RUNTIME_VM_HEAP_POINTER_BLOCK_H_
#include "platform/assert.h"
#include "platform/memory_sanitizer.h"
#include "vm/globals.h"
#include "vm/os_thread.h"
#include "vm/tagged_pointer.h"
+1
View File
@@ -6,6 +6,7 @@
#include "platform/assert.h"
#include "platform/leak_sanitizer.h"
#include "platform/thread_sanitizer.h"
#include "vm/class_id.h"
#include "vm/compiler/runtime_api.h"
#include "vm/dart.h"
+1
View File
@@ -17,6 +17,7 @@
#include "platform/assert.h"
#include "platform/atomic.h"
#include "platform/growable_array.h"
#include "platform/thread_sanitizer.h"
#include "vm/class_table.h"
#include "vm/dispatch_table.h"
#include "vm/exceptions.h"
+4
View File
@@ -2846,6 +2846,10 @@ void Object::InitializeObject(uword address,
reinterpret_cast<UntaggedObject*>(address)->tags_ = tags;
#if defined(HOST_HAS_FAST_WRITE_WRITE_FENCE)
// GCC warns that TSAN doesn't understand thread fences.
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic ignored "-Wtsan"
#endif
std::atomic_thread_fence(std::memory_order_release);
#endif
}
+4
View File
@@ -11,6 +11,10 @@
#include "bin/vmservice_impl.h"
#include "platform/globals.h"
#include "platform/leak_sanitizer.h"
#include "platform/memory_sanitizer.h"
#include "platform/thread_sanitizer.h"
#include "platform/undefined_behavior_sanitizer.h"
#include "vm/class_finalizer.h"
#include "vm/closure_functions_cache.h"
+1
View File
@@ -23,6 +23,7 @@
#include <unistd.h> // NOLINT
#include "platform/memory_sanitizer.h"
#include "platform/thread_sanitizer.h"
#include "platform/utils.h"
#include "vm/code_comments.h"
#include "vm/code_observers.h"
+1
View File
@@ -6,6 +6,7 @@
#include "platform/address_sanitizer.h"
#include "platform/atomic.h"
#include "platform/memory_sanitizer.h"
#include "vm/lockers.h"
#include "vm/log.h"
#include "vm/thread_interrupter.h"
+1 -1
View File
@@ -5300,7 +5300,7 @@ extern "C" void __tsan_func_exit() {
}
#else
#define CASE(x) \
extern "C" __attribute__((disable_sanitizer_instrumentation)) void \
extern "C" NO_SANITIZE_THREAD DISABLE_SANITIZER_INSTRUMENTATION void \
jit_tsan_##x(void* addr) { \
__tsan_##x##_pc( \
addr, reinterpret_cast<void*>( \
+1 -1
View File
@@ -142,7 +142,7 @@ typedef void (*AddFrame)(void* ctxt,
// then symbolize using our normal PC descriptors, etc, but this function must
// not call any function that has been instrumented by TSAN or it might deadlock
// during __tsan_func_entry.
extern "C" __attribute__((disable_sanitizer_instrumentation)) void
extern "C" NO_SANITIZE_THREAD DISABLE_SANITIZER_INSTRUMENTATION void
__tsan_symbolize_external_ex(uintptr_t pc, AddFrame add_frame, void* ctxt) {
constexpr uintptr_t kExternalPCBit = 1ULL << 60;
const uword lookup_pc = pc & ~kExternalPCBit;