Conversation
|
Ah, this refactor not only made the implementation much more robust and simple, both in terms of code and running (via |
|
I also don't think it's the best idea to do either fuzzing or benchmarking on PRs. It takes a considerable amount of time (namely for the benchmarking part), the fuzzing is flaky/inconsistent, especially for a 30 secs run, and the benchmarking is probably noisy and unreliable given that it's running on GitHub Actions runners, where it probably shouldn't run. I feel like we should run an extensive, longer, proper fuzzing under a cron schedule and benchmark manually via comments or using dedicated runners instead. But this is an off-topic thing I noticed during the nightly action run and, if relevant, should probably have an issue of its own. |
|
also, there is a weird interaction with #656 which is not nice at all, the API there is a bit fucked up currently |
… requested changes
|
how do we now interpret the weird fuzzing error in https://github.com/servo/rust-smallvec/actions/runs/35758316781/job/106849613954?? I'm not sure what debug has to do there |
That's just the thread '<unnamed>' (10010) panicked at src/lib.rs:892:9:
assertion failed: new_capacity >= lenThe fuzzer generated a sequence of operations that forced You should find that failure locally by fuzzing in your machine and accessing the crash file like the output of the action suggests. We could also change the CI action so that if fuzzing fails it gives us the crash either via the action's artifacts or by printing it directly in the fail. That's probably a good idea. As of now our fuzzing action tells us if something fucks up, but we can't actually access the crash to reproduce it ourselves in our machines. But as I said at the start of the issue, the fuzzing seems to fail always on the same two situations, so you can probably get the fail and access the crash yourself by simply running the fuzzing in your machine as of now. |
|
how is that even possible has any invariant been broken?? |
|
Apparently, yes. The invariant that a I will look into this at my earliest convenience. If we can indeed prove that it's a code problem, then this fuzzer is already finding existing problems that we hadn't caught and it should be a good idea to merge. Independently of merging then directly or not, the end goal is to, of course, let the fuzzer run its course for a lot of time without finding any crash or panic. |
|
great I guess... I already doubt many parts of our implementations and I'm planning to drop soon an issue group for 10-15 issues regarding code revision, this seems to confirm it I wonder what would the fuzzer find if ported to v1, and I think we should do it if possible go investigate the crash whenever you have time if you want, if you don't find time I'll take it no worries |
| assert_eq!( | ||
| small_vec.as_slice(), | ||
| std_vec.as_slice(), | ||
| "`as_slice()` mismatch" | ||
| ); | ||
| assert_eq!( | ||
| small_vec.as_mut_slice(), | ||
| std_vec.as_mut_slice(), | ||
| "`as_mut_slice()` mismatch" | ||
| ); |
There was a problem hiding this comment.
either is unnecessary
if the immutable references are equal, the mutable references will as well
I'd only keep the immutable one honestly
There was a problem hiding this comment.
The thing is - they will both be equal in theory. In theory, all of the assertions done in fuzzing should pass, because all of them attempt to guarantee that each invariant isn't violated. as_mut_slice and as_slice, albeit very similar in their internal implementation, are different functions. What happens if in the future we change or try to change one's implementation but don't change the other? What if one of the invariants is ever broken and we don't catch it? What do we lose by asserting that both match? We do lose a bit of certainty by asserting that only one matches. Does this make sense? My point is, we probably shouldn't "stop doing an assertion" because we can imply that it passes from other assertion or because it's "simply logical". Apparently, it's also "simply logical" that cap would always be greater or equal to length, but the previous failing fuzzing output shows that that's apparently not the case.
tl;dr I'd insist we keep as_mut_slice, indexing, get and bounds check. By definition they all pass, until they don't and we have edge cases with UB or crashing. We lose nothing by keeping these assertions. Still, if you'd still prefer to remove them, I can change the code in that manner.
There was a problem hiding this comment.
in the case they stop doing what they are meant to do, tests will break before fuzzing matters
honestly I get the point, but they are so low-level invariants that at this point we may as well check that taggedlen isn't lying about the heap invariant. it's like, if this fails then everything else will fail before so it really makes no sense to explicitly check it
| assert_eq!( | ||
| small_vec[i], std_vec[i], | ||
| "`small_vec[{i}]` doesn't match `std_vec[{i}]`" | ||
| ); |
There was a problem hiding this comment.
this is unnecessary
if both immutable slices are equal as checked above, all elements are equal
There was a problem hiding this comment.
Please reply to the comment above.
| assert_eq!( | ||
| small_vec.get(i), | ||
| std_vec.get(i), | ||
| "`small_vec.get({i})` doesn't match `std_vec.get({i})`" | ||
| ); |
There was a problem hiding this comment.
Please reply to the comment above.
| assert_eq!( | ||
| small_vec.get(small_vec.len()), | ||
| None, | ||
| "out-of-bounds `get()` did not return `None`" | ||
| ); |
There was a problem hiding this comment.
this by definition will always pass
There was a problem hiding this comment.
Please reply to the comment above.
|
also, CI is complaining that we renamed |
|
Yes, it's in the |
|
Btw, I think I figured out the failure that the last CI was giving. We have |
|
Indeed, I patched the function up quickly by returning a dummy |
|
I honestly can't reply to that, who knows, it was already there when I came here I'm going to open full code revision soon because it doesn't make much sense to me either I'm not exactly sure what it should do but probably not return another error. either don't do anything or make it a precondition or something like that |
okay... why...?? |
|
I don't know yet. From what I ran, the fuzzing complained about these two specific cases. the |
…t invariant assertions on fuzzing
Signed-off-by: Pedro Nobre <me@pedrodesu.xyz>
|
I agree but in order to make sure CI is happy let's simply comment out those assertions, we'll re-enable them as we fix root causes |
|
and conflicts with the workflow have appeared, rebase is needed |
Wdym? To comment out the assertions that lead to these two fails? Isn't it better to solve them or to even merge with the fuzzing action failure? The fuzzing itself seems to be working, but these fails should be fixed. |
|
since it's fuzzing I'll let it pass, but I don't think it's good to merge things that fail CI can you rebase it?? |
|
I agree with that generally. I think this is a good exception as it's something we just (re)introduced and that is apparently working, as the failing action is just a byproduct. I can't work on it right now, I should be able to rebase it and perhaps investigate the remaining problem by tomorrow. |
port the new fuzzer introduced with servo#658 in v2 to the v1 branch, it should be a copy-paste + update CI if the fuzzers finds any inconsistencies, it's ...
Closes #657.
This might need some additional work; I'm treating this PR more like a draft.
Additionally, I've already ran this fuzzer myself and it has already shown quickly that we have some violations occuring with our current code on
v2(this assumes that the current fuzzing implementation is proper, which I believe it is), namely ontry_grow'sassert!(new_capacity >= len);and on the fuzzing test's assertion thatassert_eq!(small_vec.spilled(), small_vec.capacity() > N);. From what I saw, it's not really failing anywhere else. This also means, of course, that the fuzzing action should naturally fail at this point (I've also changed the fuzzing CI, I think it's working).Small disclaimer: I've done this work through the small hours of the morning lol