Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] Segfault in a native code multi-threaded program
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: John Gerard Malecki <johnm@a...>
Subject: Re: [Caml-list] Segfault in a native code multi-threaded program
John Max Skaller wrote (2001-08-19T09:15:44+1000):
 > 
 > > <hint for next ocaml ;)>
 > > 
 > >   It would be very nice to be able to rely on Marshal as safely as on
 > >   ocaml typing. Just to be sure that if I expect an int * string, I will
 > >   effectively receive an int * string or raise an exception. It could
 > >   probably be done using the same tricks as used in printf formatters.
 > > 
 > > </hint for next ocaml ;)>
 > 
 > 	As I understand it, this is a non-trivial research problem.


Yes it is but in the mean-time we are stuck with the problem.  I'll
describe the IMPERFECT solution i use.  If anyone else has something
better please do describe it.

The idea is to use the already existing extract_crc program to get the
digest of the data-structure to be written.  There are obvious flaws
including the fact that the value to be written must have a concrete
signature and the programmer must ensure that all of the accessible
signatures are included.  Assuming that one didn't make any mistakes
this should catch reading an "out of version" marshaled value.

Here is the text from an email i wrote a while ago describing the same
mechanism followed by all of the code to make a working example.

  Under some assumptions about the things that you are writing out
  extract_crc can provide some support.  The flaw is that extract_crc is
  not "deep".  If you create a single .mli file which only contains the
  signature of the value you are to write then you can, with some
  additional makefile complexity, automatically generate an extract_crc
  .ml from that .mli file.  For example, here is the output from
  extract_crc of the cell.mli file
  
  let crc_unit_list = [
    "Cell",
      "\032\036\180\144\173\052\208\140\081\102\211\172\198\229\098\218"
  ]
  
  Instead of simply doing an output value you could ALWAYS do an output
  value of crc_unit_list and then execute
  
  let safe_output_value safe oc data =
    output_value oc safe;
    output_value oc data
  
  let safe_input_value safe ic =
    let safe_input = input_value ic in
    if safe_input = safe then
      input_value ic
    else
      raise (Sys_error "safe_input_value")
  
  The majority of the work is in (makefile) procedures for automatically
  generating the crc_unit_list.  One must be careful about the
  dependencies to make sure that the makefile can both bootstrap and
  always keep the crc_unit_list file up to date.
  
  At one time i thought of using the dynlink module to solve these
  problems but it turns out that there is no real advantage as the
  majority of the work is in the makefile.

Here is a sample Makefile

  RESULT := a.out
  
  SOURCES := safety.ml test.ml
  
  all: safety.ml byte-code
  
  include OcamlMakefile
  
  EXTRACT_CRC := $(shell $(OCAMLC) -where)/extract_crc
  
  safety.ml: test.cmi
  	$(EXTRACT_CRC) test > $@
  
  check: all
  	OCAMLRUNPARAM='b=1' ./$(RESULT)
  
The file test.mli

  type t = (int * int) list

and the file test.ml

  type t = (int * int) list
  
  let safe_output_value safe oc data =
    output_value oc safe;
    output_value oc data
      
  let safe_input_value safe ic =
    let safe_input = input_value ic in
    if safe_input = safe then
      input_value ic
    else
      raise (Sys_error "safe_input_value")
  
  let _ =
    let data = [ 0,0; 1,1 ] in
    let oc = open_out_bin "test.db" in
    safe_output_value Safety.crc_unit_list oc data;
    close_out oc
  
  let _ =
    let ic = open_in_bin "test.db" in
    let data = safe_input_value Safety.crc_unit_list ic in
    close_in ic;
    data

-cheers
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr