Skip to content

Rust 1.83.0 Sync with dyn Traits Regression #134014

Not planned
@IGN-Styly

Description

@IGN-Styly

Code

Problematic Version: rustc 1.83.0 (90b35a6 2024-11-26)
Works on rust rustc 1.82.0 (f6e511e 2024-10-15)

Using my lib, here's a short example causing the segfault.
Issue Demo Requires Submodule!
SegFault

Thread 1 "server" received signal SIGSEGV, Segmentation fault.
alloc::sync::{impl#29}::deref<dyn enginelib::event::EventHandler, alloc::alloc::Global> (self=0x555555d77db0)
    at /home/styly/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/sync.rs:2179
2179	        &self.inner().data

Rust 1.83 seems just leak. #128778 may be the cause but i can't seem to compile rust at all.

Activity

added
C-bugCategory: This is a bug.
regression-untriagedUntriaged performance or correctness regression.
on Dec 7, 2024
added
I-prioritizeIssue: Indicates that prioritization has been requested for this issue.
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Dec 7, 2024
compiler-errors

compiler-errors commented on Dec 7, 2024

@compiler-errors
Member

What is the regression here? I don't think you mentioned what the problem actually is.

IGN-Styly

IGN-Styly commented on Dec 7, 2024

@IGN-Styly
Author

Compilation happens fine but on execution a segfault happens, which didn't happen on previous versions. My bets are on: #128778 i am currently testing.

IGN-Styly

IGN-Styly commented on Dec 8, 2024

@IGN-Styly
Author

@compiler-errors I Just made my lib oss, and updated issue to have code to recreate the bug.

apiraino

apiraino commented on Dec 9, 2024

@apiraino
Contributor

@IGN-Styly can you please update your report adding how do you build your library. That would help in reproducing more quickly the issue. Thank you.

jieyouxu

jieyouxu commented on Dec 9, 2024

@jieyouxu
Member

More specifically, can you also make your example self-contained, e.g. in a repo, so that we can confirm what we try to run is the same as what you try to run?

added
S-needs-reproStatus: This issue has no reproduction and needs a reproduction to make progress.
S-needs-infoStatus: The issue lacks details necessary to triage or act on it.
on Dec 9, 2024
IGN-Styly

IGN-Styly commented on Dec 9, 2024

@IGN-Styly
Author

yes will do asap

IGN-Styly

IGN-Styly commented on Dec 9, 2024

@IGN-Styly
Author

Have Updated to include a repo to easily recreate the bug.

cyrgani

cyrgani commented on Dec 9, 2024

@cyrgani
Contributor

Can reproduce, working on minimizing this.

@rustbot label: -S-needs-repro -S-needs-info

removed
S-needs-reproStatus: This issue has no reproduction and needs a reproduction to make progress.
on Dec 9, 2024

3 remaining items

cyrgani

cyrgani commented on Dec 9, 2024

@cyrgani
Contributor

https://github.com/cyrgani/issue-134014 is a reduction that still keeps the original behavior of not segfaulting on 1.82 but on 1.83 and needs no external crates. However, removing the simple println!("cursed"); line in the repro causes it to segfault on 1.82 as well.

Additionally interesting is that the original unmodified code segfaults on 1.80 and below too, but not on 1.81.

IGN-Styly

IGN-Styly commented on Dec 10, 2024

@IGN-Styly
Author

is it haunted?( i know my code is shitty but i haven't found a better solution) might be lifetime related, and if you dont mind ill add the minimized repro into the inial repo.

added
E-needs-bisectionCall for participation: This issue needs bisection: https://github.com/rust-lang/cargo-bisect-rustc
on Dec 10, 2024
workingjubilee

workingjubilee commented on Dec 10, 2024

@workingjubilee
Member

I am removing the regression status because based on @cyrgani's report it seems very likely that what happened here is difficult to classify as a regression.

removed
I-prioritizeIssue: Indicates that prioritization has been requested for this issue.
regression-untriagedUntriaged performance or correctness regression.
on Dec 10, 2024
lukas-code

lukas-code commented on Dec 10, 2024

@lukas-code
Member

@cyrgani's minimal repro from #134014 (comment) has UB by reading from a vtable that is located in a dynamic library that has been dynamically unloaded.

The reduced example looks roughly like this:

      enginelib
      /       \
 engine       engine_core

where enginelib is a library that has a trait impl

pub trait Task {}
pub struct FibTask {}
impl Task for FibTask {}

engine_core is a dynamic library that exports a function like this:

#[no_mangle]
pub fn run(api: &mut Option<Box<dyn Task>>) {
    // here, the vtable is set to a pointer to a global variable in the `engine_core.so` file
    *api = Some(Box::new(FibTask {}) as Box<dyn Task>);
}

and engine is an executable that dynamically loads (and unloads!) engine_core.so:

fn main() {
    let mut api: Option<Box<dyn Task> = None;

    unsafe {
        let lib = Library::open(); // load `engine_core.so`
        let run: Symbol<unsafe extern "Rust" fn(reg: &mut EngineAPI)> = lib.get();
        run(&mut api); // sets vtable pointer to a vtable located in `engine_core.so`
        // `lib` goes out of scope, `engine_core.so` is unloaded
    }

    // `api` goes out of scope and the destructor of `dyn Task` is executed, which will attempt to load the
    // `drop_in_place` function from the vtable, but here the vtable is a danging pointer, because the global
    // variable that it points to has been freed by unloading `engine_core`! 💥  
}

This works in 1.82, because for some reason the dlclose doesn't actually cause the dynamic library to be unloaded on that version. I haven't investigated why this happens.

Anyway, I'm inclined to say that this is probably not a compiler bug: When dynamic libraries are dynamically unloaded, then global variables (including vtables!) are suddenly not so global anymore, and it is the responsibility of the programmer to ensure that they aren't used after they have been freed.

jieyouxu

jieyouxu commented on Dec 10, 2024

@jieyouxu
Member

Thanks for the analysis @lukas-code and the reduction @cyrgani! I'm going to close this as not-a-compiler-bug.

added
C-gubCategory: the reverse of a compiler bug is generally UB
and removed
C-bugCategory: This is a bug.
E-needs-bisectionCall for participation: This issue needs bisection: https://github.com/rust-lang/cargo-bisect-rustc
E-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Dec 10, 2024
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

    C-gubCategory: the reverse of a compiler bug is generally UB

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @compiler-errors@apiraino@lukas-code@aDotInTheVoid@jieyouxu

        Issue actions

          Rust 1.83.0 Sync with dyn Traits Regression · Issue #134014 · rust-lang/rust