Closed nullchinchilla closed 3 years ago
Thanks for the report! I'm not aware of the bug, so I'd very much appreciate a test case. Even a long one would be a start.
By the way, did you check whether the panic happens with im
? It's fairly likely that it does, because we haven't changed much Vector
code, but it would be nice to know...
I figured out a somewhat close to minimal test case:
fn testvec(n: usize) -> imbl::Vector<u8> {
imbl::Vector::from(vec![0u8; n])
}
fn append(mut x: imbl::Vector<u8>, y: imbl::Vector<u8>) -> imbl::Vector<u8> {
x.append(y);
x
}
fn cons(x: u8, mut y: imbl::Vector<u8>) -> imbl::Vector<u8> {
y.push_front(x);
y
}
fn main() {
let v7 = append(testvec(0), testvec(0));
let v7 = append(testvec(32), v7);
let v7 = append(testvec(0), v7);
let v7 = cons(0, v7);
let v7 = append(testvec(4096), v7);
let v7 = append(testvec(32), v7);
let v7 = append(testvec(32), v7);
let v7 = append(testvec(0), v7);
let v7 = cons(0, v7);
let v7 = append(testvec(4096), v7);
// CRASHES HERE
}
This doesn't happen when cons
is replaced by a version that uses append
, or if I directly create vectors and append them, so a wild guess is that push_front
is somehow messing up the data structure.
Thanks! This reproduces for me too (and also when using im
).
Since we use imbl
in production, it's pretty important that this gets fixed ASAP. Is there anything I can help with?
I can have a look starting in around 12 hours. If you want to look before then, I'd put it a test in src/vector/mod.rs
and sprinkle calls to assert_invariants
around, to try to figure out at which point the invariants are breaking.
Any leads on this? Sorry I haven't gotten around to looking at this yet
Some leads, but no solution yet. You can see the crash
branch (and the crash
test in src/vector/mod.rs
) for what I have so far. I've narrowed down the bug to promote_front
, which for some reason creates an empty subtree of the root (and then later popping on that subtree causes the panic).
I can probably find some more time tomorrow night (i.e. 24 hours from now) to look more.
I think I have a fix. Besides the specific details of this bug, there's a general issue in this crate that the node sizes are so big that the testing doesn't often catch these edge cases. I've been mitigating that in OrdMap
and OrdSet
by testing it with smaller node sizes, but it's a little more complicated for Vector
...
@nullchinchilla have you had a chance to test the PR? I fuzzed it over the weekend without finding any problems.
Yeah, it does avoid the crash and can certainly be merged, though I've decided to switch to implementing B-tree-based persistent vectors myself due to general code quality concerns with imbl and RRB trees being quite complicated. I will certainly publish what I end up with onto crates.io once done :)
Fair enough! I'm hoping we'll address those issues in #35, but it certainly won't be instant...
While fuzzing some of my own code, I ran across a bug in
imbl::Vector
:append
somehow panics!This happens when appending together big
imbl::Vector<u8>
s:Does this ring a bell? I will try to find a minimal reproducible case tomorrow --- unfortunately, the fuzzing input that led to this is long and complicated.