Skip to content

[Runtime] Scribble on metadata allocations. #32408

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions stdlib/public/runtime/EnvironmentVariables.def
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,7 @@ VARIABLE(SWIFT_ENABLE_MANGLED_NAME_VERIFICATION, bool, false,
"Enable verification that metadata can roundtrip through a mangled "
"name each time metadata is instantiated.")

VARIABLE(SWIFT_DEBUG_ENABLE_MALLOC_SCRIBBLE, bool, false,
"Scribble on runtime allocations such as metadata allocations.")

#undef VARIABLE
30 changes: 22 additions & 8 deletions stdlib/public/runtime/Metadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -662,11 +662,6 @@ swift::swift_allocateGenericValueMetadata(const ValueTypeDescriptor *description
auto bytes = (char*) cache.getAllocator().withTag(GenericValueMetadataTag)
.Allocate(totalSize, alignof(void*));

#ifndef NDEBUG
// Fill the metadata record with garbage.
memset(bytes, 0xAA, totalSize);
#endif

auto addressPoint = bytes + sizeof(ValueMetadata::HeaderType);
auto metadata = reinterpret_cast<ValueMetadata *>(addressPoint);

Expand Down Expand Up @@ -5547,6 +5542,21 @@ static void recordBacktrace(void *allocation) {
});
}

template <typename Pointee>
static inline void memsetScribble(Pointee *bytes, size_t totalSize) {
#ifndef NDEBUG
// When DEBUG is defined, always scribble.
memset(bytes, 0xAA, totalSize);
#else
// When DEBUG is not defined, only scribble when the
// SWIFT_DEBUG_ENABLE_MALLOC_SCRIBBLE environment variable is set.
if (SWIFT_UNLIKELY(
runtime::environment::SWIFT_DEBUG_ENABLE_MALLOC_SCRIBBLE())) {
memset(bytes, 0xAA, totalSize);
}
#endif
}

void *MetadataAllocator::Allocate(size_t size, size_t alignment) {
assert(Tag != 0);
assert(alignment <= alignof(void*));
Expand All @@ -5556,8 +5566,11 @@ void *MetadataAllocator::Allocate(size_t size, size_t alignment) {
SWIFT_ONCE_F(getenvToken, checkAllocatorDebugEnvironmentVariable, nullptr);

// If the size is larger than the maximum, just use malloc.
if (size > PoolRange::MaxPoolAllocationSize)
return malloc(size);
if (size > PoolRange::MaxPoolAllocationSize) {
void *allocation = malloc(size);
memsetScribble(allocation, size);
return allocation;
}

// Allocate out of the pool.
auto sizeWithHeader = size;
Expand Down Expand Up @@ -5601,7 +5614,8 @@ void *MetadataAllocator::Allocate(size_t size, size_t alignment) {
// If that succeeded, we've successfully allocated.
__msan_allocated_memory(allocation, sizeWithHeader);
__asan_unpoison_memory_region(allocation, sizeWithHeader);

memsetScribble(allocation, sizeWithHeader);

if (SWIFT_UNLIKELY(_swift_debug_metadataAllocationIterationEnabled)) {
AllocationHeader *header = (AllocationHeader *)allocation;
header->Size = size;
Expand Down
3 changes: 2 additions & 1 deletion test/Runtime/environment_variables.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// REQUIRES: executable_test
// UNSUPPORTED: use_os_stdlib

// RUN: env %env-SWIFT_DEBUG_HELP=YES %env-SWIFT_DEBUG_SOME_UNKNOWN_VARIABLE=42 %env-SWIFT_DEBUG_ENABLE_METADATA_ALLOCATION_ITERATION=YES %env-SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT=abc %env-SWIFT_DETERMINISTIC_HASHING=whatever %env-SWIFT_ENABLE_MANGLED_NAME_VERIFICATION=YES %target-run %t/main 2>&1 | %FileCheck %s --dump-input fail
// RUN: env %env-SWIFT_DEBUG_HELP=YES %env-SWIFT_DEBUG_SOME_UNKNOWN_VARIABLE=42 %env-SWIFT_DEBUG_ENABLE_METADATA_ALLOCATION_ITERATION=YES %env-SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT=abc %env-SWIFT_DETERMINISTIC_HASHING=whatever %env-SWIFT_ENABLE_MANGLED_NAME_VERIFICATION=YES %env-SWIFT_DEBUG_ENABLE_MALLOC_SCRIBBLE=YES %target-run %t/main 2>&1 | %FileCheck %s --dump-input fail

// CHECK-DAG: {{Warning: unknown environment variable SWIFT_DEBUG_SOME_UNKNOWN_VARIABLE|Using getenv to read variables. Unknown SWIFT_DEBUG_ variables will not be flagged.}}
// CHECK-DAG: Warning: cannot parse value SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT=abc, defaulting to 2.
Expand All @@ -15,6 +15,7 @@
// CHECK-DAG: uint8_t SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT [default: 2] - Print warnings when using implicit @objc entrypoints. Set to desired reporting level, 0-3.
// CHECK-DAG: bool SWIFT_DETERMINISTIC_HASHING [default: false] - Disable randomized hash seeding.
// CHECK-DAG: bool SWIFT_ENABLE_MANGLED_NAME_VERIFICATION [default: false] - Enable verification that metadata can roundtrip through a mangled name each time metadata is instantiated.
// CHECK-DAG: bool SWIFT_DEBUG_ENABLE_MALLOC_SCRIBBLE [default: false] - Scribble on runtime allocations such as metadata allocations.

print("Hello, world")
// CHECK: Hello, world
3 changes: 3 additions & 0 deletions test/lit.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -1912,6 +1912,9 @@ if config.lldb_build_root != "":
# variable.
config.environment[TARGET_ENV_PREFIX + 'SWIFT_DETERMINISTIC_HASHING'] = '1'

# Enable malloc scribble during tests by default.
config.environment[TARGET_ENV_PREFIX + 'SWIFT_DEBUG_ENABLE_MALLOC_SCRIBBLE'] = 'YES'

# Run lsb_release on the target to be tested and return the results.
def linux_get_lsb_release():
lsb_release_path = '/usr/bin/lsb_release'
Expand Down