Skip to content

Statics' symbol names are susceptible to drift #9431

Closed
@alexcrichton

Description

@alexcrichton

Let's say you're a library author. You just published the following library file under the name libbar:

// bar.rs
pub fn foo<T>() -> int {
    static a: int = 4;  
    return a;           
}                       

Some innocent programmer then comes along and uses this file. They write the following program

// foo.rs
extern mod bar;       

fn main() {           
    bar::foo::<int>();
}                    

Being a responsible library developer, you then realize that your library has a security flaw, so you update it to:

// updated bar.rs
fn fix_the_bug() {}             

pub fn foo<T>() -> int {
    static a: int = 4;  
    return a;           
}                       

You realize that this change is ABI-compatible with your previous library version, so being a responsible library developer, you push out an updated version of your new library.

As a responsible application developer, the client using your library then updates their copy, only to result in the following terrible-ness. (this shell session assumes that I'm both the library and application developer).

// let's compile libbar for the first time
$ ./x86_64-apple-darwin/stage2/bin/rustc --lib bar.rs
warning: missing crate link meta `name`, using `bar` as default
warning: missing crate link meta `vers`, using `0.0` as default
warning: no debug symbols in executable (-arch x86_64)

// Now let's compile our application, link it against libbar, and run it
$ ./x86_64-apple-darwin/stage2/bin/rustc foo.rs -L.
warning: no debug symbols in executable (-arch x86_64)
$ ./foo

// Awesome! now let's update libbar (with the bugfix), and recompile
$ ./x86_64-apple-darwin/stage2/bin/rustc --lib bar.rs
warning: missing crate link meta `name`, using `bar` as default
warning: missing crate link meta `vers`, using `0.0` as default
warning: no debug symbols in executable (-arch x86_64)

// The library didn't move, and it didn't change name, we shouldn't
// have to recompile foo here.
$ ./foo
dyld: Symbol not found: __ZN3foo1a19hff345045bc2f6a3eaj4v0.0E
  Referenced from: /Users/alex/code/rust3/./foo
  Expected in: /Users/alex/code/rust3/./libbar-15fb3a718ea23983-0.0.dylib
 in /Users/alex/code/rust3/./foo
zsh: trace trap  ./foo

The reason for this is that 1da4488 introduced the idea of a "pretty name" for statics which uses the node_id as the "unique tidbit" of information for a static in order to guarantee that they all have different names. This is very undesirable, and this should definitely be fixed.

Nominating for production-ready, and possibly the priority tag.

All credit for finding this goes to @cmr's eagle eyes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions