Skip to content

Linker error because -wL as-needed conflicts with -C link-dead-code #64685

Open

Description

@xd009642

When a project has the [lib] tag in the Cargo.toml the -wL as-needed flag is added to the projects linker flags. However, if a project uses -C link-dead-code the two flags conflict causing a linker error of undefined reference for any functions in the lib.

This was discovered because link-dead-code is used for code coverage in tarpaulin. I spent some time seeing if there was a way around it as a user but I didn't manage to solve it myself. Issue that lead me to this for reference: xd009642/tarpaulin#126

Any solutions I could currently implement would be appreciated if this requires a PR I'm also happy to contribute (though may need some mentorship)

Activity

  1. added
    A-linkageArea: linking into static, shared libraries and binaries
    C-bugCategory: This is a bug.
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Sep 22, 2019
  2. xd009642 commented on Oct 9, 2019

    @xd009642
    ContributorAuthor

    Is there any idea about what it would take to fix this? I'm interested in helping out if someone can help guide me 😄

  3. sharksforarms commented on Apr 22, 2020

    @sharksforarms
    Contributor

    Getting a similar issue in suricata: https://github.com/OISF/suricata/tree/master/rust

    I tried removing the [lib] but still getting undefined symbols... I wonder if it's the extern C stuff

  4. richkadel commented on Aug 24, 2020

    @richkadel

    When compiling Rust binaries with -Z instrument-coverage and -C link-dead-code enabled, Rust binaries compiled for the Windows-MSVC target would typically crash (seg-fault) during the post-exit phase of writing the coverage-counter results to the *.profraw file (or at best, generate an empty file).

    After learning of this known bug, I discovered a workaround: Disabling link-dead-code, via -C link-dead-code=no, resolves the problem with -Z instrument-coverage when targeting Windows-MSVC. I'm incorporating this workaround in PR #75828 , but note that this does not actually correct the bug.

    It is an acceptable workaround for now, but I would prefer to enable link-dead-code, so dead code would still show up in the coverage reports (with zero execution counts).

    Before learning of this workaround, I did some extensive investigation of the bug with -Z instrument-coverage on MSVC. I've documented my discoveries and a lot of the intermediate results, in case they are helpful to someone with more knowledge in this area. I think I understand why the program fails (and how it appears to be a link-time issue), but I was not able to determine why the linker is doing what it is doing, or how to fix it.

  5. richkadel commented on Aug 28, 2020

    @richkadel

    After some sidebar discussions, I think the issue with -Z instrument-coverage and -C link-dead-code (which is only present when targeting MSVC and using the MSVC linker) is different. I've created a new bug report, Issue #76038 , and referenced this one, just in case someone sees a relationship.

  6. xd009642 commented on Nov 11, 2020

    @xd009642
    ContributorAuthor

    @jonas-schievink @richkadel Just tagging you both as you seem to be the two contributors who have interacted with this issue 😉

    I was considering attempting to tackle this one as it's been a proverbial thorn in my side for a while. As an approach I was considering looking for -wL as-needed when linking a dependency and then just not adding link-dead-code for that dependency. I know you can pass linker flags to just the crate you're compiling via cargo rustc so I figured this approach would naively work.

    Just wanted to make sure it made sense as an approach and there's no linker things I'm oblivious too and if so a vague pointer towards where in the rust code to look to figure it out would be appreciated 😄

  7. richkadel commented on Nov 12, 2020

    @richkadel

    I'm afraid I don't really have enough depth-of-knowledge here to be of much help.

  8. richkadel commented on Dec 3, 2020

    @richkadel

    A brief note for anyone reviewing this issue, as of PR #79109, -Z instrument-coverage no longer automatically enables -C link-dead-code.

    This issue is no longer relevant to LLVM source code coverage, but may still be relevant to other use cases of course.

  9. xd009642 commented on Dec 3, 2020

    @xd009642
    ContributorAuthor

    @richkadel won't that impact the accuracy of the LLVM code coverage then?

  10. richkadel commented on Dec 3, 2020

    @richkadel

    I implemented coverage for unused functions in a different way, which is actually more complete than anything I was getting from -C link-dead-code. The -C link-dead-code didn't help much before, and now it's redundant.

  11. xd009642 commented on Dec 3, 2020

    @xd009642
    ContributorAuthor

    Oh that's great! How does it tackle things like unused generic code? Will it cover them or only cover them if instantiated with a type somewhere?

  12. richkadel commented on Dec 3, 2020

    @richkadel

    Unused generics are covered too. Since I'm going back to MIR, the MIR is generated based on the parsed code, not used code, so I don't need it to be instantiated.

    That's one of the issues I was trying to solve with this new approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    -Clink-dead-codeLinkage option: -Clink-dead-codeA-linkageArea: linking into static, shared libraries and binariesC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions