Opened 2 years ago

Last modified 20 months ago

#64061 new defect

perl: posix_spawn: ${prefix}/var/macports/sip-workaround/502/usr/bin/perl5.xx: No such file or directory

Reported by: chrstphrchvz (Christopher Chavez) Owned by:
Priority: Normal Milestone:
Component: base Version: 2.7.1
Keywords: tracemode Cc: mascguy (Christopher Nielsen)
Port:

Description

Attempting to build ccache @4.5.1_0 +doc in trace mode with a clean installation of MacPorts 2.7.1 on Monterey 12.0.1 x86-64. The build fails with:

[  5%] Generating ccache.1
cd /opt/local/var/macports/build/_opt_local_var_macports_sources_github.com_macports_macports-ports_devel_ccache/ccache/work/build/doc && perl -pe 's!\\f\(CR(.*?)\\fP!\\fB\1\\fP!g'
ccache.1.tmp >ccache.1
perl: posix_spawn: /opt/local/var/macports/sip-workaround/502/usr/bin/perl5.30: No such file or directory
make[2]: *** [doc/ccache.1] Error 1

I found only a few reports of nearly identical perl: posix_spawn: ${prefix}/var/macports/sip-workaround/502/usr/bin/perl5.xx: No such file or directory errors for various ports and macOS versions (a mailing list post appears to be the deepest investigation into this issue so far): ticket:59924#comment:4 ticket:62104#comment:4 https://lists.macports.org/pipermail/macports-dev/2019-June/040820.html

From Ryan Schmidt (Fri Jun 7 04:07:19 UTC 2019):

I am assuming that MacPorts base copies these files to the sip-workaround directory when it thinks they are being used.

I note that macOS (High Sierra at least) ships with both /usr/bin/perl and /usr/bin/perl5.18. They are both version 5.18, their "-V" output is identical, yet the files have different sizes. I am uncertain why this is. I would have thought one would be a symlink or hard link to the other.

/usr/bin/perl is a small binary, whose purpose I would guess is to append a hardcoded version string it contains (e.g. "5.18" or "5.30" depending on macOS version) and use posix_spawn() to run the perl5.xx binary located in the same directory as itself. So if /usr/bin/perl5.xx hasn’t been copied to the sip-workaround directory before /usr/bin/perl is copied, this error will occur.

Because reports of this error are rare, I would guess that /usr/bin/perl5.xx tends to be copied to the sip-workaround directory long before /usr/bin/perl is ever needed from trace mode.

This error can be reproduced by removing ${prefix}/var/macports/sip-workaround/502/usr/bin/perl5.xx and running ${prefix}/var/macports/sip-workaround/502/usr/bin/perl (either directly or during a trace mode build of something needing it, e.g. ccache @4.5.1_0 +doc).

Change History (6)

comment:1 Changed 2 years ago by chrstphrchvz (Christopher Chavez)

A workaround for this error is to manually copy over the appropriate perl5.xx:

sudo -u macports cp /usr/bin/perl5.xx ${prefix}/var/macports/sip-workaround/502/usr/bin/perl5.xx
Last edited 2 years ago by chrstphrchvz (Christopher Chavez) (previous) (diff)

comment:2 Changed 2 years ago by ryandesign (Ryan Carsten Schmidt)

This situation sounds crappy and plausible. I guess what MacPorts base should do is special-case /usr/bin/perl, and if we're going to copy that to the sip-workaround directory, then we should also copy whatever perl5.xx it would run. Since that probably varies by OS version and determining which one it is is probably difficult, we could copy all perl5.xx. There may be other similar wrapper programs in /usr/bin for which we could apply a similar workaround.

comment:3 Changed 2 years ago by neverpanic (Clemens Lang)

This is weird. I'm guessing what's happening here is this:

  • We're copying /usr/bin/perl unmodified, only stripping the SIP flag
  • The binary retains Apple's signature, so our DYLD_INSERT_LIBRARIES environment variable that is set when executing the copy is ignored
  • The unmodified binary runs, which means the posix_spawn(2) invocation in that binary isn't traced by trace mode and the perl5.xx binary is thus not copied.

However, this also means that code that runs in this perl interpreter doesn't run under trace mode, either, and any binaries spawned from there would also not run under trace mode. I guess the proper solution for this would be to strip Apple's signature when copying the binary? On the other hand, that could cause problems for binaries in /usr/bin that only properly run with Apple's signature, e.g., because they use entitlements.

comment:4 Changed 2 years ago by neverpanic (Clemens Lang)

This could probably done with https://github.com/steakknife/unsign.

comment:5 Changed 2 years ago by neverpanic (Clemens Lang)

According to find /opt/local/var/macports/sip-workaround -type f -exec codesign -d --entitlements :- {} \; none of the files I have in my installation have entitlements, so stripping the signature may probably be the best approach here.

comment:6 Changed 20 months ago by mascguy (Christopher Nielsen)

Cc: mascguy added
Note: See TracTickets for help on using tickets.