caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* RE: [Caml-list] ocaml sefault in bytecode: unanswered questions
@ 2009-08-08  9:17 ivan chollet
  2009-08-08 13:29 ` Edgar Friendly
  0 siblings, 1 reply; 5+ messages in thread
From: ivan chollet @ 2009-08-08  9:17 UTC (permalink / raw)
  To: 'Cedric Auger', caml-list

Cedric,

I use the Unix library, can it cause segfaults also? (If yes, I would expect
the ocaml bytecode runtime system to produce a nice stacktrace though)
That's the only library I use, the rest of the code fits into the OCaml core
category and also some use of the Standard modules.
FYI, Marshal can definitely produce segfault, therefore my question was:
apart from the Marshal module, what can produce segfaults?

You basically state that stuff like “let l = !myref in List.iter myfun l”
(where myfun modifies !myref) wouldn't produce segfault. 
Why? It would mean that doing "let l = !myref" creates a brand new OCaml
entity, l, ie a brand new allocation on the heap, and then, messing around
with !myref inside myfun would be of course 100% safe. Is that what OCaml
runtime does?

Nevertheless, I don’t like OCaml runtime producing segfaults. What makes the
debugging process - and therefore the development process - deterministic is
precisely the ability to get the cause of every compile time/runtime error.
OCaml is pretty good at compile time and no doubt the typechecking feature
is useful. In an ideal world, OCaml should also classify runtime errors
nicely or throw nice stacktraces. I guess that was at least the original
design goal of the OCaml team but I may be wrong.

Ivan




-----Original Message-----
From: Cedric Auger [mailto:Cedric.Auger@lri.fr] 
Sent: vendredi 7 août 2009 20:20
To: ivan chollet
Subject: Re: [Caml-list] ocaml sefault in bytecode: unanswered questions

ivan chollet a écrit :
>
> Hello guys,
>
> I would like to ask a question about ocaml error handling. Actually 
> many questions that I’ve never dared asking on the official mailing 
> list. I’ve had a few problems sparsely with OCaml bytecode programs 
> throwing a core dump. When analyzing these core dumps, gdb says it’s a 
> “Segmentation fault”. Here is an example of this:
>
> This GDB was configured as "i386-marcel-freebsd"...(no debugging 
> symbols found)...
>
> Core was generated by `ocamlrun'.
>
> Program terminated with signal 11, Segmentation fault.
>
> Reading symbols from /lib/libm.so.5...(no debugging symbols found)...done.
>
> Loaded symbols for /lib/libm.so.5
>
> Reading symbols from /lib/libncurses.so.7...(no debugging symbols 
> found)...done.
>
> Loaded symbols for /lib/libncurses.so.7
>
> Reading symbols from /lib/libc.so.7...(no debugging symbols found)...done.
>
> Loaded symbols for /lib/libc.so.7
>
> Reading symbols from /usr/local/lib/ocaml/stublibs/dllunix.so...(no 
> debugging symbols found)...done.
>
> Loaded symbols for /usr/local/lib/ocaml/stublibs/dllunix.so
>
> Reading symbols from /libexec/ld-elf.so.1...(no debugging symbols 
> found)...done.
>
> Loaded symbols for /libexec/ld-elf.so.1
>
> #0 0x080606de in caml_interprete ()
>
> Not very informative. So here are my questions:
>
> - What is the best way to produce and analyze core dumps in ocaml? 
> Should I compile in bytecode or native? Is there any special gdb 
> “trick” that gives you more information? Is there any special “trick” 
> while compiling the ocaml runtime to make it throw more information?
>
> - Then, my main question is actually: in bytecode, what can produce 
> segfaults? My ocaml code is completely standard, excepted that I use 
> the Marshal module. So my question is rather: outside the Marshal 
> module, what can cause segfault?
>
About any binding can cause segfaults, if the binded library is not 
'safe', what library did you use?
For Marshall I am not expert; but I know it will likely produce 
segfaults if you are not careful, was the marshall producucer compiled 
with the same version as the marshall user? (I am not sure to be very 
clear...) and check the types produced and those used
>
> - Slightly unrelated question: I have been able to generate segfaults 
> by running ocaml code that: 1) iterates recursively through a list 
> reference 2) changes the reference while still iterating on it. For 
> example, you just do a “List.iter myfun !myref”, and within the 
> function myfun, you do stuff like “myref := List.filter 
> somefilterfunction !myref”. It is not good to program like this, but 
> for some reason I thought ocaml would not segfault on that. Is this 
> expected behavior? If it’s not, I’ll be happy to provide some simple 
> source code that illustrates it. (nevermind I have actually cleaned 
> all my code base from these dirty uses of references)
>
I am not shocked by the segfault (I am a lot more by your code), try 
rather “let l = !myref in List.iter myfun l”
>
> - About ocaml bytecode interpreter and ocaml native compiler: it seems 
> to me, looking at the ocaml source tree, that these two parts are 
> completely unrelated (I’m talking about the byterun and the 
> asmrun/asmcomp directories), meaning that they don’t share any source 
> code. Is that correct?
>
> Anyway guys, thanks for reading this, if you did, don’t know if this 
> makes any sense to you.
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>   


-- 
Cédric AUGER

Univ Paris-Sud, Laboratoire LRI, UMR 8623, F-91405, Orsay



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] ocaml sefault in bytecode: unanswered questions
  2009-08-08  9:17 [Caml-list] ocaml sefault in bytecode: unanswered questions ivan chollet
@ 2009-08-08 13:29 ` Edgar Friendly
  2009-08-08 14:15   ` ivan chollet
  0 siblings, 1 reply; 5+ messages in thread
From: Edgar Friendly @ 2009-08-08 13:29 UTC (permalink / raw)
  To: ivan chollet; +Cc: 'Cedric Auger', caml-list

ivan chollet wrote:
> You basically state that stuff like “let l = !myref in List.iter myfun l”
> (where myfun modifies !myref) wouldn't produce segfault. 
> Why? It would mean that doing "let l = !myref" creates a brand new OCaml
> entity, l, ie a brand new allocation on the heap, and then, messing around
> with !myref inside myfun would be of course 100% safe. Is that what OCaml
> runtime does?

when you have [myref : list ref = ref [1;2]], this is in memory as:

myref -> {contents: _a}
_a -> (1,_b)
_b -> (2,0)

I've given names to the intermediate pointers -- the notation above
shows names as pointers to data structures.  [myref] is a pointer to a
record, whose contents point to the head of the list [1;2].  So there's
already two levels of indirection.

When you do [let l = !myref], [l] gets assigned [_a], so it points to
the head of the list.  List.iter traverses the list not even knowing
that [myref] exists, so if the function [myfun] modifies [myref], it
won't affect List.iter.

Does this make sense?

E


^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [Caml-list] ocaml sefault in bytecode: unanswered questions
  2009-08-08 13:29 ` Edgar Friendly
@ 2009-08-08 14:15   ` ivan chollet
  2009-08-08 17:14     ` David Allsopp
  0 siblings, 1 reply; 5+ messages in thread
From: ivan chollet @ 2009-08-08 14:15 UTC (permalink / raw)
  To: 'Edgar Friendly'; +Cc: caml-list

Yes, makes sense. But it would mean that "List.iter myfun !myref" is not semantically equivalent to "List.iter myfun (let l=!myref in l)", therefore the expressions "let l=!myref in l" and "!myref" are not semantically equivalent.

That would be very strange!


-----Original Message-----
From: Edgar Friendly [mailto:thelema314@gmail.com] 
Sent: samedi 8 août 2009 15:29
To: ivan chollet
Cc: 'Cedric Auger'; caml-list@yquem.inria.fr
Subject: Re: [Caml-list] ocaml sefault in bytecode: unanswered questions

ivan chollet wrote:
> You basically state that stuff like “let l = !myref in List.iter myfun l”
> (where myfun modifies !myref) wouldn't produce segfault. 
> Why? It would mean that doing "let l = !myref" creates a brand new OCaml
> entity, l, ie a brand new allocation on the heap, and then, messing around
> with !myref inside myfun would be of course 100% safe. Is that what OCaml
> runtime does?

when you have [myref : list ref = ref [1;2]], this is in memory as:

myref -> {contents: _a}
_a -> (1,_b)
_b -> (2,0)

I've given names to the intermediate pointers -- the notation above
shows names as pointers to data structures.  [myref] is a pointer to a
record, whose contents point to the head of the list [1;2].  So there's
already two levels of indirection.

When you do [let l = !myref], [l] gets assigned [_a], so it points to
the head of the list.  List.iter traverses the list not even knowing
that [myref] exists, so if the function [myfun] modifies [myref], it
won't affect List.iter.

Does this make sense?

E


^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [Caml-list] ocaml sefault in bytecode: unanswered questions
  2009-08-08 14:15   ` ivan chollet
@ 2009-08-08 17:14     ` David Allsopp
  2009-08-09  1:45       ` ivan chollet
  0 siblings, 1 reply; 5+ messages in thread
From: David Allsopp @ 2009-08-08 17:14 UTC (permalink / raw)
  To: 'ivan chollet', 'Edgar Friendly'; +Cc: caml-list

Apologies if I'm missing something obvious (I had a good lunch)...

Ivan Chollet wrote:
> Yes, makes sense. But it would mean that "List.iter myfun !myref" is
> not semantically equivalent to "List.iter myfun (let l=!myref in l)",

How does this follow from Edgar's explanation? (below)

> therefore the expressions "let l=!myref in l" and "!myref" are not
> semantically equivalent.

These expressions are semantically equivalent: the former merely (locally) aliases the name [l] to the result [!myref] before returning it. Aliasing a value is not the same as allocating memory. For example:

let a = "1" in
let b = a;;

Results in one allocation (a value containing the string "1") and one aliasing of the name [b] to represent the same value.

So, considering your example, observe:

let myref = ref [1; 2] in
let l = !myref in
l == !myref;;

which is [true]. [l] and [!myref] are physically the same value - i.e. the [let l] expression did not result in an allocation.

Ivan Chollet previously wrote:
> Why? It would mean that doing "let l = !myref" creates a brand new OCaml entity, l, ie a brand new 
> allocation on the heap, and then, messing around with !myref inside myfun would be of course 100% safe. 

Two problems: firstly, let l = !myref does not result in an allocation (because [l] is simply an alias for the contents of myref at the time of the [let]). Secondly, you cannot mess around with !myref - the content of a reference is immutable, it is only the reference itself which can be changed (notwithstanding 'a ref ref and so on). Once you said [List.iter myfun !myref], you pass the contents of [myref] to [List.iter] and [myfun] can do whatever it likes with the *reference* [myref] without affecting those contents at that point and so the processing of [List.iter].

Do you have an actual case which segfaults?

HTH,


David 

> 
> That would be very strange!
> 
> 
> -----Original Message-----
> From: Edgar Friendly [mailto:thelema314@gmail.com]
> Sent: samedi 8 août 2009 15:29
> To: ivan chollet
> Cc: 'Cedric Auger'; caml-list@yquem.inria.fr
> Subject: Re: [Caml-list] ocaml sefault in bytecode: unanswered
> questions
> 
> ivan chollet wrote:
> > You basically state that stuff like “let l = !myref in List.iter
> myfun l”
> > (where myfun modifies !myref) wouldn't produce segfault.
> > Why? It would mean that doing "let l = !myref" creates a brand new
> OCaml
> > entity, l, ie a brand new allocation on the heap, and then, messing
> around
> > with !myref inside myfun would be of course 100% safe. Is that what
> OCaml
> > runtime does?
> 
> when you have [myref : list ref = ref [1;2]], this is in memory as:
> 
> myref -> {contents: _a}
> _a -> (1,_b)
> _b -> (2,0)
> 
> I've given names to the intermediate pointers -- the notation above
> shows names as pointers to data structures.  [myref] is a pointer to a
> record, whose contents point to the head of the list [1;2].  So there's
> already two levels of indirection.
> 
> When you do [let l = !myref], [l] gets assigned [_a], so it points to
> the head of the list.  List.iter traverses the list not even knowing
> that [myref] exists, so if the function [myfun] modifies [myref], it
> won't affect List.iter.
> 
> Does this make sense?
> 
> E
> 
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs


^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [Caml-list] ocaml sefault in bytecode: unanswered questions
  2009-08-08 17:14     ` David Allsopp
@ 2009-08-09  1:45       ` ivan chollet
  0 siblings, 0 replies; 5+ messages in thread
From: ivan chollet @ 2009-08-09  1:45 UTC (permalink / raw)
  To: 'David Allsopp'; +Cc: caml-list

Hello David,

I was just saying that because Edgar seemed to imply that "let l = !myref in List.iter myfun l" behaved differently than "List.iter myfun !myref" but you think they behave the same. 
It's fine for me.

Thanks!

-----Original Message-----
From: David Allsopp [mailto:dra-news@metastack.com] 
Sent: samedi 8 août 2009 19:15
To: 'ivan chollet'; 'Edgar Friendly'
Cc: caml-list@yquem.inria.fr
Subject: RE: [Caml-list] ocaml sefault in bytecode: unanswered questions

Apologies if I'm missing something obvious (I had a good lunch)...

Ivan Chollet wrote:
> Yes, makes sense. But it would mean that "List.iter myfun !myref" is
> not semantically equivalent to "List.iter myfun (let l=!myref in l)",

How does this follow from Edgar's explanation? (below)

> therefore the expressions "let l=!myref in l" and "!myref" are not
> semantically equivalent.

These expressions are semantically equivalent: the former merely (locally) aliases the name [l] to the result [!myref] before returning it. Aliasing a value is not the same as allocating memory. For example:

let a = "1" in
let b = a;;

Results in one allocation (a value containing the string "1") and one aliasing of the name [b] to represent the same value.

So, considering your example, observe:

let myref = ref [1; 2] in
let l = !myref in
l == !myref;;

which is [true]. [l] and [!myref] are physically the same value - i.e. the [let l] expression did not result in an allocation.

Ivan Chollet previously wrote:
> Why? It would mean that doing "let l = !myref" creates a brand new OCaml entity, l, ie a brand new 
> allocation on the heap, and then, messing around with !myref inside myfun would be of course 100% safe. 

Two problems: firstly, let l = !myref does not result in an allocation (because [l] is simply an alias for the contents of myref at the time of the [let]). Secondly, you cannot mess around with !myref - the content of a reference is immutable, it is only the reference itself which can be changed (notwithstanding 'a ref ref and so on). Once you said [List.iter myfun !myref], you pass the contents of [myref] to [List.iter] and [myfun] can do whatever it likes with the *reference* [myref] without affecting those contents at that point and so the processing of [List.iter].

Do you have an actual case which segfaults?

HTH,


David 

> 
> That would be very strange!
> 
> 
> -----Original Message-----
> From: Edgar Friendly [mailto:thelema314@gmail.com]
> Sent: samedi 8 août 2009 15:29
> To: ivan chollet
> Cc: 'Cedric Auger'; caml-list@yquem.inria.fr
> Subject: Re: [Caml-list] ocaml sefault in bytecode: unanswered
> questions
> 
> ivan chollet wrote:
> > You basically state that stuff like “let l = !myref in List.iter
> myfun l”
> > (where myfun modifies !myref) wouldn't produce segfault.
> > Why? It would mean that doing "let l = !myref" creates a brand new
> OCaml
> > entity, l, ie a brand new allocation on the heap, and then, messing
> around
> > with !myref inside myfun would be of course 100% safe. Is that what
> OCaml
> > runtime does?
> 
> when you have [myref : list ref = ref [1;2]], this is in memory as:
> 
> myref -> {contents: _a}
> _a -> (1,_b)
> _b -> (2,0)
> 
> I've given names to the intermediate pointers -- the notation above
> shows names as pointers to data structures.  [myref] is a pointer to a
> record, whose contents point to the head of the list [1;2].  So there's
> already two levels of indirection.
> 
> When you do [let l = !myref], [l] gets assigned [_a], so it points to
> the head of the list.  List.iter traverses the list not even knowing
> that [myref] exists, so if the function [myfun] modifies [myref], it
> won't affect List.iter.
> 
> Does this make sense?
> 
> E
> 
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-08-09  1:46 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-08  9:17 [Caml-list] ocaml sefault in bytecode: unanswered questions ivan chollet
2009-08-08 13:29 ` Edgar Friendly
2009-08-08 14:15   ` ivan chollet
2009-08-08 17:14     ` David Allsopp
2009-08-09  1:45       ` ivan chollet

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).