【问题标题】:Guile foreign-library-function failsGuile 外国图书馆功能失败
【发布时间】:2021-10-04 13:07:34
【问题描述】:

在运行 guile 手册中的示例时,我在运行 foreign-library-function 时偶然发现了一个错误。由于库的 elf 格式无效,它失败并打印回溯,说明 dlopen 失败。但是该库既存在于其他环境中,也可以在其他环境中使用。

重现问题的详细信息:

test.scm(直接取自手册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))

如果我执行guile -s test.scm,我会得到以下输出:

;;; 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"

为了确保有问题的文件确实存在,这里是ls -la /usr/lib64/libm.so 的输出:

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

我尝试将 sn-p 适配到的所有其他库也出现此问题。

我当前的系统正在运行

  • openSUSE Tumbleweed 20210723
  • 使用 Linux 内核 5.22.3

我使用来自官方存储库的zypper in guile 安装了guile-package。 (当前版本为 3.0.7)

我严重怀疑 openSUSE 的编译/链接设置在这里可能有问题,但既不能证实也不能使该理论无效。 - 最好既知道问题发生的原因,又知道解决方法。

【问题讨论】:

    标签: linux ffi opensuse dlopen guile


    【解决方案1】:

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

    我对Guile一无所知,但问题似乎是它试图dlopenlibm.so

    在带有 GLIBC 的 Linux 上,libm.so 是链接描述文件,而不是 ELF 文件。 真正的 ELF 库(库guile应该dlopening)是libm.so.6

    您可以看到您的libm.so(110 字节)太小而不能成为 ELF 文件。如果您运行file -L /usr/lib64/libm.so*,您应该会看到如下内容:

    /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
    

    您可能需要修复 system/foreign-library.scm 以便 dlopens 正确的库。

    【讨论】:

    • 是的,这似乎是有道理的。 - 非常感谢!我只是想知道为什么该语言最广为宣传的功能之一在这种标准情况下不起作用。我会进一步调查,看看我是否可以干预 foreign-library.scm 以使其工作并在我确定这是问题后接受您的回答。无论如何,我可能会提交一份错误报告。
    【解决方案2】:

    问题的解决方案是 libm.so 是一个链接器脚本,就像其他答案所说的那样。

    如果将“libm.so.6”而不是“libm”传递给函数,问题就解决了。

    以下是更正后的工作 sn-p。

    (define-module (math bessel)
      #:use-module (system foreign)
      #:use-module (system foreign-library)
      #:export (j0))
    
    (define j0)
    (foreign-library-function "libm.so.6" "j0"
                              #:return-type double
                              #:arg-types (list double))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-18
      • 2016-02-05
      • 1970-01-01
      • 2012-05-04
      相关资源
      最近更新 更多