【问题标题】:Horrid error with strtod(): glibc-2.13 NOT backwards compatible with glibc-2.9?strtod() 的可怕错误:glibc-2.13 不向后兼容 glibc-2.9?
【发布时间】:2015-01-29 01:35:07
【问题描述】:

我正在开发需要在几个不同的嵌入式平台上运行的 C 和 C++ 程序,为此我有交叉编译器,因此我可以在我的 x86 桌面上进行构建。

我对某些功能有一个可怕的问题,例如“strtod()”。这是我的简单测试程序:

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv)
  {
  if ( (argc < 2) || (NULL == argv[1]) ) return 0; 
  double myDouble = strtod(argv[1], NULL);
  printf("\nValue: %f\n\n", myDouble);
  return 0;
  }

通常我使用动态链接构建所有程序以使二进制文件尽可能小。以上在 x86 和 Power PC 上运行良好。然而,在 Arm 系统(BeagleBoard xM with Debian)上,strtod() 行为异常(程序总是输出“0.000000”)。

我尝试使用选项“-static”构建程序,并且在 Beagle 上有效:

root@beaglexm:/app# ./test.dynamic 1.23 值:0.000000 [动态链接版本-错误!!] root@beaglexm:/app# ./test.static 1.23 价值:1.230000 [正确的!!]

我还在 BeagleBone Black 上进行了测试,它的分布略有不同。两个版本(静态和动态)都在 BBB 上运行良好。

在库中挖掘,我发现了以下版本号:

交叉编译器工具链:libc-2.9.so

BeagleBoard XM(不工作):libc-2.13.so

BeagleBone Black(工作!):libc-2.16.so

所以我的交叉编译器是针对旧版本的 glibc 构建的。我在几个地方读过 glibc 应该向后兼容

我考虑过只静态链接 libc,但根据this question,除非所有库都静态链接,否则这是一个坏主意。

静态链接一切都有效,但系统受到严重限制,这意味着我需要使二进制文件尽可能小。

有什么想法会导致 strtod() (和类似函数)出现可怕的问题和/或为什么 glibc 2.13 不向后兼容?

编辑: 我没有提到“soname”(即顶级名称)在所有平台上都是相同的:“libc.so.6”根据我对文档的阅读,“soname”中 .so 之后的数字是主要版本,并且仅在接口更改时才更改-因此所有这些版本都应该兼容。实际文件名中出现的 .so 之前的数字(如上所示,可通过符号链接找到)是次要版本。见:link

【问题讨论】:

    标签: c++ c linux gnu


    【解决方案1】:

    通常版本号反映了兼容性。 .so 和下一个点之间出现的数字代表主要版本,不保证与任何其他主要版本兼容。

    后面的数字(只有在您跟随符号链接时才会看到)代表次要修订。这些可以互换使用,而符号链接就是用来做到这一点的。该程序链接到libc.so.6 或其他任何东西,在实际文件系统上,libc.so.6 是指向(例如)libc.so.6.12 的符号链接。

    glibc 即使在主要版本之间也试图保持兼容性,但有时他们只需要接受重大更改。这通常发生在新版本的 C 或 POSIX 标准发布并且函数签名以破坏二进制兼容性的方式更新时。

    任何出现在.so 之前的数字如果更改也会破坏兼容性;这些通常代表对程序的完全重写。例如glibglib2。与 libc 无关。

    ldd 工具对于调查库依赖关系和发现库的确切版本何时实际加载非常有用。

    【讨论】:

    • 虽然我不能不同意你的回答,但它几乎不能回答问题。
    • @rubenvb:当然可以。 "为什么 glibc 不能向后兼容?因为 C 标准的新版本"
    • 我没有提到“soname”(即顶级名称)在所有平台上都是相同的:“libc.so.6”根据我对文档的阅读,你有你的版本号绕错路。请参阅我添加到问题中的评论。当我读到它时,它们应该都是兼容的。
    • @Jeremy:这些“数字错误的方式”直接来自您的问题,尽管您是对的,但我在解释中也遇到了一些问题。是的,如果它们都是libc.so.6.x,那么它们应该保持兼容性。有人没有注意到其中一项更改是重大更改,因此没有滚动主要库编号。
    • 嘿,这是我的怀疑 - 即“它不起作用,因为它坏了”。仍然希望我遗漏了一些东西并且有一个简单的修复方法,但目前正在尝试为有问题的平台获取确切的工具链,看看是否可行。
    猜你喜欢
    • 2022-08-07
    • 2016-06-22
    • 2011-07-14
    • 2012-06-21
    • 2016-12-09
    • 1970-01-01
    • 2015-07-20
    • 2014-12-28
    • 2016-11-03
    相关资源
    最近更新 更多