intrusive-rs icon indicating copy to clipboard operation
intrusive-rs copied to clipboard

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

Open icmccorm opened this issue 1 year ago • 2 comments

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<Obj> instead of Rc<Obj>, 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!

icmccorm avatar Feb 09 '23 02:02 icmccorm