rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.46k stars 12.73k forks source link

Document what a "dangling pointer" is #132286

Open Urgau opened 2 weeks ago

Urgau commented 2 weeks ago

Location

There are several places this applies, e.g.:

Summary

We have several place in the standard library or as part of lints where we use the term "dangling pointer" without defining it anywhere.

We should have a place where we define what that is, ideally in the standard library, in it's own section, maybe under std::ptr, so it can be referenced elsewhere.

It should probably have a definition, followed by some bad examples (and maybe how to fix them).

Wikipedia has article on the subject, I don't know if it could serve as a base for our documentation but it may be worth checking it.

Steps

saethlin commented 2 weeks ago

cc @rust-lang/opsem

RalfJung commented 2 weeks ago

Also see https://github.com/rust-lang/unsafe-code-guidelines/issues/478 (but note that some things changed since the issue was opened so part of the information there is outdated).

theemathas commented 2 weeks ago

The reference has a definition of dangling pointers.

RalfJung commented 2 weeks ago

Right, so somewhat confusingly ptr::dangling on a ZST does actually produce a non-dangling pointer.

theemathas commented 2 weeks ago

The documentation for ptr::dangling even explicitly says that it produces a dangling pointer (which is maybe false?). And then it goes to say that "the pointer value may potentially represent a valid pointer to a T" (which is false for non-ZST types, due to provenance).

theemathas commented 2 weeks ago

Documentation from the reference:

A reference/pointer is “dangling” if not all of the bytes it points to are part of the same live allocation (so in particular they all have to be part of some allocation). If the size is 0, then the pointer is trivially never “dangling” (even if it is a null pointer).

This implies that a pointer points to a range of addresses, depending on the type, and whether a pointer is dangling depends on the type.

Documentation from std::ptr:

We say that a pointer is “dangling” if it is not valid for any non-zero-sized accesses. This means out-of-bounds pointers, pointers to freed memory, null pointers, and pointers created with NonNull::dangling are all dangling.

This implies that whether a pointer is dangling or not doesn't depend on the type.

These two definitions are contradictory.

RalfJung commented 2 weeks ago

"may potentially" is definitely true, it doesn't say "will always" after all.

But yeah "is dangling" in the ptr::dangling docs uses a different definition of "dangling" than the reference. There are two reasonable definitions and we don't have a clear term to distinguish them:

We need to choose a different term for one of these.

Urgau commented 2 weeks ago

I just realized that ptr::dangling and the (recently merged) dangling_pointers_from_temporaries lint will both become stable in 1.84, with different uses of "dangling pointer", this is unfortunate, it would be good to clear this situation before they become stable.

RalfJung commented 2 weeks ago

NonNull::dangling is stable since forever, ptr::dangling just matches that. So I don't think there's any point in trying to pick a different name for ptr::dangling.

But Cc @rust-lang/libs-api in case they disagree

Urgau commented 2 weeks ago

That's a good point. The lint name however can still be changed (even after 1.84).