Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0007142OCaml~DO NOT USE (was: OCaml general)public2016-02-10 13:452017-09-24 17:33
Reportermlasson 
Assigned Tofrisch 
PrioritynormalSeverityminorReproducibilityalways
StatusclosedResolutionfixed 
PlatformOSOS Version
Product Version 
Target Version4.03.1+devFixed in Version4.04.0 +dev / +beta1 / +beta2 
Summary0007142: Change of behavior of demarshalling an empty file
DescriptionThe program in Section "Steps to Reproduce" used to work in ocaml 4.01 and fails with the exception "input_value: truncated object" on the current trunk.

It is due to the recent change in intern.c, more precisely the merge of GPR#224 [https://github.com/ocaml/ocaml/pull/224 [^]] (commit 4fd254e).

Before that commit, the function caml_input_val was raising the EOF exception while trying to read the magic number starting marshaled representation, and now the function call below fails with "input_value: truncated object" (is the object really truncated if there is no object ?):
if (caml_really_getblock(chan, header, 20) == 0) {
   caml_failwith("input_value: truncated object");
}

I don't know if this is a bug or if the original behavior was an abuse the demarshaling function. In the later case, it should be documented.
Steps To Reproducelet write oc n =
  for k = 1 to n do
     Marshal.to_channel oc k []
  done

let read ic =
  try while true do
    Printf.printf "%d\n%!" (Marshal.from_channel ic)
  done with End_of_file -> ()

let () = begin
    let filename, oc = Filename.open_temp_file ~mode:[Open_binary] "integers" "tmp" in
    write oc 10;
    close_out oc;
    let ic = open_in_bin filename in
    read ic;
    close_in ic;
  end
TagsNo tags attached.
Attached Files

- Relationships

-  Notes
(0015396)
doligez (administrator)
2016-02-25 14:10

The empty file is definitely a truncated object, and I don't see a good reason to special-case it.

I vote for documenting the new behaviour (and maybe also that it changed from previous versions).
(0015894)
guesdon (manager)
2016-05-03 11:34

When reading from a pipe or a network communication, with the new implementation there is no way to distinguish between a closed channel (end of communication) from a bad transmitted value.

This change of behaviour has already broken Stog. Ok, I should have tested it before the release, but since 4.03.0 broke a lot of libraries Stog depends on (and not only mine), this was not possible in a reasonable amount of time.
(0015900)
gabelevi (reporter)
2016-05-06 18:46

I'm also hitting this change in behavior when trying to compile Flow (github.com/facebook/flow) with 4.03.0.
(0015966)
berenger (reporter)
2016-06-02 17:38

This bug also hits clangml.
My dirty fix looks like;
code before:
---
  try io_loop ()
  with End_of_file ->
    close_in input;
    [...]
---
code after:
---
  try
    try
      io_loop ()
    with Failure msg ->
      begin
        if msg = "input_value: truncated object" then
          raise End_of_file
        else
          raise (Failure msg)
      end
  with
  | End_of_file ->
    close_in input;
    [...]
---
(0015967)
berenger (reporter)
2016-06-02 17:39

Thanks for the initial report: it allowed me to google the error message
and quickly find where and what to fix.
(0015969)
frisch (developer)
2016-06-03 11:06

> When reading from a pipe or a network communication, with the new implementation there is no way to distinguish between a closed channel (end of communication) from a bad transmitted value.

This is an interesting argument in favor of restoring the previous behavior.

Damien: would you agree to that?
(0016001)
xleroy (administrator)
2016-06-27 15:00

I am probably the one to blame for this change of behavior, although it was not on purpose!

The old implementation of the unmarshaler would raise End_of_file if it hit end-of-file while reading the first 20 bytes of data (the header), and Failure "input_value: truncated object" if it hit end-of-file while reading the remainder of the marshaled data.

The 4.03 implementation raise Failure "input_value: truncated object" in both cases.

An arguably sensible behavior would be to raise End_of_file if the input is already at end-of-file, and Failure "input_value: truncated object" if end-of-file is hit later.
(0016007)
gasche (administrator)
2016-06-27 16:01

(I would also be in favor of un-breaking user's code by reverting to the old behavior. Both make sense, let's pick the convenient one.)
(0016010)
gabelevi (reporter)
2016-06-27 16:37

All of my use cases are for two processes communicating with each other via Unix.select followed by input_value. The End_of_file exceptions that we expect should not come in the middle of reading an object, so xleroy's suggestion would work for us.
(0016016)
mlasson (reporter)
2016-06-28 11:45
edited on: 2016-06-28 12:56

I've opened the GPR #639 to fix this problem; the current solution raises end_of_file when we fail to read the first byte of the header, but I'd be happy to implement another solution.

  https://github.com/ocaml/ocaml/pull/639 [^]


- Issue History
Date Modified Username Field Change
2016-02-10 13:45 mlasson New Issue
2016-02-10 14:49 mlasson Note Added: 0015335
2016-02-11 14:15 doligez Description Updated View Revisions
2016-02-11 14:16 doligez Description Updated View Revisions
2016-02-12 13:49 mlasson Note Deleted: 0015335
2016-02-25 14:10 doligez Note Added: 0015396
2016-02-25 14:10 doligez Status new => acknowledged
2016-02-25 14:10 doligez Target Version => 4.03.0+dev / +beta1
2016-04-14 17:50 doligez Target Version 4.03.0+dev / +beta1 => 4.03.1+dev
2016-05-03 11:34 guesdon Note Added: 0015894
2016-05-06 18:46 gabelevi Note Added: 0015900
2016-06-02 17:38 berenger Note Added: 0015966
2016-06-02 17:39 berenger Note Added: 0015967
2016-06-03 11:06 frisch Note Added: 0015969
2016-06-27 15:00 xleroy Note Added: 0016001
2016-06-27 16:01 gasche Note Added: 0016007
2016-06-27 16:37 gabelevi Note Added: 0016010
2016-06-28 11:45 mlasson Note Added: 0016016
2016-06-28 12:56 gasche Note Edited: 0016016 View Revisions
2016-07-11 14:21 frisch Status acknowledged => resolved
2016-07-11 14:21 frisch Fixed in Version => 4.04.0 +dev / +beta1 / +beta2
2016-07-11 14:21 frisch Resolution open => fixed
2016-07-11 14:21 frisch Assigned To => frisch
2017-02-23 16:36 doligez Category OCaml general => -OCaml general
2017-03-03 17:55 doligez Category -OCaml general => -(deprecated) general
2017-03-03 18:01 doligez Category -(deprecated) general => ~deprecated (was: OCaml general)
2017-03-06 17:04 doligez Category ~deprecated (was: OCaml general) => ~DO NOT USE (was: OCaml general)
2017-09-24 17:33 xleroy Status resolved => closed


Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker