linksplatform / linksplatform/doublets-rs

Stacked borrows Initiative

Open
#1 9 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

miri:Fail miri:UB
Dominant language
Rust
Stars
6
Forks
0
Avg merge
1h 37m
Merged PRs (30d)
1

Description

Now the experimental miri stacked borrows consider this as Undefined Behavior

error: Undefined Behavior: not granting access to tag <83023706> because incompatible item [Unique for <83025302>] is protected by call 27318525
   --> /home/runner/.rustup/toolchains/nightly-2022-07-29-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/non_null.rs:432:18
    |
432 |         unsafe { &mut *self.as_ptr() }
    |                  ^^^^^^^^^^^^^^^^^^^ not granting access to tag <83023706> because incompatible item [Unique for <83025302>] is protected by call 27318525
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
    = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <83023706> was created by a retag at offsets [0x0..0x4000000]
   --> /home/runner/work/doublets-rs/doublets-rs/doublets/src/mem/unit/store.rs:85:19
    |
85  |         let mem = self.mem.alloc(capacity)?.leak();
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: <83023706> was protected due to <83025299> which was created here
   --> /home/runner/work/doublets-rs/doublets-rs/doublets/src/mem/unit/store.rs:158:29
    |
158 |         self.sources.attach(&mut *root, index)
    |                             ^^^^^^^^^^

I find it very difficult to thread safety when multiple mutable pointers are stored in different places.
I recommend using Yoda notation in regard to pointer storing.

# instead of 
struct DoubletsTree {
    # ha-ha i own this data
    ptr: Pointer*
    
    fn method(link: T) {
        # touch `ptr`
    }
}

# i recommend use 
struct DoubletsTree {
    # where is my data :(

    fn method(i_m_here: Pointer*, link: T) {
        # touch ptr
    }
}

This works well with stacked borrows:

#! before

# borrow data[x..y]:2
self.touch_first_tree(leak -> root_of_tree, link)
# borrow data[z..w]:3 
self.touch_second_tree(leak -> root_of_tree, link)
# [x..y] and [z..w] overlapping :(

#! after
data = self.get_data(...) # -- borrow data:1

# borrow data[x..y]:2 (not borrow self)
Tree::touch_first_tree(data, root_of_tree, link)
# unborrow data[z..w]:2

# borrow data[z..w]:2 (not borrow self)
Tree::touch_second_tree(data, root_of_tree, link)
# unborrow data[z..w]:2

# unborrow data:1 :)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the experimental Miri Stacked Borrows error and inspect doublets/src/mem/unit/store.rs at lines 85 and 158, where the reported pointers are created and used. Trace how mutable pointers are stored across the affected methods and define completion as eliminating the reported undefined behavior while preserving the relevant memory operations.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.