Linker dies when using knuffel

I ran into something New And Existing™️. When I try to use knuffel to parse something, the linker vomits:

[---]
  = note: 0  0x106d34f43  __assert_rtn + 64
          1  0x106c8858d  ld::DynamicAtomFile::makeNamedAtom(std::__1::basic_string_view<char, std::__1::char_traits<char>>, ld::file_format::Scope, bool) + 653
          2  0x106c55f0c  ___ZNK2ld10InputFiles11SliceParser15parseObjectFileEPKN6mach_o6HeaderE_block_invoke.46 + 348
          3  0x106c50bfd  ld::InputFiles::SliceParser::parseObjectFile(mach_o::Header const*) const + 9453
          4  0x106c63b71  ld::InputFiles::parseAllFiles(void (ld::AtomFile const*) block_pointer)::$_7::operator()(unsigned long, ld::FileInfo const&) const + 657
          5  0x7ff8184d55cd  _dispatch_client_callout2 + 8
          6  0x7ff8184e5e3e  _dispatch_apply_invoke + 214
          7  0x7ff8184d559a  _dispatch_client_callout + 8
          8  0x7ff8184e499d  _dispatch_root_queue_drain + 879
          9  0x7ff8184e4f22  _dispatch_worker_thread2 + 152
          10  0x7ff818679c06  _pthread_wqthread + 262
          ld: Assertion failed: (name.size() <= maxLength), function makeSymbolStringInPlace, file SymbolString.cpp, line 74.
          clang: error: linker command failed with exit code 1 (use -v to see invocation)

That name.size() <= maxLength looks suspicious.

I encounter this on macOS/x64, using:

$ cc --version
Apple clang version 15.0.0 (clang-1500.0.40.1)
Target: x86_64-apple-darwin23.0.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

Can someone test this out to see if it reproducible on other systems (in particular other macOS systems). (You can use knuffel's own Route/Plugin example to trigger the problem).

I recall reading that Rust can produce very long symbol names in certain situations, but I don't recall this ever being mentioned as something that would kill linkers.

Exactly what steps are needed to reproduce the problem? I fail to see how there would be magic things with the linker.

It's simple (though unfortunately the example is a little broken, so it's not as simple as it could be):

  1. Create a new project: cargo new --vcs none --lib mytest
  2. Add knuffel = { version = "3.2.0" } to its Cargo.toml
  3. Copy'n'paste the first example from https://crates.io/crates/knuffel to main.rs (remove the default contents of it).
  4. Fixups: Remove the obviously-shouldn't-be-there #, remove main()'s return type, add an unwrap() and remove the final Ok(()).
  5. Run cargo build.

The build will (at least on my system) appear to hang, but after a second or it'll go boom with the message in my original post.

Everything works fine on a fresh github codespace with Ubuntu. But you can try building with this command, which will write debug information into a log file.

env RUSTC_LOG=rustc_codegen_ssa::back::link=info RUSTFLAGS="-C link-arg=-Wl,--verbose" cargo build > build.log

I've also done some relatively heavy knuffle usage on Windows recently (ironically, implementing a baby linker), so it seems to be at most Mac specific. That's unfortunate!

I read on the pkgsrc mailing list that the latest Xcode has a broken ld. Not sure if it is broken in a manner that explains what I'm seeing, but for now I'm going to assume it is.

Can verify that i'm encountering the same issue with knuffel on an ARM Mac where building a project using it would fail with the same error message (name.size() <= maxLength).

Seems like indeed it's new Xcode causing issues? i remember things were working for me on Ventura and this issue popped up when i upgraded to Sonoma. Anyways, replaced ld with lld as the linker and project builds fine now!

I'm also experiencing the same issue. I tried with the command-line developer tools and with XCode, same linker error.

I was able to work around this issue by using LLVM's lld linker. You can try it yourself:

  1. Acquire lld. I ran nix-shell -p lld.

  2. Add this to your project's .cargo/config.toml file (create it if you don't already have one):

    [target.aarch64-apple-darwin]
    rustflags = [
      "-C", "link-arg=-fuse-ld=lld",
    ]
    

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.