New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
set-cdr!
can cause list?
to crash in safe mode
#599
Comments
Thanks for the interesting bug report! The implementation of A fix for this particular case is simple: add a check for I think maintainers probably need a little discussion to decide whether these functions are intended to be correct in the presence of concurrent modification and if so to identify other functions with the same issue. |
I'd also point to some other nuances highlighted by @gus-massa in racket/racket#4072 (comment) (
|
So far our general consensus is that there is no well-defined result possible in the face of concurrent modification. (My first proposed solution does have the distinction of being definitely bad, in that it could answer The only real well-defined behavior I've been able to come up with is to raise an exception if we happen to detect concurrent modification. I'll let you guess what the reaction was when I asked what sort of performance impact it would have to start each call to So far it's leaning towards not changing the behavior, but other maintainers could still weigh in with different opinions. |
NB: In SRFI 226, I propose a condition |
已收到
|
After returning to this issue, I'd like to advocate in favor of the change that @jltaylor-us describes. I don't see how list operations in general can be well-defined if the list is modified concurrently — at least, not without something dramatically more complex/expensive, like tracking all reads and writes. The solution described above takes care to return So, if we agree that list operations are undefined in the presence of mutation, then |
This is the solution described in cisco#599. One extra test in the `list?` implementation is cheap, since it's a highly predictable branch. The effect of that check is maybe less important, since the behavior of list operations just has to be undefined when the list is mutated concurrent to the operation. It's nice to raise an exception when undefined behavior is detected in safe mode, but sometimes that's too expensive; then, any convenient behavior is ok, but avoiding memory faults is a priority.
This is the solution described in cisco/ChezScheme#599. One extra test in the `list?` implementation is cheap, since it's a highly predictable branch. The effect of that check is maybe less important, since the behavior of list operations just has to be undefined when the list is mutated concurrent to the operation. It's nice to raise an exception when undefined behavior is detected in safe mode, but sometimes that's too expensive; then, any convenient behavior can be ok, but avoiding memory faults is a priority.
This is the solution described in cisco/ChezScheme#599. One extra test in the `list?` implementation is cheap, since it's a highly predictable branch. The effect of that check is maybe less important, since the behavior of list operations just has to be undefined when the list is mutated concurrent to the operation. It's nice to raise an exception when undefined behavior is detected in safe mode, but sometimes that's too expensive; then, any convenient behavior can be ok, but avoiding memory faults is a priority.
This is the solution described in cisco#599. One extra test in the `list?` implementation is cheap, since it's a highly predictable branch. The effect of that check is maybe less important, since the behavior of list operations just has to be undefined when the list is mutated concurrent to the operation. It's nice to raise an exception when undefined behavior is detected in safe mode, but sometimes that's too expensive; then, any convenient behavior is ok, but avoiding memory faults is a priority. Original commit: racket/ChezScheme@26f79b5
This is the solution described in cisco#599. One extra test in the `list?` implementation is cheap, since it's a highly predictable branch. The effect of that check is maybe less important, since the behavior of list operations just has to be undefined when the list is mutated concurrent to the operation. It's nice to raise an exception when undefined behavior is detected in safe mode, but sometimes that's too expensive; then, any convenient behavior is ok, but avoiding memory faults is a priority. Original commit: racket/ChezScheme@0d9db98
The changes that @jltaylor-us described were made as part of the v9.9.9 merge. |
This program (by @mflatt, from racket/racket#4072 (comment)) creates an engine that calls
list?
on a pair which is initially a list. While the engine is suspended, it usesset-cdr!
to mutate one of the interior pairs so that it is no longer a list. If the interruption comes at just the right moment, resuming the engine will leadlist?
to perform an invalid memory reference: the program iteratively finds an amount of fuel that will reveal the error.Example output:
The text was updated successfully, but these errors were encountered: