[Larceny-users] Another wee FFI question

Felix Klock felixluser at pnkfx.org
Wed Jan 2 12:38:39 EST 2008


David-

On Jan 1, 2008, at 6:22 PM, David Rush wrote:

> I have wrapped libfcgi in a slightly more lisp-friendly garment, but  
> I've had difficulties getting the Apache server to find the shared  
> object when I run my C test harness in the web-root. So I've become  
> curious about the fate of DLLs referenced through the (foreign-file  
> " foo.so") form when you dump the Larceny heap.
>
> I imagine it would be too much to hope that it will all magically  
> work? I presume it's something more like that you must bind the .so  
> and the foreign functions at run-time, each time - but a precise  
> description of the rules would help.
>
> (I didn't see an obvious answer to this in the source tree docs, so  
> a pointer to my blind spot would also be appreciated)


My understanding is that Lars designed the (upper level of the) FFI so  
that a dumped heap remembers what shared objects were loaded at the  
time of the dumping, and the objects would be reloaded when you load  
the heap.

The code in charge of this magic is in lib/Ffi/ffi-upper.sch.  The  
invocation at the end of that file, (add-init-procedure! ffi/ 
initialize-after-load-world), registers a procedure that will attempt  
to relink all of the foreign procedures, and I believe this relinking  
process will also attempt to reload the shared objects.

I do not think we exercise this code very much.  I cannot vouch for  
its correctness in general; but here is a demonstration of the magic  
in action (note in particular the sensitivity of the final two  
executions of ./larceny on the presence of the foo.dylib file).

% cat foo.c
#include <stdio.h>

int fib(int n) { switch (n) { case 0: case 1: return 1; default:  
return fib(n-1)+fib(n-2); } }
int fact(int n) { switch (n) { case 0: return 1; default: return  
n*fact(n-1); } }
int main() { printf("fib(10): %d\n", fib(10)); }
% gcc -dynamic -c -o foo.o foo.c; ld -bundle /usr/lib/bundle1.o - 
flat_namespace -undefined suppress -o foo.dylib foo.o
% LD_LIBRARY_PATH="`pwd`" ./larceny -stopcopy -- -e '(foreign-file  
"foo.dylib")' -e '(define cfact (foreign-procedure "fact" (quote  
(int)) (quote int)))' -e '(begin (display `((cfact 12): ,(cfact 12)  
(cfact 18): ,(cfact 18))) (newline))' -e '(dump-interactive-heap  
"foo.heap")' -e '(exit)'
Larceny v0.951 "First Safety" (Dec 12 2007 23:36:17, precise:Posix  
Unix:unified)
((cfact 12) : 479001600 (cfact 18) : -898433024)
; Dumping heap...
; Done.
% ./larceny -heap foo.heap -- -e '(begin (display `((cfact 12): , 
(cfact 12) (cfact 18): ,(cfact 18))) (newline))' -e '(exit)'
Larceny v0.951 "First Safety" (Dec 12 2007 23:36:17, precise:Posix  
Unix:unified)
((cfact 12) : 479001600 (cfact 18) : -898433024)
% rm foo.dylib
% ./larceny -heap foo.heap -- -e '(begin (display `((cfact 12): , 
(cfact 12) (cfact 18): ,(cfact 18))) (newline))' -e '(exit)'
Larceny v0.951 "First Safety" (Dec 12 2007 23:36:17, precise:Posix  
Unix:unified)
dlopen error: dlopen(foo.dylib, 5): image not found
ffi/load-libraries: foo.dylib can't be opened.


Error: ffi/find-procedure: procedure : fact  can't be found.
Entering debugger; type "?" for help.
debug>


-Felix




More information about the Larceny-users mailing list