| Anonymous | Login | Signup for a new account | 2013-05-23 13:06 CEST | ![]() |
| Main | My View | View Issues | Change Log | Roadmap |
| View Issue Details [ Jump to Notes ] | [ Issue History ] [ Print ] | |||||||||||
| ID | Project | Category | View Status | Date Submitted | Last Update | |||||||
| 0005289 | OCaml | OCaml general | public | 2011-06-15 21:57 | 2011-08-03 18:00 | |||||||
| Reporter | cvp | |||||||||||
| Assigned To | ||||||||||||
| Priority | normal | Severity | crash | Reproducibility | always | |||||||
| Status | resolved | Resolution | no change required | |||||||||
| Platform | GNU/Linux (x86_64) | OS | Fedora Core (x86_64) | OS Version | 15 | |||||||
| Product Version | 3.12.0 | |||||||||||
| Target Version | Fixed in Version | |||||||||||
| Summary | 0005289: error code 141 / "unknown C primitive `unix_dup'" when flushing to unopened pipe | |||||||||||
| Description | When piping to programs that don't use stdin, the toplevel and the bytecode interpreter straight-up crash, when you would expect that an exception be thrown instead or something. | |||||||||||
| Steps To Reproduce | Toplevel: $ ocaml # #load "unix.cma" ;; # let p_out = Unix.open_process_out "true" ;; val p_out : out_channel = <abstr> # output_string p_out "foo" ;; - : unit = () # flush p_out ;; (* crashes *) $ echo $? 141 $ (Also crashes in toplevel without dynamic loading, made with: $ ocamlmktop -custom -cclib -lunix unix.cma -o unix-top ) Bytecode: $ cat > fail.ml let p_out = Unix.open_process_out "true" in output_string p_out "foo"; flush p_out; close_out p_out; Unix.close_process_out p_out ;; print_endline "executed successfully" ;; ^D $ ocamlc -custom -cclib -lunix unix.cma fail.ml -o fail $ ./fail # works executed successfully $ ocamlrun fail # doesn't Fatal error: unknown C primitive `unix_dup' $ Compiling to native machine code produces no errors (i.e. "executed successfully"). | |||||||||||
| Additional Information | $ uname -a Linux icarus 2.6.38.7-30.fc15.x86_64 #1 SMP Fri May 27 05:15:53 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux $ ocaml -version The Objective Caml toplevel, version 3.12.0 $ grep '$Id' $(ocamlc -where)/unix.mli (* $Id: unix.mli 10450 2010-05-21 12:00:49Z doligez $ *) | |||||||||||
| Tags | No tags attached. | |||||||||||
| Attached Files | ||||||||||||
Notes |
|
|
(0006011) cvp (reporter) 2011-06-15 21:58 |
Er... click the "View Advanced" link to see Steps to Reproduce. |
|
(0006012) ygrek (reporter) 2011-06-16 08:34 |
It doesn't crash, but exits on SIGPIPE because `true` exits before output channel is flushed. Try `yes > /dev/null' instead and see. Bytecode compiled works because channel happens to be flushed before `true` is launched (race condition). `unix_dup` is not found in last example because you shouldn't use ocamlrun to run executables with custom runtime. |
|
(0006013) cvp (reporter) 2011-06-16 17:24 |
In that case, shouldn't the interactive toplevel handle a SIGPIPE a little more gracefully? Because all the user sees is a sudden termination without an explanation. |
|
(0006080) doligez (manager) 2011-08-03 17:59 |
You have your explanation right here: # flush p_out ;; (* crashes *) $ echo $? 141 The termination code is 128 + 13. The 128 is a flag telling you that the process was killed by a signal, and the 13 is the signal number (SIGPIPE). Maybe the shell should report exit codes more explicitely ? Should we try to catch all signals? And what do we do when we get one? |
Issue History |
|||
| Date Modified | Username | Field | Change |
| 2011-06-15 21:57 | cvp | New Issue | |
| 2011-06-15 21:58 | cvp | Note Added: 0006011 | |
| 2011-06-16 08:34 | ygrek | Note Added: 0006012 | |
| 2011-06-16 17:24 | cvp | Note Added: 0006013 | |
| 2011-08-03 17:59 | doligez | Note Added: 0006080 | |
| 2011-08-03 18:00 | doligez | Status | new => resolved |
| 2011-08-03 18:00 | doligez | Resolution | open => no change required |
| Copyright © 2000 - 2011 MantisBT Group |