4

I am trying to build a simple HelloWorld application with stripped symbols. Compilation succeeds but when I try to execute it I get "Killed: 9" message (I am running MacOS).

compile command:

rustc main.rs -o main_stripped  -C strip=symbols

main.rs file:

fn main() {
    println!("Hello, world!");
}

Here is my environment information:

Rust

$ rustup show
Default host: aarch64-apple-darwin
rustup home:  /Users/<user>/.rustup

installed toolchains
--------------------

stable-aarch64-apple-darwin (default)
nightly-aarch64-apple-darwin

installed targets for active toolchain
--------------------------------------

aarch64-apple-darwin
wasm32-unknown-unknown

active toolchain
----------------

stable-aarch64-apple-darwin (default)
rustc 1.65.0 (897e37553 2022-11-02)

HW and OS

  • Model: MacBook Pro
  • Model Indentifier: MacBookPro18,2
  • Chip: Apple M1 Max
  • Total Number of Cores: 10 (8 performance and 2 efficiency)
  • System Version: macOS Ventura 13.0.1 (22A400)

What I tried so far...

dtrace/dtruss

received below output:

sudo dtruss ./main_stripped
dtrace: failed to execute ./main_stripped: Malformed Mach-o file

compile without stripping

rustc main.rs -o main

I am able to run main binary

inspect both binaries

$ file main_stripped
main_strip: Mach-O executable arm64
$ 
$ otool -h main_stripped
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedface 16777228          0  0x00           2    10       1440 0x00a00085
$ file main
main: Mach-O 64-bit executable arm64
$
$
$ otool -h main
main:
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           2    20       1960 0x00a00085
$

noticed a differences:

binary file magic
main_stripped Mach-O executable arm64 0xfeedface
main Mach-O 64-bit executable arm64 0xfeedfacf

According to mach-o/loader.h the magic 0xfeedface refers to 32-bit architecture.

So for some reason architecture has changed to 32-bit when using strip=symbols...

strip symbols using another command

tried strip command from GNU binutils 2.39 package

$ strip -v --strip-debug  -o main_stripped_2 main
copy from `main' [mach-o-arm64] to `main_stripped_2' [mach-o-arm64]

as a result I have received main_stripped_2 which had also incorrect 32-bit architecture..

$ file main_stripped_2
main_stripped_2: Mach-O executable arm64
$ 
$ otool -h main_stripped_2
main_stripped_2:
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedface 16777228          0  0x00           2    12       1544 0x00a00085

tried llvm-strip command from LLVM version 15.0.5

$ llvm-strip -s -o main_stripped_3  main

as a result I have received main_stripped_3 with correct 64-bit architecture and was able to run. However, I am not sure what can I do with this information to fix my problem.

$ file main_stripped_3
main_stripped_3: Mach-O 64-bit executable arm64

try another linker

Tried to used different linkers: zld or mold

rustc main.rs -o main_strip_mold  -C strip=debuginfo  -C link-arg=-fuse-ld=/opt/homebrew/bin/ld64.mold

again I have received binary in 32-bit architecture

$ file main_strip_mold
main_strip_mold: Mach-O executable arm64
$
$ otool -h main_strip_mold
main_strip_mold:
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedface 16777228          0  0x00           2    15       2104 0x00a00085

above steps work fine on another MacBook with below specs

  • Model: MacBook Pro
  • Model Indentifier: MacBookPro18,3
  • Chip: Apple M1 Pro
  • Total Number of Cores: 8 (6 performance and 2 efficiency)
  • System Version: macOS Monterey

What is different is chip and system version, but not sure if this is relevant to my problem.


Does anyone have a clue what could be the root cause of my problem and how to fix it?

rubinen
  • 51
  • 4

1 Answers1

1

Problem solved. Root cause was as follows.

PATH was including path to homebrew binutils before system binaries, which led to resolving strip to /opt/homebrew/opt/binutils/bin/strip instead of /usr/bin/strip

For some reason binutils don't work as expected.

rubinen
  • 51
  • 4