Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor the linkage handling of libunwind #84040

Open
12101111 opened this issue Apr 9, 2021 · 5 comments
Open

Refactor the linkage handling of libunwind #84040

12101111 opened this issue Apr 9, 2021 · 5 comments
Labels
A-linkage Area: linking into static, shared libraries and binaries A-runtime Area: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows C-enhancement Category: An issue proposing an enhancement or a PR with one.

Comments

@12101111
Copy link
Contributor

12101111 commented Apr 9, 2021

libunwind currently need a c/cpp library that provide _Unwind_* symbols to work. libgcc_s.so/libgcc_eh.a from gcc or libunwind.so/libunwind.a from llvm can provide those symbols.

The libunwind crate is built when compiler bootstrap, and there is a flag in config.toml that choose which implementation to use. User can't change the implementation after bootstrap ( unless build-std add a flag for this )

# Use LLVM libunwind as the implementation for Rust's unwinder.
# Accepted values are 'in-tree' (formerly true), 'system' or 'no' (formerly false).
#llvm-libunwind = 'no'
  • in-tree will enable llvm-libunwind feature of libunwind
  • system will enable system-llvm-libunwind feature of libunwind
  • no won't enable any feature of libunwind

Ideally, the behavior of this flags would be:

  • in-tree will compile the intree copy of llvm-libunwind, and link it into libunwind.rlib
  • system will link the libunwind.so/libunwind.a from users' system
  • no will link the libgcc_s.so/libgcc_eh.a from users' system

But the current situation is a mess:

image

The probems are:

My suggestion:

@petrochenkov
Copy link
Contributor

  • in-tree will compile the intree copy of llvm-libunwind, and link it into libunwind.rlib

If this is implemented, then I suggest following the approach from #72274 ("Distribute libc.a as a separate library instead of bundling it into liblibc.rlib on musl and wasi") for the in-tree case.

@mati865
Copy link
Contributor

mati865 commented May 28, 2021

limit the llvm-libunwind=system option to linux only, as all other system only have one working unwind implementation. ( some changes to build.rs )

There is no such target for Rust yet but on Windows with mingw-w64 there are toolchains allowing switching between libgcc and libunwind, also there are even toolchains using libunwind exclusively.

@12101111
Copy link
Contributor Author

There is no such target for Rust yet but on Windows with mingw-w64 there are toolchains allowing switching between libgcc and libunwind, also there are even toolchains using libunwind exclusively.

Currently libgcc_s on windows_gnu is pulled in

let dynamic_unwind_libs = vec![
// If any of our crates are dynamically linked then we need to use
// the shared libgcc_s-dw2-1.dll. This is required to support
// unwinding across DLL boundaries.
"-lgcc_s".to_string(),
];
late_link_args_dynamic.insert(LinkerFlavor::Gcc, dynamic_unwind_libs.clone());
late_link_args_dynamic.insert(LinkerFlavor::Lld(LldFlavor::Ld), dynamic_unwind_libs);
let static_unwind_libs = vec![
// If all of our crates are statically linked then we can get away
// with statically linking the libgcc unwinding code. This allows
// binaries to be redistributed without the libgcc_s-dw2-1.dll
// dependency, but unfortunately break unwinding across DLL
// boundaries when unwinding across FFI boundaries.
"-lgcc_eh".to_string(),
"-l:libpthread.a".to_string(),
];
late_link_args_static.insert(LinkerFlavor::Gcc, static_unwind_libs.clone());
late_link_args_static.insert(LinkerFlavor::Lld(LldFlavor::Ld), static_unwind_libs);

It's possible to migrate the logic to libunwind

} else if target.contains("pc-windows-gnu") {
// This is handled in the target spec with late_link_args_[static|dynamic]
} else if target.contains("uwp-windows-gnu") {
println!("cargo:rustc-link-lib=unwind");

@mati865
Copy link
Contributor

mati865 commented May 28, 2021

Yeah, it was outlined in #72241 (comment) but I haven't got time to investigate it further.

@petrochenkov
Copy link
Contributor

Yeah, it was outlined in #72241 (comment) but I haven't got time to investigate it further.

This needs compiler support (evaluation of cfg predicates in #[link] attributes at link time instead of expansion time) which is in my work queue, but I never got to it either.

@workingjubilee workingjubilee added A-runtime Area: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows A-linkage Area: linking into static, shared libraries and binaries C-enhancement Category: An issue proposing an enhancement or a PR with one. labels Mar 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries A-runtime Area: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows C-enhancement Category: An issue proposing an enhancement or a PR with one.
Projects
None yet
Development

No branches or pull requests

4 participants