-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Segfault with no-naked-pointers and recursive modules #10203
Comments
Incremental GC is going too far! :-) I've always had mixed feelings about stopping GC marking in the middle of a heap block, and now we see what can happen... I'm afraid the only solution is to always go through a trampoline function (the ocaml/stdlib/camlinternalMod.ml Lines 92 to 97 in 0553723
Performance will suffer a bit, but never mind. (As a side effect, |
If I understand correctly, the suggestion is to use the trampoline when the shape of the closures are distinct (rather than always, for all function backpatching). The dummy closure used in Note that if a user observes a performance degradation due to the change (probably no one), they are initializing a publicly-visible function |
In native mode, functions with arity greater than one have
Performance will be much worse with this approach, at least with the native compiler, as direct calls to self (or a mutually recursive function) are much cheaper than indirect calls going through the recursive module being defined. |
I've prototyped an alternative approach to recursive module initialisation in #10205, which is simpler than the current one and I think should perform well (and doesn't overwrite closures). |
This was fixed by #10205 as far as I can see, isn't it? |
Trunk can currently segfault during GC, due to a bad interaction between the new closure representation (relied upon in no-naked-pointers mode) and the way that recursive modules are initialised.
During recursive module initialisation, a stub closure is directly overwritten with the contents of another closure, once the recursive closure has been built. The current code in camlInternalMod is careful to ensure that both the old and new closures are valid and the correct intrinsics in Obj are used to mutate them.
However, this isn't enough, as incremental garbage collection can still get mixed up between the old and new layouts. The sequence of events that goes wrong is:
[2, 11]
of the stub closure's fields[2, 11]
from mark stack and starts markingWe end up marking field 2 of a closure which by that point has
env_offset = 3
. Field 2 of this closure is not a markable value (it's a code pointer), so this segfaults.(This came up during an attempt to benchmark #10195 using sandmark: cubicle segfaults on startup due to this bug)
The text was updated successfully, but these errors were encountered: