Search code examples
linuxffiopensusedlopenguile

Guile foreign-library-function fails


In running an example from the guile handbook I stumbled upon an error while running foreign-library-function. It fails and prints a backtrace stating dlopen failed, because of an invalid elf format of the library. But the library is both present and working in other contexts.

The details to reproduce the issue:

test.scm (taken straight from the manual at https://www.gnu.org/software/guile/manual/guile.html#Foreign-Functions)

(define-module (math bessel)
  #:use-module (system foreign)
  #:use-module (system foreign-library)
  #:export (j0))

(define j0)
(foreign-library-function "libm" "j0"
                          #:return-type double
                          #:arg-types (list double))

If I execute guile -s test.scm I get the following output:

;;; note: source file /home/max/projects/guile-tests/test.scm
;;;       newer than compiled /home/max/.cache/guile/ccache/3.0-LE-8-4.5/home/max/projects/guile-tests/test.scm.go
;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0
;;;       or pass the --no-auto-compile argument to disable.
;;; compiling /home/max/projects/guile-tests/test.scm
;;; compiled /home/max/.cache/guile/ccache/3.0-LE-8-4.5/home/max/projects/guile-tests/test.scm.go
Backtrace:
In ice-9/boot-9.scm:
  1752:10  8 (with-exception-handler _ _ #:unwind? _ # _)
In unknown file:
           7 (apply-smob/0 #<thunk 7f57b930ef60>)
In ice-9/boot-9.scm:
    724:2  6 (call-with-prompt _ _ #<procedure default-prompt-handle…>)
In ice-9/eval.scm:
    619:8  5 (_ #(#(#<directory (guile-user) 7f57b9307c80>)))
In ice-9/boot-9.scm:
   2835:4  4 (save-module-excursion _)
  4380:12  3 (_)
In system/foreign-library.scm:
    240:6  2 (foreign-library-function "libm" "j0" #:return-type _ # …)
   190:25  1 (load-foreign-library _ #:extensions _ # _ #:search-path …)
In unknown file:
           0 (dlopen "/usr/lib64/libm.so" 1)

ERROR: In procedure dlopen:
In procedure dlopen: file "/usr/lib64/libm.so", message "/usr/lib64/libm.so: Ungültiger ELF-Header"

To ensure the file in question is actually there here's the output of ls -la /usr/lib64/libm.so:

-rw-r--r-- 1 root root 110 20. Jun 19:52 /usr/lib64/libm.so

The problem also occured for all other libraries I tried to adapt the snippet to.

My current system is running on

  • openSUSE Tumbleweed 20210723
  • with Linux kernel 5.22.3

I installed the guile-package using zypper in guile from the official repositories. (currently version 3.0.7)

I heavily suspect that openSUSEs compilation/linking settings could be at fault here, but can neither confirm nor invalidate that theory. - It would be ideal to both know why the issue occurs as well as knowing a workaround.


Solution

  • dlopen: file "/usr/lib64/libm.so"

    I don't know anything about Guile, but the problem appears to be that it is trying to dlopen libm.so.

    On Linux with GLIBC, libm.so is a linker script, not an ELF file. The real ELF library (and the library guile should be dlopening) is libm.so.6.

    You can see that your libm.so (at 110 bytes) is way too small to be an ELF file. If you run file -L /usr/lib64/libm.so*, you should see something like this:

    /usr/lib64/libm.so:   ASCII text
    /usr/lib64/libm.so.6: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=07ae52cfc7f4eda1d13383c04564e3236e059993, for GNU/Linux 3.2.0, stripped
    

    Possibly you need to fix system/foreign-library.scm so it dlopens correct library.