Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Fix or allow all hard clippy errors. #11409

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

afck
Copy link
Contributor

@afck afck commented Jan 26, 2020

This would make cargo clippy succeed, albeit with lots of warnings.

I think the write calls are an actual potential bug, since the returned number of written bytes is not handled. (I.e. it would just continue, even if the strings were only partially written.)

I'm very unsure about the alignment issues.

@parity-cla-bot
Copy link

It looks like @afck signed our Contributor License Agreement. 👍

Many thanks,

Parity Technologies CLA Bot

@afck afck marked this pull request as ready for review January 27, 2020 09:40
@afck
Copy link
Contributor Author

afck commented Jan 27, 2020

We could also #![allow(clippy::cast_ptr_alignment)] for the whole file in those three cases, although that would be even scarier. 😅

@@ -185,6 +185,7 @@ fn make_memmapped_cache(path: &Path, num_nodes: usize, ident: &H256) -> io::Resu

let mut memmap = unsafe { MmapMut::map_mut(&file)? };

#[allow(clippy::cast_ptr_alignment)] // TODO: Why is this okay?
Copy link
Collaborator

@niklasad1 niklasad1 Jan 27, 2020

Choose a reason for hiding this comment

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

We should use ptr::read_unaligned instead but it will still be a clippy error see rust-lang/rust-clippy#2881

Copy link
Contributor Author

@afck afck Jan 27, 2020

Choose a reason for hiding this comment

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

I'm still a bit confused about what's going on here. But it really looks wrong to me:

  • initialize_memory internally creates a slice::from_raw_parts_mut of type &mut [Node].
  • MmapMut does not guarantee alignment, otherwise it wouldn't have an align_to_mut method.
  • from_raw_parts_mut explicitly requires the data to be aligned.

read_unaligned would copy the data: My impression is that most of this code was written as an optimization to avoid copying. If we are fine with copying, we could probably do away with most of the unsafe code here?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I thought mmap is page-aligned http://man7.org/linux/man-pages/man2/mmap.2.html, but maybe @Vurich could provide more input.

MmapMut does not guarantee alignment, otherwise it wouldn't have an align_to_mut method.

This is a method on a slice though (I guess it shows up in the docs, because MapMut implements Deref to a slice), which can be arbitrary aligned.

Copy link
Collaborator

@ordian ordian Jan 27, 2020

Choose a reason for hiding this comment

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

And I agree we should remove unsafe code as much as possible, we have some benchmarks, see e.g. #10861. But let's do it in a separate PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I see! Sorry! 🤦‍♂️
Then I guess I should just add a comment pointing to the mmap man page? (But what about platforms other than Linux?)

Copy link
Contributor

@eira-fransham eira-fransham Jan 28, 2020

Choose a reason for hiding this comment

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

I thought mmap is page-aligned http://man7.org/linux/man-pages/man2/mmap.2.html, but maybe @Vurich could provide more input.

MmapMut does not guarantee alignment, otherwise it wouldn't have an align_to_mut method.

This is a method on a slice though (I guess it shows up in the docs, because MapMut implements Deref to a slice), which can be arbitrary aligned.

I have been summoned! The link you want is https://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html - while on Linux it is defined to be page-aligned, mmap is a POSIX syscall and so on non-Linux POSIX environments it might fail. I'd add an alignment check (with error on fail) here, LLVM has alignment knowledge for libc functions for all architectures it supports so we can rely on it to remove the alignment check where appropriate. I'd be shocked if there are any real-world environments that will return unaligned pointers from mmap but better do the right thing now instead of dealing with a truly nasty bug further down the road.

I made the same mistake while writing this code, of using the Linux docs instead of the POSIX docs.

@@ -83,6 +83,7 @@ impl NodeEndpoint {
let address = match addr_bytes.len() {
4 => Ok(SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(addr_bytes[0], addr_bytes[1], addr_bytes[2], addr_bytes[3]), tcp_port))),
16 => unsafe {
#[allow(clippy::cast_ptr_alignment)] // TODO: Why is this okay?
Copy link
Collaborator

Choose a reason for hiding this comment

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

well, I'm not super intimate with this piece of code why it is unsafe in the first place but I think it is because we don't want to copy the bytes to perform the conversion [u8; 16] -> [u16; 8]

We could do this in safe rust:

				let mut addr = [0_u8; 16];
				addr.copy_from_slice(&addr_bytes[0..16]);
				Ok(SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::from(addr), tcp_port, 0, 0)))

The unsafe scope could be reduced because only slice::from_raw_parts is unsafe.

I'm up making it safe, but let's here what the others have to say //cc @ordian @dvdplm

Copy link
Collaborator

Choose a reason for hiding this comment

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

AFAICT it is not used on any hot paths (on_ping, on_pong and on_neighbours). It is called often, sure, but not so often as to be a performance bottleneck I'd say. On the other hand the code today is, I'd say, safe.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree with @niklasad1, we should just replace it with the safe code unless it introduces a perf bottleneck.

@@ -265,6 +266,7 @@ fn read_from_path(path: &Path) -> io::Result<Vec<Node>> {
}

let out: Vec<Node> = unsafe {
#[allow(clippy::cast_ptr_alignment)] // TODO: Why is this okay?
Copy link
Collaborator

Choose a reason for hiding this comment

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

hmm, this is a good question, I'm not sure myself about the alignment cc @Vurich

@ordian ordian added A0-pleasereview 🤓 Pull request needs code review. M4-core ⛓ Core client code / Rust. labels Jan 28, 2020
@afck afck force-pushed the afck-clippy-errs branch from 9530e9b to de688da Compare March 10, 2020 14:04
@afck
Copy link
Contributor Author

afck commented Mar 10, 2020

Sorry for the delay! I added alignment checks and removed some unsafe code.

unsafe { initialize_memory(memmap.as_mut_ptr() as *mut Node, num_nodes, ident) };
unsafe {
let bytes = memmap.as_mut_ptr();
assert_eq!(bytes as usize % mem::align_of::<Node>(), 0, "Mmap memory not aligned.");
Copy link
Collaborator

Choose a reason for hiding this comment

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

what's the rationale of panicking instead of returning an Error as in the code below?

Copy link
Collaborator

Choose a reason for hiding this comment

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

is there any way to check this at compile-time?

mem::align_of is const fn

@ordian
Copy link
Collaborator

ordian commented Mar 10, 2020

please merge with master, that should help with CI

@afck afck force-pushed the afck-clippy-errs branch from de688da to 5928b08 Compare March 11, 2020 10:28
@afck
Copy link
Contributor Author

afck commented Mar 11, 2020

I rebased on master, but I'm still getting errors on CI:

failed to run custom build command for `parity-snappy-sys v0.1.2`

and:

The process 'C:\Rust\.cargo\bin\cargo.exe' failed with exit code 101

afck and others added 3 commits March 31, 2020 13:43
This makes clippy succeed, albeit with lots of warnings.
@afck afck force-pushed the afck-clippy-errs branch from 6b191ae to d9a4c75 Compare March 31, 2020 12:04
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A0-pleasereview 🤓 Pull request needs code review. M4-core ⛓ Core client code / Rust.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants