Conversation
def9228 to
26e7947
Compare
|
This bugfix actually opens a new opportunity: given that it is now clear that arbitrary code can execute during What would you think of this idea? |
[caml_alloc_small], to make sure the code is reetrant.
26e7947 to
e41c40f
Compare
| let t : int array = Array.make 200 0 | ||
| let c = open_out_bin "data0" | ||
| let () = Marshal.to_channel c t [] | ||
| let () = close_out c |
There was a problem hiding this comment.
Could it fail before also using bytes instead of external files? I think it is better to avoid files in tests if possible.
There was a problem hiding this comment.
This would not fail, because the code for unmarshalling bytes already restores the values of the global variables. It does so for a different reason: the reason is that input_src then points to the global heap, and the GC might move the source data.
There was a problem hiding this comment.
What's the issue with files in tests? OCamltest uses a specific directory for each tests, which can easily be removed. Also, note that the compilation artifacts always exist.
|
Instead of relying on saving global variables can't we turn them into a record that is passed to all the functions? |
This would certainly have some performance penalty (an additional parameter for every single function of the input machinery), and would require quite a large refactoring. |
|
By the way, note that even with my fixed version, if the allocation function raises an exception (via a finalizer), then Not sure how acceptable this is! The only fix I can think about is not trying to allocate in the minor heap in |
|
In the backtrace-related PR I wondered if it would be possible to have a function that allocates in the minor heap without calling the finalizers (by keeping finalizer-attached blocks in the minor heap), or fails if not possible. But that would be a major undertaking, if I understand the runtime correctly. |
That's actually not so difficult: There already is such a mechanism (in order to prevent finalisers being called from finalisers). It suffices to play with What would you think of that? |
stedolan
left a comment
There was a problem hiding this comment.
Looks good to me!
Before merging, I'd like to get @xavierleroy to weigh in on the comment change in signals_nat.c - it comes from here. I think the change is correct: there's now no need to distinguish between a GC that can context-switch and a GC that cannot since, due to signal handlers and finalisers, anything bad that can happen during a context-switch can already happen without one.
Actually, because of the possibility of a finaliser raising an exception even the fix implemented in this PR is not fully correct. See my comment at #8674 (comment). Hence, my new proposal would be, as suggested by @gasche, to have a new version of |
(I'm not qualified to answer this question but the general idea sounds quite nice to me.) |
|
I see two seperate issues here:
This PR fixes 1. I think the fix is correct, and I'd like to merge it. I think issue 2 is a seperate problem. To me, the problem is that finalisers and signal handlers should not be allowed to raise exceptions - I suspect this causes resource-handling problems elsewhere in the runtime and it certainly causes resource-handling problems in user code. Fixing it just for |
|
Alright, then, what about deactivating callbacks from |
|
I also agree with @stedolan on the principle that exceptions should not escape from finalisers and signals handlers. But I think the exceptions should be caught and ignored, rather than turned into fatal errors. |
That makes sense to me! |
Ah, but this is not so easy to do this for memprof callbacks. We could use the "postponing" mechanism, but then the callbacks could be called in a very different context... |
|
@stedolan: in the last weeks or so I have the impression that I encountered several situations (coming from code from either you or @jhjourdan) where it would be convenient to allocate memory on the minor heap without having to protect the caller against arbitrary OCaml code executing -- in one case, the You seem to suggest that conceptually this is not a good approach, but it is not clear to me why. Would it make things harder for multicore? (I guess there the assumption would be that no OCaml code runs on the same domain -- thread-local values are preserved, but of course mutators may run in other places.) I agree with your comment that the present PR is already an improvement and could be merged as-is. (After conflicts are fixed.) I would be happy if other people took care of merging, because I didn't look at the code here carefully. Regarding statmemprof callbacks: yes, I think that postponing them would be the right thing -- for this discussed Alloc_small_silent function/macro. I'm not sure why this would delay things "too much" -- if you call |
|
I think we are discussing about two different approaches to the problem:
|
Note that in that case, we wanted to prevent GC, not only arbitrary OCaml code. The solutions discussed here will not fix the callstack-in-memprof issue. |
I agree with what @jhjourdan says. I was against the original idea of adding a separate version of Afterwards, @jhjourdan suggested that in general,
Ah, you're right, this is a difficulty. I was just discussing this with @lpw25, and he suggested that one approach is to have an implicit |
|
I implemented the change we are discussing here as part of #8691. Let's continue the discussion there. |
Intern was using
caml_alloc, which calls the GC and hence can trigger finalizers. If such a finalizer calls an unmarshalling function, then it erases the global variable of the unmarshalling algorithm.This PR fixes the issue by saving the value of intern's global variables during the call to
caml_alloc. I also updated some comments which are no longer valid sincecaml_alloccan call finalizers.This is a bugfix. This should be cherry-picked to 4.09 too.