<div dir="auto"><div><br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le lun. 25 mai 2020 à 13:57, Florian Margaine <<a href="mailto:florian@margaine.com">florian@margaine.com</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div><br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le lun. 25 mai 2020 à 11:57, Luís Oliveira <<a href="mailto:luismbo@gmail.com" target="_blank" rel="noreferrer">luismbo@gmail.com</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello Florian,<br>
<br>
On Sun, 24 May 2020 at 20:58, Florian Margaine <<a href="mailto:florian@margaine.com" rel="noreferrer noreferrer" target="_blank">florian@margaine.com</a>> wrote:<br>
> - CFFI loads a static foreign library, either as :grovel-wrapper or :system<br>
> - The image is dumped with the loaded library<br>
> - When restored, the runtime will try to reload those "shared" libraries and fails because the path doesn't exist on the target system<br>
<br>
Let me point out, that this is an issue for regular foreign libraries.<br>
Take cl-sqlite as an example:<br>
<br>
(define-foreign-library sqlite3-lib<br>
(:darwin (:default "libsqlite3"))<br>
(:unix (:or "libsqlite3.so.0" "libsqlite3.so"))<br>
(t (:or (:default "libsqlite3") (:default "sqlite3"))))<br>
<br>
On UNIX, (load-foreign-library 'sqlite3-lib) will attempt to load<br>
"lbsqlite3.so.0" first. If that fails, "libsqlite3.so" will be used<br>
instead. Whichever happens to succeed when building an image, is what<br>
will be retried when starting up the image. Things get worse if things<br>
like *foreign-library-directories* come into play. When that's used,<br>
the library will be loaded using an absolute path, and that's what<br>
will be retried at startup.<br>
<br>
The proper way to handle this is to close all foreign libraries before<br>
dumping an image, and reload them using load-foreign-library at<br>
startup.<br>
<br>
I think we should either (a) have load-foreign-library register these<br>
hooks or (b) somehow hook into image/runtime-op (not the static<br>
versions) to perform this unload/reload dance.<br>
<br>
We might have to be mindful that people shipping applications most<br>
likely do this dance themselves, so we might clash. For instance, we<br>
could offer this functionality as a convenient hook users can use in<br>
their dump and startup routines.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Maybe a new option in the ASDF integration? I'm a big fan of backwards compatibility.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
> Specifically for the 2nd one, CFFI provides a :c-file ASDF integration, which, when used with :static-program-op, will compile the C file into an object file (among others), load it as a foreign library, and statically link the object file with the program.<br>
<br>
For :c-file, when shipped dynamically, I think the best we can do is<br>
make sure it's reloaded by name instead of absolute path. That'd work<br>
on Windows, by placing the DLL next to the executable. Not sure what<br>
the proper way would be on UNIX.<br>
<br>
For a statically linked :c-file (or wrapper, or whatever), then we of<br>
course need to avoid reopening.<br>
<br>
I conclude that we /always/ want to close on dump. Should we just do<br>
that unconditionally?<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">This actually plays really well with the recent canary addition to cffi, as the load will be skipped for static libraries.</div></div></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Actually, the canary option implies that we know an existing ELF symbol in the foreign library, which is not possible in our case.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
As for reloading, we'd still need to distinguish between what should<br>
and shouldn't be reloaded, so I'm leaning towards your CLOSE-ON-DUMP<br>
idea but call it RELOAD-ON-RESTART (or something along those lines).<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">We don't actually need to, if we just use the canary mechanism, right?</div></div></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Still trying to think of a good way to do that. I'll likely come back with a PR.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Why do you say it implies exposing REGISTER-FOREIGN-LIBRARY? Seems<br>
like a LOAD-FOREIGN-LIBRARY option, no?<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">That was mostly for plumbing, but I'm not quite sure myself now.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Cheers,<br>
<br>
-- <br>
Luís Oliveira<br>
<a href="http://kerno.org/~luis/" rel="noreferrer noreferrer noreferrer" target="_blank">http://kerno.org/~luis/</a></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Regards,</div><div dir="auto">Florian</div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
</blockquote></div></div></div>
</blockquote></div></div></div>