3

我使用以下命令在 Ubuntu 5.4 (GNAT 3.4) 上为 Linux 编译了 Ada 程序:

gnatmake -O3 myprogram -bargs -static

然后,当我在 Ubuntu 机器上运行该程序时,它运行良好。但是在另一台机器(Linux 网络服务器)上,当我尝试时收到以下错误消息strace

execve("./myprogram", ["./myprogram"], [/* 15 vars */]) = 0
brk(0)                                  = 0x811e000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76f8000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76f7000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb76f7680, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++

这意味着什么?我是否正确理解程序无法运行是因为缺少两个文件(ld.so.nohwcap 和 ld.so.preload)?我怎样才能避免这个错误?编译时是否有可能将这些文件包含到程序中?

4

3 回答 3

4

这意味着什么?

这意味着您的程序试图取消引用NULL指针并死于SIGSEGV

我是否正确理解程序无法运行是因为缺少两个文件(ld.so.nohwcap 和 ld.so.preload)?

不:这些文件不存在是完全正常的,您的问题与它们无关。

  1. 调试此类问题的工具是gdb. strace对这种调试很少有用。
  2. 与流行的看法相反,完全静态的可执行文件(如您构建的那个)在 Linux 上的可移植性较差,然后是动态链接的可执行文件。特别是,您可能在链接时收到警告,类似于此:

    Using 'initgroups' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

    如果是这样,并且如果您的构建和网络服务器机器上安装的 glibc 版本不同,那么这正是您的问题。不要忽略此类警告(并且不要将您的可执行文件与-static标志链接)。

更新:

是否可以仅将缺少的 libgnat 包含到程序中?

有可能:您要做的是安排最终的链接行如下所示:

gcc ... -Wl,-Bstatic -lgnat -Wl,-Bdynamic ...

我不知道如何用gnatmake.

另一个可能更简单的替代方案:您是否考虑libgnat-3.4.so.1过在服务器上安装?

于 2012-04-12T04:01:37.853 回答
2

您从 strace 看到的输出是尝试在库中链接的动态链接器

  1. 我可以向您推荐运行ldd这将向您显示依赖项
  2. 修复依赖项,如果这不起作用
  3. 如果您重新编译它,请使用 -g 标志稍后对其进行调试
  4. 如果它仍然没有运行,请使用 gdb 并运行它,如果它使用 SIGSEV 类型退出 where

旁注:始终确保 CPU“完全”相同,否则在新机器上重新编译它并将可执行文件作为二进制文件传输

很好读的手册页

于 2012-04-12T04:57:01.930 回答
1

另请记住,将在一台 Linux 机器(Ubuntu 5.4)上编译的程序移动到另一台(网络服务器)可能具有不同的文件依赖关系。特别是如果它们基于不同的发行版。这是 ld.so.* 文件的描述:滚动到底部

尝试 jimw 的建议并在网络服务器上构建程序。GNAT 3.4 是旧版本,因此它可能无法在网络服务器上使用。还请记住,受雇俄罗斯人的建议 - 不要使用-static国旗。您可以尝试在没有标志的情况下在 Ubuntu 上重新编译您的程序-static并在网络服务器上运行新版本,但这可能无法解决错误。

如果在网络服务器上重新编译和/或编译它不起作用,你将不得不使用 gdb 来调试你的程序。或者您可以在此处发布部分代码,看看是否有人可以帮助您。

于 2012-04-12T04:36:36.043 回答