Skip to content

Commit 0365981

Browse files
committed
[Runtime] Scribble on metadata allocations.
Previously, when NDEBUG was not defined, the allocations made for value metadata records were filled with 0xAA bytes. Here, that behavior is both expanded to all metadata records and enabled in release builds when the environment variable SWIFT_DEBUG_ENABLE_MALLOC_SCRIBBLE is set.
1 parent 8cb1331 commit 0365981

File tree

3 files changed

+27
-9
lines changed

3 files changed

+27
-9
lines changed

stdlib/public/runtime/EnvironmentVariables.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,7 @@ VARIABLE(SWIFT_ENABLE_MANGLED_NAME_VERIFICATION, bool, false,
4141
"Enable verification that metadata can roundtrip through a mangled "
4242
"name each time metadata is instantiated.")
4343

44+
VARIABLE(SWIFT_DEBUG_ENABLE_MALLOC_SCRIBBLE, bool, false,
45+
"Scribble on runtime allocations such as metadata allocations.")
46+
4447
#undef VARIABLE

stdlib/public/runtime/Metadata.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -662,11 +662,6 @@ swift::swift_allocateGenericValueMetadata(const ValueTypeDescriptor *description
662662
auto bytes = (char*) cache.getAllocator().withTag(GenericValueMetadataTag)
663663
.Allocate(totalSize, alignof(void*));
664664

665-
#ifndef NDEBUG
666-
// Fill the metadata record with garbage.
667-
memset(bytes, 0xAA, totalSize);
668-
#endif
669-
670665
auto addressPoint = bytes + sizeof(ValueMetadata::HeaderType);
671666
auto metadata = reinterpret_cast<ValueMetadata *>(addressPoint);
672667

@@ -5547,6 +5542,21 @@ static void recordBacktrace(void *allocation) {
55475542
});
55485543
}
55495544

5545+
template <typename Pointee>
5546+
static inline void memsetScribble(Pointee *bytes, size_t totalSize) {
5547+
#ifndef NDEBUG
5548+
// When DEBUG is defined, always scribble.
5549+
memset(bytes, 0xAA, totalSize);
5550+
#else
5551+
// When DEBUG is not defined, only scribble when the
5552+
// SWIFT_DEBUG_ENABLE_MALLOC_SCRIBBLE environment variable is set.
5553+
if (SWIFT_UNLIKELY(
5554+
runtime::environment::SWIFT_DEBUG_ENABLE_MALLOC_SCRIBBLE())) {
5555+
memset(bytes, 0xAA, totalSize);
5556+
}
5557+
#endif
5558+
}
5559+
55505560
void *MetadataAllocator::Allocate(size_t size, size_t alignment) {
55515561
assert(Tag != 0);
55525562
assert(alignment <= alignof(void*));
@@ -5556,8 +5566,11 @@ void *MetadataAllocator::Allocate(size_t size, size_t alignment) {
55565566
SWIFT_ONCE_F(getenvToken, checkAllocatorDebugEnvironmentVariable, nullptr);
55575567

55585568
// If the size is larger than the maximum, just use malloc.
5559-
if (size > PoolRange::MaxPoolAllocationSize)
5560-
return malloc(size);
5569+
if (size > PoolRange::MaxPoolAllocationSize) {
5570+
void *allocation = malloc(size);
5571+
memsetScribble(allocation, size);
5572+
return allocation;
5573+
}
55615574

55625575
// Allocate out of the pool.
55635576
auto sizeWithHeader = size;
@@ -5601,7 +5614,8 @@ void *MetadataAllocator::Allocate(size_t size, size_t alignment) {
56015614
// If that succeeded, we've successfully allocated.
56025615
__msan_allocated_memory(allocation, sizeWithHeader);
56035616
__asan_unpoison_memory_region(allocation, sizeWithHeader);
5604-
5617+
memsetScribble(allocation, sizeWithHeader);
5618+
56055619
if (SWIFT_UNLIKELY(_swift_debug_metadataAllocationIterationEnabled)) {
56065620
AllocationHeader *header = (AllocationHeader *)allocation;
56075621
header->Size = size;

test/Runtime/environment_variables.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// REQUIRES: executable_test
66
// UNSUPPORTED: use_os_stdlib
77

8-
// 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
8+
// 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
99

1010
// CHECK-DAG: {{Warning: unknown environment variable SWIFT_DEBUG_SOME_UNKNOWN_VARIABLE|Using getenv to read variables. Unknown SWIFT_DEBUG_ variables will not be flagged.}}
1111
// CHECK-DAG: Warning: cannot parse value SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT=abc, defaulting to 2.
@@ -15,6 +15,7 @@
1515
// 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.
1616
// CHECK-DAG: bool SWIFT_DETERMINISTIC_HASHING [default: false] - Disable randomized hash seeding.
1717
// 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.
18+
// CHECK-DAG: bool SWIFT_DEBUG_ENABLE_MALLOC_SCRIBBLE [default: false] - Scribble on runtime allocations such as metadata allocations.
1819

1920
print("Hello, world")
2021
// CHECK: Hello, world

0 commit comments

Comments
 (0)