Skip to content

Recommendation for allocators when linking with C* binary #1238

Open
@keith

Description

@keith

When using rules_rust to link a rust library into a final C / C++ binary, you end up hitting some linker issues around missing allocator symbols:

Undefined symbols for architecture arm64:
  "___rust_alloc", referenced from:
      core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h2255888a02196d18 in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h8c8e34d5191bcf2c in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      alloc::raw_vec::finish_grow::hf9c3a7b5d277e764 in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      addr2line::Context$LT$R$GT$::find_frames::h2faede176ceedb5a in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      addr2line::ResDwarf$LT$R$GT$::parse::hde4e81cf26db861b in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      addr2line::ResUnit$LT$R$GT$::parse_lines::h989d285cff418912 in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      addr2line::ResUnit$LT$R$GT$::render_file::h057f5d698fb8b6fa in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      ...
  "___rust_alloc_error_handler", referenced from:
      alloc::alloc::handle_alloc_error::rt_error::h0566a1d251bd0a5b in liballoc-7e50779556d46264.a(alloc-7e50779556d46264.alloc.6069a24a-cgu.0.rcgu.o)
  "___rust_alloc_zeroed", referenced from:
      _$LT$std..sys..unix..fs..File$u20$as$u20$core..fmt..Debug$GT$::fmt::h858fd589f450b4fa in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
  "___rust_dealloc", referenced from:
      core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h5915480aa2f4d427 in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h8c8e34d5191bcf2c in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::he32668d17116d3cf in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      core::ptr::drop_in_place$LT$core..option..Option$LT$std..sys..unix..process..process_common..CStringArray$GT$$GT$::hc73bf8e1be5ce67e in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      core::ptr::drop_in_place$LT$alloc..collections..btree..map..BTreeMap$LT$u64$C$gimli..read..abbrev..Abbreviation$GT$$GT$::hd615d11dfc761993 in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      core::ptr::drop_in_place$LT$$LP$std..ffi..os_str..OsString$C$core..option..Option$LT$std..ffi..os_str..OsString$GT$$RP$$GT$::h53e782e9cd3898db in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      core::ptr::drop_in_place$LT$$LT$std..backtrace..Backtrace$u20$as$u20$core..fmt..Display$GT$..fmt..$u7b$$u7b$closure$u7d$$u7d$$GT$::h11130cb13523a05c in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      ...
  "___rust_realloc", referenced from:
      alloc::raw_vec::finish_grow::hf9c3a7b5d277e764 in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      addr2line::Context$LT$R$GT$::find_frames::h2faede176ceedb5a in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      addr2line::ResUnit$LT$R$GT$::parse_lines::h989d285cff418912 in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      std::env::current_dir::h829333952c66e8ad in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      std::ffi::c_str::CString::from_vec_unchecked::hc7adf6773960680b in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      std::ffi::c_str::CString::from_vec_with_nul_unchecked::h6cd7e60a1e34c996 in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      std::ffi::c_str::CString::from_vec_with_nul::he767a74f4ba7920f in libstd-eb660d415c354e23.a(std-eb660d415c354e23.std.dfe53c44-cgu.0.rcgu.o)
      ...

After reading some various issues it sounds like the core issue is that rust mostly expects to handle linking itself, and provides these manually during the final link, but when linking it into a C binary with bazel, we don't go through that logic and therefore end up missing these symbols.

This change 802bcf9 potentially improves this by allowing you to add a global allocator_library which can provide these symbols and solve this. But as far as I can tell that would currently require reproducing a lot of toolchain setup boilerplate, as well as a library containing the necessary symbols (one of which can be found here https://github.com/chromium/chromium/blob/42bd3d0802e90ca093450a2683ff2a104e10e48a/build/rust/std/remap_alloc.cc)

I'm hoping for some input on the best way to solve this, ideally for everyone, and ideally in rules_rust. One potential thing I could see working is defaulting the allocator library to a library in rules_rust containing something like chromium's solution. If that would be too invasive we could potentially expose the allocator_library attribute and pipe that through all the toolchain setup so users could specify one globally in their WORKSPACE without having to add too much boilerplate.

Please let me know what you think!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions