An alternative to macOS's DYLD_LIBRARY_PATH

In my last blog post about Traveling Ruby's future, I said that it's hard to democratize the development of Traveling Ruby because of System Integrity Protection (SIP). Traveling Ruby's build process relies on DYLD_LIBRARY_PATH, which is blocked by SIP. This means that:

  • Contributors that build Traveling Ruby on their own laptops, must disable SIP.
  • Traveling Ruby cannot be built on many CI hosting services, such as Azure DevOps and Github Actions, because it's not possible to disable SIP there.

After some research and experimentation, I've found an alternative to DYLD_LIBRARY_PATH, meaning that it's no longer necessary to disable SIP. This significantly changes the ability to democratize Traveling Ruby's development.

Read more »

The future of Traveling Ruby

A couple of years ago, I had a dream: to make it dead-easy to distribute Ruby CLI apps to end users, without requiring those users to install Ruby or muck about with gems and Bundler. And thus Traveling Ruby was born.

Traveling Ruby hasn't seen updates for quite a while now. Recently I tried making a new bugfix release, but I found it to be more challenging than I had hoped. In this article I reflect on those challenges, as well as on the future of Traveling Ruby.

Read more »

Why Ruby app servers break on macOS High Sierra and what can be done about it

People who have upgraded to macOS High Sierra and who are using a preforking app server such as Puma or Unicorn (with the right settings), may have noticed this error:

objc[81924]: +[__NSPlaceholderDictionary initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.

This cryptic error is triggered under the following conditions:

  1. You are using Unicorn with preload_app, or Puma in cluster mode, or iodine in prefork mode, or Passenger in smart spawning mode.
  2. And you are using MRI.
  3. And your application uses a gem that is either directly or indirectly linked to the macOS Foundation framework.

This error is caused by changes in how fork() behaves in High Sierra. This article covers:

  • What is this and why did Apple change it?
  • How are the Puma, Unicorn and Passenger authors responding to this?
  • What can you do about it, and do you need to do anything at all?
  • What should the wider Ruby ecosystem do?

Read more »