Linux上的Ada程序:SIGSEGV由于缺少文件?

Linux上的Ada程序:SIGSEGV由于缺少文件?,linux,ubuntu,ada,gnat,Linux,Ubuntu,Ada,Gnat,我使用以下命令在Ubuntu 5.4(GNAT 3.4)上编译了一个针对Linux的Ada程序: gnatmake -O3 myprogram -bargs -static 当我在Ubuntu机器上运行这个程序时,它运行得很好。但是在另一台机器(Linux Web服务器)上,当我尝试strace时,会收到以下错误消息: execve("./myprogram", ["./myprogram"], [/* 15 vars */]) = 0 brk(0)

我使用以下命令在Ubuntu 5.4(GNAT 3.4)上编译了一个针对Linux的Ada程序:

gnatmake -O3 myprogram -bargs -static
当我在Ubuntu机器上运行这个程序时,它运行得很好。但是在另一台机器(Linux Web服务器)上,当我尝试
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)?如何避免这个错误?编译时是否有可能将这些文件包含到程序中

这是什么意思

这意味着您的程序试图取消对
NULL
指针的引用,并导致
SIGSEGV

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

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

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

    在静态链接的应用程序中使用“initgroups”需要在运行时使用glibc版本中用于链接的共享库

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

  • 更新:

    是否可以只在程序中包含缺少的libgnat

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

    gcc ... -Wl,-Bstatic -lgnat -Wl,-Bdynamic ...
    
    我不知道如何通过
    gnatmake
    实现这一点


    另一种可能更简单的选择:您是否考虑过在服务器上安装
    libgnat-3.4.so.1

    还要记住,将在一台Linux机器(Ubuntu 5.4)上编译的程序移动到另一台(Web服务器)上可能会有不同的文件依赖关系。特别是如果它们基于不同的发行版。以下是ld.so.*文件的说明:

    尝试jimw的建议,并在Web服务器上构建程序。GNAT 3.4是较旧的版本,因此可能无法在Web服务器上使用。还请记住,俄罗斯的建议-不要使用
    -static
    标志。您可以尝试在Ubuntu上重新编译程序,而不使用
    -static
    标志,并在Web服务器上运行新版本,但这可能无法解决错误


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

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

  • 我可以建议您运行ldd这将显示依赖项
  • 如果不起作用,请修复依赖项
  • 如果重新编译,则使用-g标志稍后对其进行调试
  • 如果它仍然没有运行,请使用gdb并运行它,如果它退出,请在where中键入SIGSEV
  • 旁注:始终确保CPU“完全”相同,否则在新机器上重新编译,并将可执行文件作为二进制文件传输


    您看到的输出不一定——事实上可能不是——意味着segv和丢失的文件之间存在连接。你会一直在远处看到这种事情;只是系统在寻找一个预加载库,它可能在那里,也可能不在那里。如果程序中有调试符号,gdb是跟踪SEGV的更好工具。我已经很久没有调试ADA了,所以我不知道该怎么做。另外,你是在Web服务器上编译程序,还是复制二进制文件?如果是后者,尝试在那里构建它。我复制了二进制文件。但这是必要的,因为Web服务器上缺少GNAT。而且我不允许在那里安装新的软件包。
    ldd
    静态链接
    ,因为我使用了参数
    -static
    。感谢您提供这些一般和有用的提示!我没有看到这个警告。但是现在我重新编译了程序,没有使用
    -static
    -bargs
    标志。
    strace
    输出更长,不再包含
    SIGSEGV KILL
    。所以看起来好多了。但是当我用
    ldd
    检查依赖项时,它说
    linuxgate.so.1=>(0xffffe000)libgnat-3.4.so.1=>找不到libgcc_.so.1=>/lib/libgcc_.so.1(0xb786c000)libc.so.6=>/lib/libc.so.6(0xb7726000)/lib/ld-linux.so.2(0xb7893000)
    。我怎样才能解决这个问题?是否可以只在程序中包含缺少的
    libgnat
    ?非常感谢您的回答和添加!解决依赖关系非常重要,因为此依赖关系是我的程序的
    ldd
    输出与运行的预编译输出之间的唯一区别。因此,如果我解决了对libgnat的依赖,程序将(可能)运行。我想我发现了问题:我安装了
    gnat-3.4
    ,这取决于
    gcc-3.4
    。但是我在这个系统上不仅有
    gcc-3.4
    ,还有
    gcc-4.0
    。因此,可能编译器使用的版本4.0太新了。这可能是原因吗?那gnatlink呢?这不是要将共享库集成到编译的程序中吗?最终解决了将
    LD_library_PATH
    设置为本地目录并将缺少的依赖项放在那里的问题。非常感谢你!非常感谢。在没有
    -static
    标志的情况下编译程序有帮助。最后,复制所有缺少的依赖项并设置
    LD\u LIBRARY\u路径
    解决了这个问题