Skip to content

Don't cache the value of _NSGetEnviron on macOS#290

Merged
rizsotto merged 1 commit intorizsotto:masterfrom
saagarjha:master
Jul 2, 2020
Merged

Don't cache the value of _NSGetEnviron on macOS#290
rizsotto merged 1 commit intorizsotto:masterfrom
saagarjha:master

Conversation

@saagarjha
Copy link
Copy Markdown
Contributor

This should fix #215, hopefully. I've tested this using bear --libear with the new libear.dylib (which was quite convenient, but I'm unsure if that was something I was supposed to use) on a couple of projects and it seems to work OK for most cases, whereas it didn't work at all before. I did run into one issue when trying to pass address sanitizer flags to ld but I'm unsure if that's a problem with Bear or this particular project's Makefile, so I'll try to double check that tomorrow.

This causes an issue with xcrun because its purpose is to set SDKROOT,
which causes environ to change internally and when it calls execv (which
we interpose) we continue to use the old value we copied at launch time
rather than the new value. This is how environ has been defined
internally for just about the last decade so hopefully this shouldn't be
too poor of a workaround.

Also, fix a couple of typos that I happened upon.
@rizsotto
Copy link
Copy Markdown
Owner

Hey @saagarjha , thanks for doing this.

I wish I would have some understanding what OSX is doing with the environment in the processes. (I've learnt that it's not available as environ at the process loading time, so that's why we need to call _NSGetEnviron(). But you are saying, to capture the returned pointer is also not safe.)

Do you know if it's okay to call getenv() during the library initialization time? Or you know some good document which describes these policies for OSX?

@saagarjha
Copy link
Copy Markdown
Contributor Author

The best I have is the man page for enivon(7):

PROGRAMMING
     Programs can query and modify the environment, using the environment rou-
     tines getenv(3), putenv(3), setenv(3) and unsetenv(3).  Direct access can
     be made through the global variable environ, though it is recommended
     that changes to the enviroment still be made through the environment rou-
     tines.

     Shared libraries and bundles don't have direct access to environ, which
     is only available to the loader ld(1) when a complete program is being
     linked.  The environment routines can still be used, but if direct access
     to environ is needed, the _NSGetEnviron() routine, defined in
     <crt_externs.h>, can be used to retrieve the address of environ at run-
     time.

which essentially seem to say that *env(3) functions are always available, as is _NSGetEnviron(). It's just environ that is not made available for the specific case of libraries while they are still being linked. Capturing the returned pointer is not correct even on Linux, I would assume, because adding a string to the environment could cause it to be reallocated somewhere else. (I believe macOS actually says it will keep the old values around, but again, that doesn't help us here.)

@rizsotto rizsotto merged commit 5072cd9 into rizsotto:master Jul 2, 2020
@wyuenho
Copy link
Copy Markdown

wyuenho commented Sep 9, 2020

Would be nice if we could get a release for this.

@rizsotto
Copy link
Copy Markdown
Owner

v2.4.4 is the release which has this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bear fails compilation in connection with apple's llvm 10

3 participants