Skip to content

Instantly share code, notes, and snippets.

@weissi
Last active January 9, 2022 09:57
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save weissi/7eefbfcbf546b0dd375de7b879593f64 to your computer and use it in GitHub Desktop.
Save weissi/7eefbfcbf546b0dd375de7b879593f64 to your computer and use it in GitHub Desktop.
dont free
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
#include <string.h>
#include <stdlib.h>
#include <malloc/malloc.h>
#include <stdio.h>
#ifndef __APPLE__
#error Sorry, currently only Apple platforms supported. This can be made to work on Linux/other UNIX too though.
#endif
#define DYLD_INTERPOSE(_replacement,_replacee) \
__attribute__((used)) static struct { const void *replacement; const void *replacee; } _interpose_##_replacee \
__attribute__ ((section("__DATA,__interpose"))) = { (const void *)(unsigned long)&_replacement, (const void *)(unsigned long)&_replacee };
__attribute__((constructor))
static void go(void) {
fprintf(stderr, "[[ DONT FREE is active, free() doesn't free anymore ]]\n");
}
void replacement_free(void *ptr) {
if (ptr) {
size_t size = malloc_size(ptr);
memset(ptr, 0x41, size);
}
}
void replacement_malloc_zone_free(malloc_zone_t *zone, void *ptr) {
replacement_free(ptr);
}
DYLD_INTERPOSE(replacement_free, free)
DYLD_INTERPOSE(replacement_malloc_zone_free, malloc_zone_free)
CFLAGS := -O2 -fPIC
test: libdontfree.dylib test.swift
swiftc -L. -ldontfree test.swift
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $^
libdontfree.dylib: dont-free.o
$(CC) $(LDFLAGS) -shared -o $@ $^
clean:
rm *.o *.dylib test
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
class Foo {}
var allAddrs: Set<UInt> = []
var iterations = 0
while true {
iterations += 1
let foo = Foo()
let addr = UInt(bitPattern: ObjectIdentifier(foo))
if !allAddrs.contains(addr) {
if CommandLine.arguments.dropFirst().first == "debug" {
print("0x", String(addr, radix: 16), separator: "")
}
allAddrs.formUnion([addr])
}
if iterations % 100000 == 0 {
let reused = iterations - allAddrs.count
print("After \(iterations) iterations, we saw \(reused) reused and \(iterations - reused) fresh addresses.")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment