vagrant-dns: macOS 13.x Ventura, daemon crashes on start

When starting the daemon on macOS 13.0 Beta Ventura the daemon appears to crash on startup,

The following log lines are output:

objc[15801]: +[NSPlaceholderMutableString initialize] may have been in progress in another thread when fork() was called. objc[15801]: +[NSPlaceholderMutableString 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.

Running the service in the foreground with: vagrant dns --start --ontop Runs fine as a workaround, no errors logged.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 1
  • Comments: 21 (14 by maintainers)

Commits related to this issue

Most upvoted comments

Merged the work-around and released as 2.2.3

This seems to be something happening every now and then with stuff that usually works well under linux but doesn’t like macOS in that regard. If it’s the same issue it isn’t limited to macOS 13.0 either.

See https://github.com/ansible/ansible/issues/49207 for example for details, but the gist is trying to export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES in your shell before you execute the crashing commands.

The quick and dirty way would be to directly apply the patch: curl -s https://patch-diff.githubusercontent.com/raw/BerlinVagrant/vagrant-dns/pull/73.patch | (cd ~/.vagrant.d/gems/2.7.6/gems/vagrant-dns-2.2.2; git apply)

Or, you could clone this repo, checkout the 72-workaround-darwin22-crash branch, and build it (requires a working ruby 2.7 installation):

$ bundle install
$ bundle exec rake build
$ vagrant plugin install ./pkg/vagrant-dns-2.2.3.pre.dev1.gem

It’s all pretty weird. It also seems to have something to do with XCode 14.

Here’s a small sample script that runs just fine with a fresh install of ruby 2.7.7:

gem install daemons

# try_fork_daemons.rb
require 'daemons'
opts = {
  ARGV: ARGV,
  dir_mode: :normal,
  dir: __dir__,
  log_output: true,
  log_dir: __dir__,
  backtrace: true,
  multiple: false
}

puts "script start"
Daemons.run_proc("try_fork_daemons", opts) do
  begin
    require "not-there"
  rescue LoadError
    puts "Ignore LoadError"
  end
  puts "new pid #{Process.pid}"
  loop { sleep 1 }
end
$ ruby -v try_fork_daemons.rb start
ruby 2.7.7p221 (2022-11-24 revision 36cadad643) [x86_64-darwin22]
script start
try_fork_daemons: process with pid 73355 started.
$ ruby -v try_fork_daemons.rb status
ruby 2.7.7p221 (2022-11-24 revision 36cadad643) [x86_64-darwin22]
script start
try_fork_daemons: running [pid 73355]

Runing with Vagrants Ruby

Using the daemons gem installed in vagrants gemdir (as a dependency of vagrant-dns):

$LOAD_PATH.unshift(File.join(ENV["HOME"], ".vagrant.d/gems/2.7.6/gems/daemons-1.4.1/lib"))

# ... the rest of the original try_fork_daemons.rb
$ GEMRC=/opt/vagrant/embedded/etc/gemrc GEM_HOME=/opt/vagrant/embedded/gems/2.3.4 RUBYOPT= GEM_PATH=/opt/vagrant/embedded/gems/2.3.4 RUBYLIB= /opt/vagrant/embedded/bin/ruby try_fork_daemons.rb start
script start
try_fork_daemons: process with pid 74269 started.

No luck:

$ ps -p 74269
  PID TTY           TIME CMD

Using inline bundler:

require 'bundler/inline'
gemfile(true) do
  source 'https://rubygems.org'
  gem 'daemons'
end

# ... the rest of the original try_fork_daemons.rb
$ GEMRC=/opt/vagrant/embedded/etc/gemrc GEM_HOME=/opt/vagrant/embedded/gems/2.3.4 RUBYOPT= GEM_PATH=/opt/vagrant/embedded/gems/2.3.4 RUBYLIB= /opt/vagrant/embedded/bin/ruby try_fork_daemons.rb start
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Using bundler 2.1.4
Using daemons 1.4.1
Following files may not be writable, so sudo is needed:
  /opt/vagrant/embedded/gems/2.3.4
  /opt/vagrant/embedded/gems/2.3.4/bin
  /opt/vagrant/embedded/gems/2.3.4/bin
  /opt/vagrant/embedded/gems/2.3.4/build_info
  /opt/vagrant/embedded/gems/2.3.4/cache
  /opt/vagrant/embedded/gems/2.3.4/doc
  /opt/vagrant/embedded/gems/2.3.4/extensions
  /opt/vagrant/embedded/gems/2.3.4/gems
  /opt/vagrant/embedded/gems/2.3.4/specifications
script start
try_fork_daemons: process with pid 74530 started.

This works:

$ ps -p 74530
  PID TTY           TIME CMD
74530 ??         0:00.05 try_fork_daemons

I’ve no idea what’s really going on and what’s the best approach to actually fixing it.
I still believe, that it would be nice if Vagrant could update ruby to 2.7.7 (see https://bugs.ruby-lang.org/issues/19005 and https://bugs.ruby-lang.org/issues/18912) and maybe even ship a different ruby for Ventura/XCode 14?

There’s one hot-fix we could do in vagrant-dns:

In https://github.com/BerlinVagrant/vagrant-dns/blob/master/lib/vagrant-dns/service.rb#L30-L32, when we move the require statements before the daemonized block, so that everything is loaded in the parent process already.

@mpdude Yes, I was working on an issue but wanted to get a testable script first.

Finally updated to Ventura. Tested in development with a fresh install of ruby 2.7.6 (ruby-install ruby 2.7.6 -- --enable-shared) and that one works. So I believe the ruby Vagrants ships is not good on Ventura:

/opt/vagrant/embedded/bin/ruby -v
ruby 2.7.6p219 (2022-04-12 revision c9c2245c0a) [x86_64-darwin19]

versus

ruby -v
ruby 2.7.6p219 (2022-04-12 revision c9c2245c0a) [x86_64-darwin22]