From ce20207931d1c5eeeb1a1fbf3c88bc1534d02a98 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Mon, 21 Oct 2024 02:51:18 +0100 Subject: [PATCH] Fix symbol resolution for malloc_type functions on macOS Sequoia This commit addresses an issue with symbol resolution for malloc_type functions on the latest macOS Sequoia. The problem arises due to changes in how these functions are named in the dynamic symbol table of the system libraries that are part of the linker cache like the ones that contain the C++ runtime. This fix ensures that Memray correctly intercepts and tracks allocations made by malloc_type functions, fixing tracking allocations in the C++ runtime and other system libraries on macOS Sequoia. --- src/memray/_memray.pyx | 1 - src/memray/_memray/macho_shenanigans.cpp | 15 +++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/memray/_memray.pyx b/src/memray/_memray.pyx index 417f6f2657..aa41456c77 100644 --- a/src/memray/_memray.pyx +++ b/src/memray/_memray.pyx @@ -101,7 +101,6 @@ def set_log_level(int level): """ setLogThreshold(level) - cpdef enum AllocatorType: MALLOC = 1 FREE = 2 diff --git a/src/memray/_memray/macho_shenanigans.cpp b/src/memray/_memray/macho_shenanigans.cpp index fc310eb831..d47e67b23e 100644 --- a/src/memray/_memray/macho_shenanigans.cpp +++ b/src/memray/_memray/macho_shenanigans.cpp @@ -36,6 +36,15 @@ patch_symbol( } } +static inline const char* + get_canonical_name(const char* name) { + const char* prefix = "_malloc_type"; + if (strncmp(name, prefix, strlen(prefix)) != 0) { + return name; + } + return name + strlen(prefix); +} + static void patch_symbols_in_section( const section_t* section, @@ -49,8 +58,9 @@ patch_symbols_in_section( if (!symbol_name || !(symbol_name[0] == '_' || symbol_name[0] == '.') || !symbol_name[1]) { continue; } + const char* canonical_name = get_canonical_name(symbol_name); #define FOR_EACH_HOOKED_FUNCTION(hookname) \ - if (strcmp(MEMRAY_ORIG(hookname).d_symbol, symbol_name + 1) == 0) { \ + if (strcmp(MEMRAY_ORIG(hookname).d_symbol, canonical_name + 1) == 0) { \ LOG(DEBUG) << "Patching " << symbol_name << " symbol pointer at " << std::hex << std::showbase \ << *(symbol_addr_table + i) << " for relocation entry " << (symbol_addr_table + i); \ patch_symbol( \ @@ -225,9 +235,10 @@ patch_stubs( if (!symbol_name || !(symbol_name[0] == '_' || symbol_name[0] == '.') || !symbol_name[1]) { continue; } + const char* canonical_name = get_canonical_name(symbol_name); auto stub_addr = reinterpret_cast(symbol_addr_table + i * element_size); #define FOR_EACH_HOOKED_FUNCTION(hookname) \ - if (strcmp(MEMRAY_ORIG(hookname).d_symbol, symbol_name + 1) == 0) { \ + if (strcmp(MEMRAY_ORIG(hookname).d_symbol, canonical_name + 1) == 0) { \ LOG(DEBUG) << "Extracting symbol address for " << symbol_name << " from stub function at " \ << std::hex << std::showbase << stub_addr; \ void* symbol_addr = reinterpret_cast(lazy_pointer_from_stub(stub_addr)); \