Loading...
#import "internal.h" #if CONFIG_QUARANTINE #import <dlfcn.h> #import <XCTest/XCTest.h> #define XCTAssertNotNull(ptr) XCTAssertNotEqual(ptr, NULL) @interface quarantine_tests : XCTestCase { @private malloc_zone_t *qzone; } @end @implementation quarantine_tests - (void)setUp { setenv("MallocQuarantineNoPoisoning", "1", 1); malloc_zone_t *szone = create_scalable_zone(0, 0); self->qzone = quarantine_create_zone(szone); } static void * memory_reader(task_t task, vm_address_t address, size_t size) { void *p = malloc(size); memcpy(p, address, size); return p; } // Exported so that the symbol name isn't stripped and can be looked up via dladdr. MALLOC_EXPORT MALLOC_NOINLINE void * _quarantine_test_allocationFunction(malloc_zone_t *qzone, size_t size) { void *p = malloc_zone_malloc(qzone, size); asm volatile (""); // disable tail-calling return p; } // Exported so that the symbol name isn't stripped and can be looked up via dladdr. MALLOC_EXPORT MALLOC_NOINLINE void _quarantine_test_deallocationFunction(malloc_zone_t *qzone, void *p) { malloc_zone_free(qzone, p); asm volatile (""); // disable tail-calling return; } - (void)testStacktraces { void *p = _quarantine_test_allocationFunction(qzone, 32); XCTAssertNotNull(p); _quarantine_test_deallocationFunction(qzone, p); quarantine_report_t report = {}; kern_return_t ret = quarantine_diagnose_fault_from_crash_reporter(p, &report, mach_task_self(), qzone, memory_reader); XCTAssertEqual(ret, KERN_SUCCESS); XCTAssertEqual(report.fault_address, (uintptr_t)p); XCTAssertEqual(report.nearest_allocation, (uintptr_t)p); XCTAssertEqual(report.allocation_size, 32); bool allocSiteFrameFound = false; for (int i = 0; i < report.alloc_trace.num_frames; i++) { Dl_info info = {}; dladdr(report.alloc_trace.frames[i], &info); NSLog(@"frame[%d] = %s", i, info.dli_sname); if ([@(info.dli_sname) isEqualTo:@"_quarantine_test_allocationFunction"]) { allocSiteFrameFound = true; break; } } XCTAssertTrue(allocSiteFrameFound); bool deallocSiteFrameFound = false; for (int i = 0; i < report.dealloc_trace.num_frames; i++) { Dl_info info = {}; dladdr(report.dealloc_trace.frames[i], &info); NSLog(@"frame[%d] = %s", i, info.dli_sname); if ([@(info.dli_sname) isEqualTo:@"_quarantine_test_deallocationFunction"]) { deallocSiteFrameFound = true; break; } } XCTAssertTrue(deallocSiteFrameFound); } @end #endif // CONFIG_QUARANTINE |