Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

daniel-levin
Copy link
Contributor

Normally, I don't like taking new dependencies if they can be avoided. But, zerocopy is no ordinary dependency. First of all, we already depend on it as a transitive dependency of std. Secondly, it supplements rustc's analysis of data structures to automatically reason about which transmutes are safe. That is, changing std::mem::transmute to zerocopy::transmute does not simply sequester the unsafe code. Rather, this macro will result in a compile error unless zerocopy can establish that the resultant unsafe code is sound. Jack Wrenn wrote up a nice article on how it works: https://jack.wrenn.fyi/blog/safety-goggles-for-alchemists/

This change includes the only call site of std::mem::transmute that could be swapped out in one shot. There are other places where zerocopy can relieve the burden of reasoning about safety, but they will require more invasive changes.

@daniel-levin daniel-levin force-pushed the master branch 3 times, most recently from 2e2d9ff to 163d180 Compare August 15, 2025 12:44
Copy link
Owner

@Phantomical Phantomical left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I have a couple concerns about this PR. I'm not strictly opposed to adding a dependency on zerocopy but I don't consider avoiding a single transmute between bytes and a known #[repr(C)] struct to be worth it, especially since it is being added as a dependency of the sys crate. As such, I'd like to know where else you think it would be useful.

edit: If you have an external need where you want the structs in the sys crate to derive the relevant zerocopy traits I would also be ok with adding that behind a feature flag.

As a code level concern: the bindings files are autogenerated so any changes made manually will be overwritten the next time I run regenerate.sh. You will need to modify regenerate.sh to make this change automatically.

@daniel-levin
Copy link
Contributor Author

daniel-levin commented Aug 16, 2025

I'm not strictly opposed to adding a dependency on zerocopy

For the avoidance of doubt, the Rust standard library depends on zerocopy, so it's already a transitive dependency. In an of itself, not a justification for taking the dependency, but possible useful to know.

As a code level concern: the bindings files are autogenerated so any changes made manually will be overwritten the next time I run regenerate.sh. You will need to modify regenerate.sh to make this change automatically.

I incorrectly concluded that the different authors over time appearing in a git blame meant that these files had been hand-edited. I'm going to change the bindgen scripts instead.

As such, I'd like to know where else you think it would be useful.

Good point. I have found several places. Consider the Sampler::page method, which returns a raw pointer, and all the subsequent reads of this struct's fields. While the subsequent atomic loads will still need to drop to unsafe, a couple of the computations with respect to the fields of perf_event_mmap_page's fields can be hoisted to safe code. It would be very useful to return a reference instead.

Lastly, even though we can trivially reason about the safety of transmutes from repr(C) structs, zerocopy offers a means to automate this on all architectures, for every possible change to the C API, forever. I want to emphasize that it's not just hiding the unsafe code, it's actually performing architecture-specific reasoning that would be quite burdensome to do manually. Most importantly, zerocopy will refuse to allow the code to compile if it finds something that would make the transmutes unsound, like an abstruse platform-specific alignment requirement, for example. YMMV, but I've found that zerocopy has made me point the proverbial gun away from my own foot many times.

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

Successfully merging this pull request may close these issues.

2 participants