与strtod()的可怕错误:glibc-2.13不向后兼容glibc-2.9?

时间:2014-12-01 04:32:03

标签: c++ c linux gnu

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

我对某些功能有一个可怕的问题,例如"关于strtod()&#34 ;.这是我的简单测试程序:

#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()行为异常(程序始终输出&#34; 0.000000&#34;)。

我尝试使用选项&#39; -static&#39;来构建程序,这对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(DOESN&#39; T WORK): libc-2.13.so

BeagleBone Black(WORKS!): libc-2.16.so

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

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

静态链接一切都有效,但是系统存在严重的限制,这意味着我需要保持二进制文件尽可能小。

任何想法会导致strtod()(和类似函数)和/或为什么glibc 2.13不向后兼容?

修改 我没有提到&#34; soname&#34; (即顶级名称)在所有平台上都是相同的:&#34; libc.so.6&#34;从我阅读的文档中,在#son;#34;中的.so之后的数字。是主要版本,只有在接口更改时才会更改 - 因此所有这些版本都应该兼容。出现在实际文件名中的.so之前的数字(如上所示,通过符号链接找到)是次要版本。请参阅:link

1 个答案:

答案 0 :(得分:3)

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

随后的数字(如果您遵循符号链接,您只能看到它)代表MINOR修订版。这些可以互换使用,符号链接用于实现这一点。该程序链接libc.so.6或其他任何内容,在实际文件系统上,libc.so.6是(例如)libc.so.6.12的符号链接。

glibc尝试在主要版本中保持兼容性,但有时候他们只需要接受一个重大变化。通常情况下,会发布新版本的C或POSIX标准,并以破坏二进制兼容性的方式更新功能签名。

.so之前出现的任何数字如果更改,也会破坏兼容性;这些通常代表完整的程序重写。例如glib vs glib2。不关心libc。

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