Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interfacing with C missing documentation and helper macros and functions #7179

Closed
vicuna opened this issue Mar 13, 2016 · 9 comments · Fixed by #11894
Closed

Interfacing with C missing documentation and helper macros and functions #7179

vicuna opened this issue Mar 13, 2016 · 9 comments · Fixed by #11894

Comments

@vicuna
Copy link

vicuna commented Mar 13, 2016

Original bug ID: 7179
Reporter: goswin
Status: acknowledged (set by @damiendoligez on 2016-03-14T13:34:46Z)
Resolution: open
Priority: normal
Severity: minor
Category: documentation
Monitored by: @jmeber

Bug description

When an ocaml function is used as callback from C code and the last thing the callback does is call a C stub returning unit and the return register happens to contain ((x & 3) == 2) then this is taken as an exception. When caml_callback() is used this carshes and when caml_callback_exn is garbage is returned from Extract_exception().

Ocaml should sanitize the return register after calling the C stub.

Steps to reproduce

% make
ocamlopt -g -c -o main.cmx main.ml
gcc -O2 -W -Wall -g -c -o stubs.o stubs.c
ocamlopt -o test main.cmx stubs.o
./test
test(0x61ea78)
fail
test: callback got exception 0x0

==> Makefile <==
ocamlopt -o $@ $+

%.cmx: %.ml
ocamlopt -g -c -o $@ $&lt;

%.o: %.c
gcc -O2 -W -Wall -g -c -o $@ $&lt;

clean:
rm -f test *.o *.cmx *.cmi *~

==> main.ml <==
external fail : unit -> unit = "fail"
external test : (unit -> unit) -> unit = "test"

let callback () =
fail ()

let () =
test callback

==> stubs.c <==
CAMLparam1(callback);
CAMLlocal1(res);
printf("%s(0x%lx)\n", PRETTY_FUNCTION, callback);
res = caml_callback_exn(callback, Val_unit);
if (Is_exception_result(res)) {
res = Extract_exception(res);
fprintf(stderr, "%s: callback got exception 0x%lx\n", PRETTY_FUNCTION, res);
}
CAMLreturn0;
}

Additional information

https://github.com/mrvn/ocam-problems/tree/false-exception

@vicuna
Copy link
Author

vicuna commented Mar 13, 2016

Comment author: mfp

AFAICS CAMLreturn0 is not supposed to be in the outermost C function
(the one called by OCaml), but only in void-returning "procedures".
Indeed, as per 19.1.2 in the manual, primitives should always be declared
with CAMLprim value and would thus use CAMLreturn(Val_unit).

@vicuna
Copy link
Author

vicuna commented Mar 14, 2016

Comment author: @mshinwell

Hmm, I wonder if all this needs is a clarification in the manual that you must use one of the macros that actually returns a value at the return point to OCaml.

@vicuna
Copy link
Author

vicuna commented Mar 14, 2016

Comment author: goswin

It does. I would like to re-title this issue to "Interfacing with C missing documentation and helper macros and functions"

I just looked over the chapter and spotted a few other things missing:

  • Nowhere in 19.1.2 does it say that returning value is a requirement. All the examples return a non-void result so that gives no hint.

  • In 19.5.1 the docs say to use CAMLreturn0 for methods returning void. It does not mention that that is not allowed for the interface between C and ocaml.

  • There is no example for CAMLreturnT.

  • CAMLnoreturn is not explained

  • Weak.t is not mentioned (see other issue)

  • 19.3.4 lists unit as Val_int(0) instead of Val_unit, true/false as Val_int but there is Val_bool, Val-true, Val_false, Val_not, Bool_val, [] not as Val_emptylist, x::xs not with Tag_cons

  • option types and references are not explained

  • mlvalues.h: Val_none and Tag_some missing, Some_val(), Is_none() or Is_some() missing

  • alloc.h: caml_alloc_some(value) missing

@vicuna
Copy link
Author

vicuna commented Mar 14, 2016

Comment author: @damiendoligez

Indeed this part of the documentation needs some work.

I've re-titled this PR.

@bschommer
Copy link
Contributor

bschommer commented May 5, 2020

I think the Interfacing with C needs some general update, since at the moment a lot of this stuff is still not documented and for example the documentation for CAMLreturn0 can lead to the impression for functions returning unit one should use void as return type and CAMLreturn0.

@github-actions
Copy link

This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.

@gasche
Copy link
Member

gasche commented May 12, 2021

This should be an easy documentation improvement: clarify the documentation of the C interface in the manual to explain that CAMLreturn0 should only be used for internal FFI procedures of type void, and that CAMLreturn(Val_unit) should be used for functions that return an OCaml unit value.

@kirisky
Copy link
Contributor

kirisky commented Oct 6, 2021

Hi @gasche! Can I take this issue?

@github-actions
Copy link

This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants