24

For example, TeX Live Utility 1.17 and earlier will not work on Mac OS X 10.10 Yosemite. If a shell task relies on the PATH environment variable to launch a command, rather than a fully-specified path, it will likely fail. A typical error message will look like this:

/usr/texbin/updmap-sys: line 30: exec: updmap: not found

This can also occur in programs that launch pdflatex, dvipng, epstopdf, or other commands as part of a typesetting process.

  • 2
    Just a note that Apple has done this kind of thing before, and I would not even be sure they will think it is a bug. There was a whole mess with fork() a few years ago that broke all kind of programs, including, if I remember correctly, Adobe Reader. – Richard Heck Oct 22 '14 at 15:07
  • 1
    @RichardHeck I agree that Apple may not fix it, but since char **environ is part of POSIX, it's hard to see how they'd claim it's not a bug. Enforcing an exec after fork is the only recent issue I recall in this regard, but at least that had been documented for years beforehand. – Adam Maxwell Oct 22 '14 at 22:42
33

Background

There is a bug (or possibly multiple related bugs) in Yosemite with respect to environment variables. When a program is launched in Finder by double-clicking, it will inherit a default set of environment variables from its parent process (I believe this is launchd currently, but that's not relevant).

GUI programs do not inherit variables from ~/.bash_profile, ~/.bashrc or other shell init files.

TeX Live Utility allows the user to add TeX binaries to its internal (i.e., in-memory) PATH variable by means of a preference setting. Other programs may do via shell scripts, config files in the home directory, or other configuration mechanisms.

Problem

Traditionally, UNIX programs store environment variables in the global variable environ(7) (to see documentation, type man 7 environ in Terminal). Values in this C-array are generally changed with calls such as setenv(3) and read with getenv(3). Child processes launched with fork(2) and execv(3) will inherit the parent's environ variable, although some variants such as execve(2) allow passing a different set of environment variables.

When you call setenv("PATH", "/usr/texbin:/usr/bin:/usr/sbin", 1), it should replace the existing PATH=… value in the environment array. Under Yosemite, it appears to either append another PATH variable, or fail to modify environ at all. Consequently, even though getenv(3) may return a correct value, dereferencing the environ variable will return something with duplicate values or stale values…in other words, garbage.

Workaround

For TeX Live Utility, the workaround was to launch it from the Terminal as follows:

/Applications/TeX/TeX\ Live\ Utility.app/Contents/MacOS/TeX\ Live\ Utility

Note the backslashes to protect spaces in the program name; this is the actual binary, which resides inside the .app bundle. The same thing should work for other GUI programs, so please add a comment if it does or does not.

Caveats

  • This workaround may only work with the bash shell
  • This workaround will certainly only work if echo $PATH contains the path to your TeX binaries (for MacTeX, this is /usr/texbin)
  • If you're writing code, it appears that environ(7) is unusable now, and you need to build your own environment and pass it to execve(2) or execle(3)

Alternatives

This is clearly a bug, and Apple needs to fix this problem in Yosemite. TeX Live Utility 1.19 has a workaround that does not require launching from the Terminal, so I've used it here for illustrative purposes only. The Cocoa NSProcessInfo object can be used to get a seemingly correct environment, which can be modified and passed to NSTask. Note that NSProcessInfo is not thread-safe on all versions of OS X, and this workaround relies on Cocoa picking the "correct" environment variable.

Alternate workarounds may involve using launchctl to set environment variables. I do not recommend setting this up as a default except as a last resort; it modifies the environment for all programs you run, and can cause problems that are extremely difficult to debug in future (as Mac OS X's ~/.MacOSX/environment.plist used to do).

Inspired by @JoeCheng in the comments, I also wrote a plain C workaround, in the diff here. This should be a lowest-common-denominator for OS X.

Additional

More details and a link to an example Cocoa program to test this can be found here. Related problems can be found under the RStudio and Sublime-Text tags.

Any Cocoa program that uses NSTask (a wrapper object for fork/exec) to launch a shell or other script appears to be affected. This includes Python, for instance; the problem isn't limited to the C/Objective-C language, as far as I can tell. The problem was extremely difficult to debug as things work correctly when you launch from a debugger in Terminal, or launch under the debugger in Xcode. If I have made wrong inferences, that is a likely cause!

I filed a bug report with Apple, two months before Yosemite was released. The only feedback was a request that I describe how what I was seeing was unexpected. I'll update this if I hear anything further.

  • excellent explanation. It would be nice to link to the bug report (if there is one). Or perhaps Mac bug reports aren't public? That would be a shame. – scottkosty Oct 21 '14 at 5:21
  • 1
    Sadly, bug reports aren't public, since they may have confidential info and so forth. Apple claims that duplicate bug reports count as votes, though I have my doubts. – Adam Maxwell Oct 21 '14 at 5:35
  • 2
    Another work of "cutting edge technologies and innovation" by Apple. WTF, I am pushed to the edge and will never buy a Apple product again. Money has corrupted it to the root. – biocyberman Oct 23 '14 at 19:46
  • 2
    Hi, I'm with RStudio. Thanks Adam for such a great writeup, it was very helpful! We've spent a lot of time investigating this issue and have one additional piece of information that may help. It appears that under Yosemite, the GUI processes in question start with two PATH variables (and several others) in the environ block. setenv/getenv affect the first one that's found, but when child processes are launched, they inherit the last one (or at least not the first one--I've only tested cases where n=2). (continued...) – Joe Cheng Oct 27 '14 at 18:04
  • 3
    Until Apple fixes this issue (if they choose to at all) I believe the best workaround for apps like RStudio and Lyx is to immediately remove duplicate env variables at startup. Here's an implementation in C++. Once you've done this, everything is sane again. – Joe Cheng Oct 27 '14 at 18:05
0

An anonymous user edited my answer as follows:

It works for AlphaX, version 8.2.2; type: open -a AlphaX in your terminal.

I'm moving this to a separate answer, as this solution does not work for the problem as posed (for TeX Live Utility or other programs I've tested). If it does fix a problem for AlphaX, great.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.