Skip to content

FFI call to C adds an extra argument before the specified argument list #7627

Closed
@kevinmehall

Description

@kevinmehall

I'm trying to call a function in a C library with two args, a pointer and an int, and was seeing the C function segfault. When I break on the C function in GDB, I see that the pointer I passed in the first argument from Rust shows up in the second argument, and there's another address added as the first argument.

Simplified to a minimal example by passing a constant for the pointer to show that it's shifted into the second argument:

libusb_set_debug(10 as *mut libusb_context, 4);
/* Breakpoint 1, libusb_set_debug (ctx=0x804e738, level=10) at core.c:1600 */

I'm using Fedora 18, 32-bit
rustc 0.7 (3e933b1 2013-07-06 08:32:10 -0700)
host: i686-unknown-linux-gnu

Here's the original code and GDB output:

use std::cast;
use std::libc::{c_void, c_int, size_t, malloc, free};
use std::ptr;
use std::unstable::intrinsics;

struct libusb_context;

#[link_args = "-lusb-1.0"]
extern{
    fn libusb_init(ctx: **mut libusb_context) -> c_int;
    fn libusb_exit(ctx: *mut libusb_context) -> c_void;
    fn libusb_set_debug(ctx: *mut libusb_context, level: c_int) -> c_void;
}

fn main() {
    unsafe{
        let mut ctx: *mut libusb_context = intrinsics::init();
        let r = libusb_init(&ctx);
        println(fmt!("r=%?, ctx=0x%x", r, ctx as uint));
        libusb_set_debug(ctx, 4);
        println("set debug");
    }
}

/*
r=0, ctx=0xb7a00468
[Switching to Thread 0xb7bffb40 (LWP 32527)]

Breakpoint 1, libusb_set_debug (ctx=0x805b690, level=-1214249880)
    at core.c:1600
1600    {
(gdb) p/x level
$1 = 0xb7a00468
*/

I also tried calling libusb_exit(ctx), and it also receives the wrong pointer and segfaults.

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