mirror of
https://github.com/dart-lang/sdk
synced 2024-09-04 16:03:44 +00:00
[vm] Create builds for LeakSanitizer, MemorySanitizer and ThreadSanitizer.
Change-Id: I65905ec76fcde8b7f4063cb5b80a3d034b453153 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/120323 Commit-Queue: Ryan Macnak <rmacnak@google.com> Reviewed-by: Chinmay Garde <chinmaygarde@google.com> Reviewed-by: Siva Annamalai <asiva@google.com>
This commit is contained in:
parent
8c5236f55e
commit
d5feab0c53
|
@ -16,7 +16,7 @@ config("sdk") {
|
|||
"-Wl,--exclude-libs=libc++.a",
|
||||
]
|
||||
|
||||
if (is_asan) {
|
||||
if (is_asan || is_lsan || is_msan || is_tsan) {
|
||||
ldflags += [ "-lrt" ]
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ declare_args() {
|
|||
# Use libc++ (buildtools/third_party/libc++ and
|
||||
# buildtools/third_party/libc++abi) instead of stdlibc++ as standard library.
|
||||
# This is intended to be used for instrumented builds.
|
||||
use_custom_libcxx = (is_asan && is_linux) || is_tsan || is_msan
|
||||
use_custom_libcxx = (is_asan && is_linux) || is_lsan || is_msan || is_tsan
|
||||
|
||||
# Track where uninitialized memory originates from. From fastest to slowest:
|
||||
# 0 - no tracking, 1 - track only the initial allocation site, 2 - track the
|
||||
|
|
|
@ -186,6 +186,9 @@ config("dart_config") {
|
|||
if (defined(is_asan) && is_asan) {
|
||||
ldflags += [ "-fsanitize=address" ]
|
||||
}
|
||||
if (defined(is_lsan) && is_lsan) {
|
||||
ldflags += [ "-fsanitize=leak" ]
|
||||
}
|
||||
if (defined(is_msan) && is_msan) {
|
||||
ldflags += [ "-fsanitize=memory" ]
|
||||
}
|
||||
|
|
|
@ -11,16 +11,24 @@
|
|||
// told about areas that are initialized by generated code.
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(memory_sanitizer)
|
||||
extern "C" void __msan_poison(const volatile void*, size_t);
|
||||
extern "C" void __msan_unpoison(const volatile void*, size_t);
|
||||
#define MSAN_POISON(ptr, len) __msan_poison(ptr, len)
|
||||
#define MSAN_UNPOISON(ptr, len) __msan_unpoison(ptr, len)
|
||||
#define NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
|
||||
#else // __has_feature(memory_sanitizer)
|
||||
#define MSAN_POISON(ptr, len) \
|
||||
do { \
|
||||
} while (false && (ptr) == 0 && (len) == 0)
|
||||
#define MSAN_UNPOISON(ptr, len) \
|
||||
do { \
|
||||
} while (false && (ptr) == 0 && (len) == 0)
|
||||
#define NO_SANITIZE_MEMORY
|
||||
#endif // __has_feature(memory_sanitizer)
|
||||
#else // defined(__has_feature)
|
||||
#define MSAN_POISON(ptr, len) \
|
||||
do { \
|
||||
} while (false && (ptr) == 0 && (len) == 0)
|
||||
#define MSAN_UNPOISON(ptr, len) \
|
||||
do { \
|
||||
} while (false && (ptr) == 0 && (len) == 0)
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
// 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.
|
||||
|
||||
// Customize ASAN options for this test with 'allocator_may_return_null=1' as
|
||||
// it tries to allocate a large memory buffer.
|
||||
// Environment=ASAN_OPTIONS=handle_segv=0:detect_stack_use_after_return=1:allocator_may_return_null=1
|
||||
// Environment=MSAN_OPTIONS=handle_segv=0:detect_stack_use_after_return=1:allocator_may_return_null=1
|
||||
|
||||
// Test that ensures correct exception when running out of memory for
|
||||
// really large transferable.
|
||||
|
||||
|
|
|
@ -283,6 +283,10 @@ void HierarchyInfo::BuildRangesForJIT(ClassTable* table,
|
|||
|
||||
qsort(cids_array, cids.length(), sizeof(intptr_t),
|
||||
[](const void* a, const void* b) {
|
||||
// MSAN seems unaware of allocations inside qsort. The linker flag
|
||||
// -fsanitize=memory should give us a MSAN-aware version of libc...
|
||||
MSAN_UNPOISON(static_cast<const intptr_t*>(a), sizeof(intptr_t));
|
||||
MSAN_UNPOISON(static_cast<const intptr_t*>(b), sizeof(intptr_t));
|
||||
return static_cast<int>(*static_cast<const intptr_t*>(a) -
|
||||
*static_cast<const intptr_t*>(b));
|
||||
});
|
||||
|
|
|
@ -375,6 +375,8 @@ SemiSpace* SemiSpace::New(intptr_t size_in_words, const char* name) {
|
|||
#ifdef DEBUG
|
||||
result->reserved_->Protect(VirtualMemory::kReadWrite);
|
||||
#endif
|
||||
// Initialized by generated code.
|
||||
MSAN_UNPOISON(result->reserved_->address(), size_in_words << kWordSizeLog2);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -392,18 +394,21 @@ SemiSpace* SemiSpace::New(intptr_t size_in_words, const char* name) {
|
|||
#if defined(DEBUG)
|
||||
memset(memory->address(), Heap::kZapByte, size_in_bytes);
|
||||
#endif // defined(DEBUG)
|
||||
// Initialized by generated code.
|
||||
MSAN_UNPOISON(memory->address(), size_in_bytes);
|
||||
return new SemiSpace(memory);
|
||||
}
|
||||
}
|
||||
|
||||
void SemiSpace::Delete() {
|
||||
#ifdef DEBUG
|
||||
if (reserved_ != nullptr) {
|
||||
const intptr_t size_in_bytes = size_in_words() << kWordSizeLog2;
|
||||
#ifdef DEBUG
|
||||
memset(reserved_->address(), Heap::kZapByte, size_in_bytes);
|
||||
reserved_->Protect(VirtualMemory::kNoAccess);
|
||||
}
|
||||
#endif
|
||||
MSAN_POISON(reserved_->address(), size_in_bytes);
|
||||
}
|
||||
SemiSpace* old_cache = nullptr;
|
||||
{
|
||||
MutexLocker locker(mutex_);
|
||||
|
|
|
@ -263,7 +263,7 @@ class Interpreter {
|
|||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
bool is_debugging_;
|
||||
bool is_debugging_ = false;
|
||||
#endif // !PRODUCT
|
||||
|
||||
bool supports_unboxed_doubles_;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
// Customize ASAN options for this test with 'allocator_may_return_null=1' as
|
||||
// it tries to allocate a large memory buffer.
|
||||
// Environment=ASAN_OPTIONS=handle_segv=0:detect_stack_use_after_return=1:allocator_may_return_null=1
|
||||
// Environment=MSAN_OPTIONS=handle_segv=0:detect_stack_use_after_return=1:allocator_may_return_null=1
|
||||
|
||||
import "dart:io";
|
||||
|
||||
|
|
|
@ -285,6 +285,21 @@
|
|||
"builder-tag": "asan",
|
||||
"timeout": 240
|
||||
}},
|
||||
"dartk-lsan-(linux|mac|win)-(debug|product|release)-(ia32|x64)": {
|
||||
"options": {
|
||||
"builder-tag": "lsan",
|
||||
"timeout": 240
|
||||
}},
|
||||
"dartk-msan-(linux|mac|win)-(debug|product|release)-(ia32|x64)": {
|
||||
"options": {
|
||||
"builder-tag": "msan",
|
||||
"timeout": 240
|
||||
}},
|
||||
"dartk-tsan-(linux|mac|win)-(debug|product|release)-x64": {
|
||||
"options": {
|
||||
"builder-tag": "tsan",
|
||||
"timeout": 240
|
||||
}},
|
||||
"dart2js-(linux|mac|win)-chrome": {
|
||||
"options": {
|
||||
"use-sdk": true
|
||||
|
@ -788,7 +803,7 @@
|
|||
"arguments": ["runtime"],
|
||||
"environment": {
|
||||
"DART_USE_ASAN": 1,
|
||||
"ASAN_OPTIONS": "handle_segv=0:detect_leaks=1:detect_stack_use_after_return=0:disable_coredump=0",
|
||||
"ASAN_OPTIONS": "handle_segv=0:detect_leaks=1:detect_stack_use_after_return=0:disable_coredump=0:abort_on_error=1",
|
||||
"ASAN_SYMBOLIZER_PATH": "buildtools/linux-x64/clang/bin/llvm-symbolizer"
|
||||
}
|
||||
},
|
||||
|
@ -797,12 +812,101 @@
|
|||
"arguments": [
|
||||
"-ndartk-asan-linux-release-${arch}"],
|
||||
"environment": {
|
||||
"ASAN_OPTIONS": "handle_segv=0:detect_leaks=1:detect_stack_use_after_return=0:disable_coredump=0",
|
||||
"ASAN_OPTIONS": "handle_segv=0:detect_leaks=1:detect_stack_use_after_return=0:disable_coredump=0:abort_on_error=1",
|
||||
"ASAN_SYMBOLIZER_PATH": "buildtools/linux-x64/clang/bin/llvm-symbolizer"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"builders": [
|
||||
"vm-kernel-lsan-linux-release-ia32",
|
||||
"vm-kernel-lsan-linux-release-x64"
|
||||
],
|
||||
"meta": {
|
||||
"description": "This configuration is used by the vm builders with leak sanitizing (lsan). We have to run gn.py with the DART_USE_LSAN options, which we do by running generate_buildfiles."
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"name": "build dart",
|
||||
"script": "tools/build.py",
|
||||
"arguments": ["runtime"],
|
||||
"environment": {
|
||||
"DART_USE_LSAN": 1,
|
||||
"ASAN_OPTIONS": "handle_segv=0:detect_leaks=1:detect_stack_use_after_return=0:disable_coredump=0:abort_on_error=1",
|
||||
"ASAN_SYMBOLIZER_PATH": "buildtools/linux-x64/clang/bin/llvm-symbolizer"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vm tests",
|
||||
"arguments": [
|
||||
"-ndartk-lsan-linux-release-${arch}"],
|
||||
"environment": {
|
||||
"ASAN_OPTIONS": "handle_segv=0:detect_leaks=1:detect_stack_use_after_return=0:disable_coredump=0:abort_on_error=1",
|
||||
"ASAN_SYMBOLIZER_PATH": "buildtools/linux-x64/clang/bin/llvm-symbolizer"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"builders": [
|
||||
"vm-kernel-msan-linux-release-ia32",
|
||||
"vm-kernel-msan-linux-release-x64"
|
||||
],
|
||||
"meta": {
|
||||
"description": "This configuration is used by the vm builders with memory sanitizing (msan). We have to run gn.py with the DART_USE_MSAN options, which we do by running generate_buildfiles."
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"name": "build dart",
|
||||
"script": "tools/build.py",
|
||||
"arguments": ["runtime"],
|
||||
"environment": {
|
||||
"DART_USE_MSAN": 1,
|
||||
"MSAN_OPTIONS": "handle_segv=0:detect_leaks=1:detect_stack_use_after_return=0:disable_coredump=0:abort_on_error=1",
|
||||
"MSAN_SYMBOLIZER_PATH": "buildtools/linux-x64/clang/bin/llvm-symbolizer"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vm tests",
|
||||
"arguments": [
|
||||
"-ndartk-msan-linux-release-${arch}"],
|
||||
"environment": {
|
||||
"MSAN_OPTIONS": "handle_segv=0:detect_leaks=1:detect_stack_use_after_return=0:disable_coredump=0:abort_on_error=1",
|
||||
"MSAN_SYMBOLIZER_PATH": "buildtools/linux-x64/clang/bin/llvm-symbolizer"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"builders": [
|
||||
"vm-kernel-tsan-linux-release-x64"
|
||||
],
|
||||
"meta": {
|
||||
"description": "This configuration is used by the vm builders with thread sanitizing (tsan). We have to run gn.py with the DART_USE_TSAN options, which we do by running generate_buildfiles."
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"name": "build dart",
|
||||
"script": "tools/build.py",
|
||||
"arguments": ["runtime"],
|
||||
"environment": {
|
||||
"DART_USE_TSAN": 1,
|
||||
"TSAN_OPTIONS": "handle_segv=0:disable_coredump=0:abort_on_error=1",
|
||||
"TSAN_SYMBOLIZER_PATH": "buildtools/linux-x64/clang/bin/llvm-symbolizer"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vm tests",
|
||||
"arguments": [
|
||||
"-ndartk-tsan-linux-release-${arch}"],
|
||||
"environment": {
|
||||
"TSAN_OPTIONS": "handle_segv=0:disable_coredump=0:abort_on_error=1",
|
||||
"TSAN_SYMBOLIZER_PATH": "buildtools/linux-x64/clang/bin/llvm-symbolizer"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"builders": [
|
||||
"vm-kernel-linux-release-simarm",
|
||||
|
|
15
tools/gn.py
15
tools/gn.py
|
@ -20,6 +20,7 @@ GN = os.path.join(DART_ROOT, 'buildtools', 'gn')
|
|||
|
||||
# Environment variables for default settings.
|
||||
DART_USE_ASAN = "DART_USE_ASAN" # Use instead of --asan
|
||||
DART_USE_LSAN = "DART_USE_LSAN" # Use instead of --lsan
|
||||
DART_USE_MSAN = "DART_USE_MSAN" # Use instead of --msan
|
||||
DART_USE_TSAN = "DART_USE_TSAN" # Use instead of --tsan
|
||||
DART_USE_TOOLCHAIN = "DART_USE_TOOLCHAIN" # Use instread of --toolchain-prefix
|
||||
|
@ -35,6 +36,10 @@ def UseASAN():
|
|||
return DART_USE_ASAN in os.environ
|
||||
|
||||
|
||||
def UseLSAN():
|
||||
return DART_USE_LSAN in os.environ
|
||||
|
||||
|
||||
def UseMSAN():
|
||||
return DART_USE_MSAN in os.environ
|
||||
|
||||
|
@ -152,7 +157,7 @@ def ParseStringMap(key, string_map):
|
|||
|
||||
|
||||
def UseSanitizer(args):
|
||||
return args.asan or args.msan or args.tsan
|
||||
return args.asan or args.lsan or args.msan or args.tsan
|
||||
|
||||
|
||||
def DontUseClang(args, target_os, host_cpu, target_cpu):
|
||||
|
@ -249,6 +254,7 @@ def ToGnArgs(args, mode, arch, target_os, use_nnbd):
|
|||
gn_args['dart_vm_code_coverage'] = enable_code_coverage
|
||||
|
||||
gn_args['is_asan'] = args.asan and gn_args['is_clang']
|
||||
gn_args['is_lsan'] = args.lsan and gn_args['is_clang']
|
||||
gn_args['is_msan'] = args.msan and gn_args['is_clang']
|
||||
gn_args['is_tsan'] = args.tsan and gn_args['is_clang']
|
||||
|
||||
|
@ -460,6 +466,13 @@ def parse_args(args):
|
|||
default=False,
|
||||
dest='exclude_kernel_service',
|
||||
action='store_true')
|
||||
other_group.add_argument(
|
||||
'--lsan',
|
||||
help='Build with LSAN',
|
||||
default=UseLSAN(),
|
||||
action='store_true')
|
||||
other_group.add_argument(
|
||||
'--no-lsan', help='Disable LSAN', dest='lsan', action='store_false')
|
||||
other_group.add_argument(
|
||||
'--msan',
|
||||
help='Build with MSAN',
|
||||
|
|
Loading…
Reference in a new issue