Skip to content

Commit 603f4e1

Browse files
committed
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.
1 parent f5eb8d7 commit 603f4e1

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

src/memray/_memray/macho_shenanigans.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,19 @@ patch_symbol(
3636
}
3737
}
3838

39+
static inline const char*
40+
get_canonical_name(const char* name)
41+
{
42+
// In macOS 15 (Sequoia)+, the symbols in the shared cache have a prefix
43+
// "_malloc_type" that we need to remove to match the symbols that we
44+
// are looking for.
45+
const char* prefix = "_malloc_type";
46+
if (strncmp(name, prefix, strlen(prefix)) != 0) {
47+
return name;
48+
}
49+
return name + strlen(prefix);
50+
}
51+
3952
static void
4053
patch_symbols_in_section(
4154
const section_t* section,
@@ -49,8 +62,9 @@ patch_symbols_in_section(
4962
if (!symbol_name || !(symbol_name[0] == '_' || symbol_name[0] == '.') || !symbol_name[1]) {
5063
continue;
5164
}
65+
const char* canonical_name = get_canonical_name(symbol_name);
5266
#define FOR_EACH_HOOKED_FUNCTION(hookname) \
53-
if (strcmp(MEMRAY_ORIG(hookname).d_symbol, symbol_name + 1) == 0) { \
67+
if (strcmp(MEMRAY_ORIG(hookname).d_symbol, canonical_name + 1) == 0) { \
5468
LOG(DEBUG) << "Patching " << symbol_name << " symbol pointer at " << std::hex << std::showbase \
5569
<< *(symbol_addr_table + i) << " for relocation entry " << (symbol_addr_table + i); \
5670
patch_symbol( \
@@ -225,9 +239,10 @@ patch_stubs(
225239
if (!symbol_name || !(symbol_name[0] == '_' || symbol_name[0] == '.') || !symbol_name[1]) {
226240
continue;
227241
}
242+
const char* canonical_name = get_canonical_name(symbol_name);
228243
auto stub_addr = reinterpret_cast<uint64_t>(symbol_addr_table + i * element_size);
229244
#define FOR_EACH_HOOKED_FUNCTION(hookname) \
230-
if (strcmp(MEMRAY_ORIG(hookname).d_symbol, symbol_name + 1) == 0) { \
245+
if (strcmp(MEMRAY_ORIG(hookname).d_symbol, canonical_name + 1) == 0) { \
231246
LOG(DEBUG) << "Extracting symbol address for " << symbol_name << " from stub function at " \
232247
<< std::hex << std::showbase << stub_addr; \
233248
void* symbol_addr = reinterpret_cast<void*>(lazy_pointer_from_stub(stub_addr)); \

0 commit comments

Comments
 (0)