Skip to content

Calling fast_clear causes a memory leak when using Rc<T>, even if force_unlink is called on each linked object.  #81

@icmccorm

Description

@icmccorm

Miri found memory leaks in the following tests:

  • xor_linked_list::tests::test_force_unlink
  • linked_list::tests::test_force_unlink
  • singly_linked_list::tests::test_fast_clear
  • rbtree::tests::test_fast_clear

All assertions pass. Each test has a similar structure; here's a minimal example using LinkedList that recreates the issue:

let mut l = LinkedList::new(ObjAdapter1::new());
      
let a = make_obj(1);

l.cursor_mut().insert_before(a.clone());

l.fast_clear();

unsafe {
    a.link1.force_unlink();
}

When executing this, Miri detects that a is leaked and provides the following output:

The following memory was leaked: alloc94446 (Rust heap, size: 56, align: 8) {
    0x00 │ 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 │ ................
    0x10 │ 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
    0x20 │ 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 │ ................
    0x30 │ 01 00 00 00 __ __ __ __                         │ ....░░░░
}

I originally thought this was due to unwrapping the clone in insert_before(...). To test this, I switched to using a modified ObjAdapter3 with Weak instead of Rc, and passed Rc::downgrade(&a) as a parameter to insert_before instead of making a clone. However, this did not correct the issue.

Given the descriptions of both force_unlink and fast_clear, I'm guessing that there are always going to be some precautions necessary to avoid memory leaks here. Could you confirm if this is a bug, and if not, what additional steps a user would need to take to avoid this type of leak when using these methods? Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions