Bug #22401
closedaddr2line.c does not build when crt_externs.h is absent (iOS SDK)
Description
Ruby version: master (4.0.7)
addr2line.c includes <crt_externs.h> unconditionally. The build fails on
Darwin targets where that header is absent. The public iOS SDK does not
ship crt_externs.h.
Steps to reproduce¶
Configure Ruby for a Darwin target without crt_externs.h, then run make.
One example is a cross-compile for armv7-apple-ios6.0 against the iOS 6.1
SDK:
SDK=/path/to/iPhoneOS6.1.sdk
CC="clang -target armv7-apple-ios6.0 -isysroot $SDK" \
CPP="clang -target armv7-apple-ios6.0 -isysroot $SDK -E" \
../ruby/configure --host=armv7-apple-darwin10 --build=aarch64-apple-darwin25
make
Actual result¶
Expected result¶
addr2line.c compiles.
Cause¶
Three other files already handle this case: hash.c, eval_intern.h and
missing/setproctitle.c. They check HAVE_CRT_EXTERNS_H. When the header is
absent, they include missing/crt_externs.h instead. configure.ac sets that
macro for darwin targets. addr2line.c was missed.
addr2line.c also calls _NSGetMachExecuteHeader(). Only the macOS
crt_externs.h declares that function, so a fallback header alone is not
sufficient. The fix must also declare the function locally, with the same
LP64 distinction that crt_externs.h uses. The symbol itself exists in
libSystem/dyld on iOS too.
Proposed fix¶
Branch: https://github.com/DominikAlberski/ruby/tree/fix/addr2line-crt-externs-fallback
macOS behavior does not change. On macOS HAVE_CRT_EXTERNS_H is defined, so
the includes and the declarations stay the same. I verified this by
preprocessing both versions with HAVE_CRT_EXTERNS_H defined. The output is
identical, apart from the LINE numbers that the added lines shift.
A test is not possible for this change. The code path is a compile-time
header fallback, and macOS builds do not take it.
Updated by Anonymous 17 days ago
- Status changed from Open to Closed
Applied in changeset git|4f620ec5eeb9aa6724b06d74c523f8ef3ae13818.
[Bug #22401] addr2line.c: fall back to missing/crt_externs.h when the header is absent
The public iOS SDK does not ship crt_externs.h. addr2line.c included it
unconditionally and failed to compile:
hash.c, eval_intern.h and missing/setproctitle.c already handle this
case. They check HAVE_CRT_EXTERNS_H. When the header is absent, they
include missing/crt_externs.h instead. configure.ac sets that macro for
darwin targets, so the check works. addr2line.c was missed.
addr2line.c also calls _NSGetMachExecuteHeader(). Only the macOS
crt_externs.h declares that function. This commit declares it locally
when the header is absent. The declaration uses the LP() macro, which
selects mach_header or mach_header_64 for the pointer size. LP() was
defined inside fill_lines(), so this commit moves the definition to the
top of the file, next to the other Mach-O code. The symbol itself exists
in libSystem/dyld on iOS too.
macOS behavior does not change. On macOS HAVE_CRT_EXTERNS_H is defined,
so the includes and the declarations stay the same. The preprocessed
output is identical, apart from the LINE numbers that the added
lines shift. LP() is not used before its new position, so the move
changes no other code.