MantisBT - OCaml
View Issue Details
0007796OCamlruntime system and C interfacepublic2018-05-17 10:502018-05-23 19:51
xleroy 
xleroy 
normalmajoralways
resolvedfixed 
x86-64Ubuntu Linux 16.04
4.07.0+dev/beta2/rc1/rc2 
4.07.0+dev/beta2/rc1/rc24.07.0+dev/beta2/rc1/rc2 
0007796: "at_exit" function run twice with cleanup-at-exit runtime option
When "c=1" is put in OCAMLRUNPARAM, text printed to standard output in an at_exit function ends up written twice to standard output.

~/caml/devel$ cat foo.ml
let _ =
  at_exit (fun () -> print_endline "\nAll tests succeeded.")
~/caml/devel$ boot/ocamlrun ./ocamlc -I ./stdlib -o foo.byte foo.ml
~/caml/devel$ byterun/ocamlrun foo.byte

All tests succeeded.
~/caml/devel$ OCAMLRUNPARAM=c=1 byterun/ocamlrun foo.byte

All tests succeeded.

All tests succeeded.
~/caml/devel$


Among other ill effects, this causes many tests in the test suite to fail when run with OCAMLRUNPARAM="c=1".
No tags attached.
related to 0007253acknowledged  at_exit functions get called twice if a callback raises and prevents earlier handlers to execute. 
related to 0007178resolved xleroy Calling exit in at_exit callback results in infinite loop. 
Issue History
2018-05-17 10:50xleroyNew Issue
2018-05-17 11:21xleroyNote Added: 0019116
2018-05-17 11:54xleroySummaryDuplicate output with cleanup-at-exit runtime option => "at_exit" function runs twice with cleanup-at-exit runtime option
2018-05-17 11:55xleroySummary"at_exit" function runs twice with cleanup-at-exit runtime option => "at_exit" function run twice with cleanup-at-exit runtime option
2018-05-17 12:34nojebarNote Added: 0019118
2018-05-17 12:42nojebarNote Added: 0019119
2018-05-17 13:08xleroyNote Added: 0019120
2018-05-17 13:08dbuenzliNote Added: 0019121
2018-05-17 13:25xleroyRelationship addedrelated to 0007253
2018-05-17 13:25xleroyRelationship addedrelated to 0007178
2018-05-17 14:32xleroyNote Added: 0019122
2018-05-17 14:32xleroyStatusnew => confirmed
2018-05-17 14:32xleroyTarget Version => 4.07.0+dev/beta2/rc1/rc2
2018-05-21 11:38xleroyNote Added: 0019126
2018-05-23 19:51xleroyNote Added: 0019135
2018-05-23 19:51xleroyAssigned To => xleroy
2018-05-23 19:51xleroyStatusconfirmed => resolved
2018-05-23 19:51xleroyResolutionopen => fixed
2018-05-23 19:51xleroyFixed in Version => 4.07.0+dev/beta2/rc1/rc2

Notes
(0019116)
xleroy   
2018-05-17 11:21   
It seems that all "at_exit" functions are run TWICE if cleanup-at-exit is set. This is a serious mistake.
(0019118)
nojebar   
2018-05-17 12:34   
at_exit functions are called from caml_shutdown

  https://github.com/ocaml/ocaml/blob/trunk/byterun/startup_aux.c#L159 [^]

(caml_shutdown is called if cleanup_on_exit is set), but if the program finished normally, they would also have been called via std_exit.
(0019119)
nojebar   
2018-05-17 12:42   
The change to call at_exit functions from caml_shutdown was thread-related:

commit a6cad36c9da5fd136590132949d760603be98fa9
Author: Max Mouratov <mmouratov@gmail.com>
Date: Sun Nov 29 23:26:18 2015 +0500

    runtime: handling "at_exit" in caml_shutdown
    
    Without this, the Thread machinery didn't shut down correctly.
(0019120)
xleroy   
2018-05-17 13:08   
I agree that caml_shutdown should run the at-exit functions. This is especially true if the OCaml code is embedded as a library in a larger program. I also think that we should not run the at-exit functions twice, and will propose a GPR for that.
(0019121)
dbuenzli   
2018-05-17 13:08   
Since people might look into the whole machinery I just want to relate this to 0007253 and 0007178 and associated aborted GPR.
(0019122)
xleroy   
2018-05-17 14:32   
Proposed fix at https://github.com/ocaml/ocaml/pull/1783 [^] .
It does not address the other issues mentioned by @dbuenzli, but it an improvement nonetheless.
(0019126)
xleroy   
2018-05-21 11:38   
Alternate, improved fix at https://github.com/ocaml/ocaml/pull/1790 [^]
It also addresses MPR#7253.
(0019135)
xleroy   
2018-05-23 19:51   
Merged https://github.com/ocaml/ocaml/pull/1790 [^]