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

Incorrect behavior calling extern "C" varargs functions in nightly (works in 1.8 beta) #32588

Closed
jgallagher opened this issue Mar 29, 2016 · 2 comments

Comments

@jgallagher
Copy link

I was seeing segfaults in libsqlite running one of the tests on rusqlite on the latest nightly. Tracked it down to rust not calling extern "C" functions with variable args correctly.

Given this C function:

void foobar(int32_t x, ...) {
    va_list ap;
    va_start(ap, 2);
    uint64_t y = va_arg(ap, uint64_t);
    uint64_t z = va_arg(ap, uint64_t);
    va_end(ap);

    printf("called with x = %d and varargs %#lx %#lx\n", x, y, z);
}

where two 64-bit values are expected in the varargs, and this Rust function:

extern "C" {
    fn foobar(x: i32, ...);
}

fn main() {
    extern "C" fn callback() {
    }

    println!("calling foobar(1, 0x{:x}, 3u64)", callback as usize);
    unsafe { foobar(1, callback, 3u64); }
}

Running on rustc 1.8.0-beta.2 (2879d940a 2016-03-22) outputs

calling foobar(1, 0x105906d40, 3u64)
called with x = 1 and varargs 0x105906d40 0x3

and running on rustc 1.9.0-nightly (d5a91e695 2016-03-26) outputs

calling foobar(1, 0x101223d40, 3u64)
called with x = 1 and varargs 0x3 0x10000000100

(I uploaded a full cargo project reproducer.)

I assume this is related to #19925, as both workarounds listed there for transmute fix the above problem too; i.e.,

foobar(1, callback as extern "C" fn(), 3u64);
foobar(1, callback as usize, 3u64);

both work correctly on nightly, but given this started causing segfaults in code that was working previously, I wonder if a warning or error could be issued for "you're passing a 0-sized thing to a C function and that's probably not what you want"? (I assume the output I pasted above from nightly is a result of rustc skipping over the 0-size callback and passing only a single parameter to the varargs instead of two.)

@alexcrichton
Copy link
Member

I think this is a dupe of #32201, but thanks for the report!

@jgallagher
Copy link
Author

Whoops, yeah, you're exactly right. I guess add me to the "ran into a crazy edge case" camp. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants