Skip to content

Pointer-to-pointer + casts in FFI leads to hard-to-debug mysterious problems #17417

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

Closed
huonw opened this issue Sep 21, 2014 · 6 comments
Closed
Labels
A-FFI Area: Foreign function interface (FFI) A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. C-enhancement Category: An issue proposing an enhancement or a PR with one.

Comments

@huonw
Copy link
Member

huonw commented Sep 21, 2014

If you have a C API taking a pointer-to-a-pointer, like void**, where the function fills in a pointer value, it's very easy to screw up if there is any pointer casting involved:

extern crate libc;
extern {
    fn c_func(x: *mut *mut libc::c_void);
}

fn main() {
    let x = 0 as *mut u8;
    c_func(&mut (x as *mut libc::c_void));
    println!("new pointer is {}", x);
}

This will always print new pointer is 0x0, no matter what c_func does.

Reason: the x as *mut ... cast is creating a temporary, that's disconnected from the original x and thus the modification happens to the anonymous stack slot that stores the result of the cast. The code should be written something like (&mut x) as *mut _ as *mut *mut libc::c_void.

This is really subtle to debug, so we could have a lint that assists in this case: "did you mean to take a reference to the result of a cast in this FFI call" (could have it apply to non-FFI things too, and presumably it should only apply when there are &mut pointers involved).

@huonw huonw added A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. A-FFI Area: Foreign function interface (FFI) labels Sep 21, 2014
@huonw huonw changed the title Pointer-to-pointer + casts in FFI leads to hard to mysterious failures Pointer-to-pointer + casts in FFI leads to hard-to-debug mysterious failures Sep 21, 2014
@huonw huonw changed the title Pointer-to-pointer + casts in FFI leads to hard-to-debug mysterious failures Pointer-to-pointer + casts in FFI leads to hard-to-debug mysterious problems Sep 21, 2014
@steveklabnik
Copy link
Member

Triage: i've created a repository to assist anyone who wants to write this lint: https://github.com/steveklabnik/rust-issue-17417

@steveklabnik steveklabnik added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Oct 27, 2015
@steveklabnik
Copy link
Member

Since new lints have a big impact on users of rustc, the policy is that they should go through the RFC process like other user-facing changes. As such, I'm going to give this one a close, but if anyone comes across this ticket and wants this lint, consider adding it to clippy and/or writing up an RFC. Thanks!

@Envek
Copy link

Envek commented May 21, 2017

@huonw, thank you for sharing a recipe for working with pointer-to-a-pointer APIs. It apparently should be documented in FFI chapter of the Rust book!

@joshhansen
Copy link

Yes, that formula really does belong in the FFI section of the book. Saved me a million years of experimentation.

@messense
Copy link
Contributor

messense commented Jan 8, 2018

Just ran into this today, it really should be documented in the book!

@woodgear
Copy link

woodgear commented Nov 7, 2018

is there some update?

lnicola pushed a commit to lnicola/rust that referenced this issue Jun 23, 2024
refactor: Prefer plain trait definitions over macros for impl_intern_value_trivial

`impl_intern_value_trivial` can be defined with a trait directly, so prefer that over a macro definition.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-FFI Area: Foreign function interface (FFI) A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. C-enhancement Category: An issue proposing an enhancement or a PR with one.
Projects
None yet
Development

No branches or pull requests

6 participants