狡猾的外国图书馆功能失败
Guile foreign-library-function fails
在 运行 guile 手册中的一个示例中,我在 运行 foreign-library-function
时偶然发现了一个错误。它失败并打印回溯,说明 dlopen 失败,因为库的 elf 格式无效。但是图书馆既存在又在其他环境中工作。
重现问题的详细信息:
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
这个问题也发生在我尝试将代码片段改编到的所有其他库中。
我当前的系统是 运行
- openSUSE 风滚草 20210723
- 使用 Linux 内核 5.22.3
我使用官方存储库中的 zypper in guile
安装了 guile
软件包。 (当前版本 3.0.7)
我严重怀疑 openSUSEs compilation/linking 设置可能有问题,但既不能证实也不能否定该理论。 - 最好既知道问题发生的原因又知道解决方法。
dlopen: file "/usr/lib64/libm.so"
我对 Guile 一无所知,但问题似乎是它试图 dlopen
libm.so
.
在 Linux 上使用 GLIBC,libm.so
是链接描述文件,而不是 ELF 文件。 real ELF 库(以及库 guile
应该 是 dlopen
ing)是 libm.so.6
。 =23=]
您可以看到您的 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
以便它 dlopen
是正确的库。
问题的解决方案是 libm.so 是一个链接描述文件,就像其他答案所说的那样。
如果将“libm.so.6”传递给函数而不是“libm”,问题就解决了。
以下是更正后的工作片段。
(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))
在 运行 guile 手册中的一个示例中,我在 运行 foreign-library-function
时偶然发现了一个错误。它失败并打印回溯,说明 dlopen 失败,因为库的 elf 格式无效。但是图书馆既存在又在其他环境中工作。
重现问题的详细信息:
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
这个问题也发生在我尝试将代码片段改编到的所有其他库中。
我当前的系统是 运行
- openSUSE 风滚草 20210723
- 使用 Linux 内核 5.22.3
我使用官方存储库中的 zypper in guile
安装了 guile
软件包。 (当前版本 3.0.7)
我严重怀疑 openSUSEs compilation/linking 设置可能有问题,但既不能证实也不能否定该理论。 - 最好既知道问题发生的原因又知道解决方法。
dlopen: file "/usr/lib64/libm.so"
我对 Guile 一无所知,但问题似乎是它试图 dlopen
libm.so
.
在 Linux 上使用 GLIBC,libm.so
是链接描述文件,而不是 ELF 文件。 real ELF 库(以及库 guile
应该 是 dlopen
ing)是 libm.so.6
。 =23=]
您可以看到您的 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
以便它 dlopen
是正确的库。
问题的解决方案是 libm.so 是一个链接描述文件,就像其他答案所说的那样。
如果将“libm.so.6”传递给函数而不是“libm”,问题就解决了。
以下是更正后的工作片段。
(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))