c++ - strtod() 的可怕错误 : glibc-2. 13 不向后兼容 glibc-2.9?

标签 c++ c linux gnu

我正在研究需要在多个不同的嵌入式平台上运行的 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 系统(带有 Debian 的 BeagleBoard xM)上,strtod() 行为不当(程序总是输出“0.000000”)。

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

root@beaglexm:/app# ./test.dynamic 1.23
Value: 0.000000
  [Dynamic linked version - WRONG!!]

root@beaglexm:/app# ./test.static 1.23
Value: 1.230000
  [Correct!!]

我还在 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 之前的数字(如上所示,可通过符号链接(symbolic link)找到)是次要版本。请参阅:link

最佳答案

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

紧随其后的数字(只有在您点击符号链接(symbolic link)后才能看到)表示次要修订。这些可以互换使用,符号链接(symbolic link)就是用来做到这一点的。该程序链接到 libc.so.6 或其他任何内容,并且在实际文件系统上,libc.so.6 是指向(例如)libc 的符号链接(symbolic link).so.6.12.

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

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

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

关于c++ - strtod() 的可怕错误 : glibc-2. 13 不向后兼容 glibc-2.9?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27221745/

相关文章:

c - respawn :1 mean in c? 是什么意思

c - 交换两个数字 - 处理器行为

c++ - 无法使用 istream 和 ostream 指针跨 Linux 管道写入

c++ - SIGBART 错误 vector<list<myClass>>

c - 在 C 中使用函数的内积

c - umount 不适用于 C 中的设备(但可以在终端中使用)

linux - kern_path() : Failed to return parent path in new 4. 4.* Linux 内核

c++ - 如何以编程方式创建 CDialog 窗口?

c++ - 如何在不使用boost的情况下创建目录?

c++ - 使用 size_type 索引从 std vector 中删除会导致编译器错误?