Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Alexey Rodriguez <alexey@vectorfabrics.com>
To: David Allsopp <dra-news@metastack.com>
Cc: "caml-list@inria.fr" <caml-list@inria.fr>
Subject: Re: [Caml-list] Exception values may crash GC when interfacing C and Caml
Date: Wed, 2 May 2012 16:37:19 +0200	[thread overview]
Message-ID: <CAHg28AXwNnw23-YOYBN_jwNfp5xp1Wwc3a_M+azHW6Y8oq_pyQ@mail.gmail.com> (raw)
In-Reply-To: <E51C5B015DBD1348A1D85763337FB6D9C299E98C@Remus.metastack.local>

[-- Attachment #1: Type: text/plain, Size: 2629 bytes --]

I added a warning to the documentation. Can someone with commit rights
have a look at it and apply it? This would have definitely saved us a
lot of time. And I am sure this will help other people too.

Cheers,

Alexey

On Wed, May 2, 2012 at 1:28 PM, David Allsopp <dra-news@metastack.com> wrote:
> Alexey Rodriguez wrote:
>> Dear all,
>>
>> We are experiencing crashes in Caml-calling C code. This happens if
>> garbage collection runs after Caml code has raised an exception. We now
>> understand why this happens but we are puzzled as to why the "Interfacing
>> C with Ocaml" chapter of the Ocaml manual doesn't warn about this
>> situation.
>>
>> Suppose you have C code that calls Caml code as follows:
>>
>> ...
>> CAMLparam2(v1,v2);
>> CAMLlocal2(...,res);
>> res = callback2_exn(...,v1,v2);
>> foobar();
>> ...
>>
>> We have found that this code will crash with "Fatal error: out of memory."
>> if the following two things happen:
>> * the function called by [callback2_exn] raises an exception, and
>> * [foobar] triggers a garbage collection through the allocation of values
>> in the Caml heap. (just calling [caml_gc_full_major] is enough to cause
>> the crash).
>>
>> The reason for this crash is that [res] will contain an invalid pointer if
>> an exception is thrown. The GC follows this bogus pointer ([res] is
>> registered as a root by [CAMLlocal2]) which ultimately causes a crash in
>> the GC code. Why does [res] contain a bogus pointer?
>> It's not really a bogus pointer, but the lower bits are tagged in order to
>> denote a thrown exception. These bits are usually tested/cleared by
>> [Is_exception_result] and [Extract_exception].
>
> This is already in the manual, but I agree that the requirement to do so could be stated more clearly. Section 18.7.1[1], last paragraph states "The return v of the caml_callback*_exn function **must** be tested with the macro Is_exception_result(v)". It also clearly indicates that v is only a valid [value] if Is_exception_result(v) returns false so storing the return of caml_callback*_exn in a local root and allowing the Gc to run before you update that root with the result of Extract_exception is "obviously" a Gc violation.
>
>
> David
>
> [1] http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html#htoc245



-- 
dr. Alexey Rodriguez Yakushev

Vector Fabrics included in EE Times 'Silicon 60' list of emerging startups

O +31 (0)40 8200960   |  D + 31 (0)40 8200974  |  F +31 (0)40 8200979
Vonderweg 22, 5616 RM  |  Eindhoven |  The Netherlands
www.vectorfabrics.com  |  alexey@vectorfabrics.com

[-- Attachment #2: warning_exception.patch --]
[-- Type: application/octet-stream, Size: 818 bytes --]

Index: manual/cmds/intf-c.etex
===================================================================
--- manual/cmds/intf-c.etex	(revision 12413)
+++ manual/cmds/intf-c.etex	(working copy)
@@ -1273,6 +1273,12 @@
 an exception escaped, and its value (the exception descriptor) can be
 recovered using "Extract_exception("\var{v}")".
 
+\paragraph{Warning:} If an exception did escape the OCaml function, \var{v}
+does not contain a valid value. It follows that prior to calling a memory-allocating
+function, \var{v} should not be reachable by the garbage collector. For instance,
+\var{v} should not be assigned to a variable declared with one of the "CAMLlocal*"
+macros.
+
 \subsection{Obtaining or registering OCaml closures for use in C functions}
 
 There are two ways to obtain OCaml function values (closures) to

  reply	other threads:[~2012-05-02 14:37 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-05-02 11:18 Alexey Rodriguez
2012-05-02 11:28 ` David Allsopp
2012-05-02 14:37   ` Alexey Rodriguez [this message]
2012-05-02 19:37     ` Wojciech Meyer
2012-05-03  9:21       ` Alexey Rodriguez

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAHg28AXwNnw23-YOYBN_jwNfp5xp1Wwc3a_M+azHW6Y8oq_pyQ@mail.gmail.com \
    --to=alexey@vectorfabrics.com \
    --cc=caml-list@inria.fr \
    --cc=dra-news@metastack.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox