5

I've been struggling with a very weird issue. I'm trying to use libgmalloc (eg per man 3 libgmalloc) on Big Sur (I'm on 11.3.1) to trouble shoot a memory issue in my code. However, I can't set the environment variable DYLD_INSERT_LIBRARIES. It sets as a shell variable, but not as an environment variable that can be seen by child processes:

stuarts@iMac-Pro ~ % export DYLD_INSERT_LIBRARIES="/usr/lib/libgmalloc.dylib"
stuarts@iMac-Pro ~ % echo $DYLD_INSERT_LIBRARIES
/usr/lib/libgmalloc.dylib
stuarts@iMac-Pro ~ % env |grep DYLD_INSERT_LIBRARIES
stuarts@iMac-Pro ~ % 

The variable doesn't show up in the env listing (and isn't detected by my program using getenv() either). I started fooling around setting other randomly named variables, and found that I can export "DYLD" and "A_B", but not "DYLD_A" (or other things that start with "DYLD_").

This seems an extremely strange silent filter in export.

How should one use libgmalloc in Big Sur?

3
  • 1
    You might be better off rebuilding the app with the malloc library
    – mmmmmm
    Commented May 26, 2021 at 15:08
  • 1
    Yeah, using -lgmalloc in my Makefile works. Commented May 26, 2021 at 15:49
  • Is SIP turned on? If so, try again with it off. Commented May 26, 2021 at 16:38

4 Answers 4

3

Given the security features identified in @negacao's answer, the injection of libgmalloc via environment variable is very fragile (it works directly off the command line, but doesn't work when invoked via scripts, or within the debugger).

Instead, building the application with -lgmalloc in the Makefile worked well both from the command line and in the debugger (as hinted at in the comment from @mmmmmm) and I was able to find my bug in the debugger this way.

Apple needs to update the libgmalloc man page.

3
  • Note the flags are not set in the shell but in the debugger in the man page example
    – mmmmmm
    Commented May 26, 2021 at 16:03
  • I disagree with that - it pretty clearly documents first setting the environment variable and then running the program "This tells dyld to use Guard Malloc instead of the standard version of malloc.". IME if you set the environment variable and then run the debugger, the environment variable has disappeared (I log the result of getenv("DYLD_INSERT_LIBRARIES")). Commented May 26, 2021 at 16:07
  • I agree the wording is bad. All the examples say it is working with the debugger,an settinging it insde the debugger run.
    – mmmmmm
    Commented May 26, 2021 at 16:12
2

On my (M1) machine:

~$ export DYLD_INSERT_LIBRARIES=foo
~$ env | grep DYLD_INSERT_LIBRARIES
~$ /opt/homebrew/bin/bash
dyld: could not load inserted library 'foo' because image not found

Abort trap: 6

So (as you saw), the variable is being set - but since env is a system binary, it is silently removed. Testing with my homebrew installed version of bash, you can see the value is actually set.

See also this StackOverflow answer.

TL;DR works fine for non-system binaries, silently removed from the environment for system binaries.

2
  • 1
    Well it works for some non-system binaries - those binarioes can tuen the entitlement to load this off.
    – mmmmmm
    Commented May 26, 2021 at 15:07
  • Ok, I can confirm that when I run my program directly off the command line, it sees the environment variable and I get guard malloc messages. I was previously running it from a Perl test script (which would invoke the shell via system) and so the environment variable was silently filtered as you suggest. Commented May 26, 2021 at 15:09
0

DYLD_INSERT_LIBRARIES for system binaries requires disabling SIP. However, for processes that use Library Validation, the injection is impossible at all (e. g. it's impossible to inject into xcodebuild, but it's injected into its child processes such as clang).

-1

install jemalloc

brew install jemalloc

find it

$ tree /usr/local/Cellar/jemalloc/5.2.1_1/lib

/usr/local/Cellar/jemalloc/5.2.1_1/lib
├── libjemalloc.2.dylib
├── libjemalloc.a
├── libjemalloc.dylib -> libjemalloc.2.dylib
├── libjemalloc_pic.a
└── pkgconfig
    └── jemalloc.pc

use it

export DYLD_INSERT_LIBRARIES=/usr/local/Cellar/jemalloc/5.2.1_1/lib/libjemalloc.dylib

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .