为什么在两个略有不同的机器上编译的库表现略有不同?

时间:2009-08-12 19:05:31

标签: c++ gcc libraries cross-compiling buildroot

以下是设置:

我的同事有一台带有gcc 4.3.3交叉编译器的Fedora x64_86机器(来自buildroot)。 我有一个Ubuntu 9.04 x64_86机器与相同的交叉编译器。

我的同事建立了一个可以在测试机器上运行的库+测试应用程序,我编译了相同的库和testapp,它在同一台测试机器上崩溃。

据我所知,gcc是针对buildroot编译的ucLibc构建的,所以,相同的代码,相同的编译器。哪种主机差异会影响交叉编译?

有任何见解。

更新:为了澄清,编译器是相同的。库和testapp的源代码是相同的。唯一的区别是testapp + lib已在不同的机器上编译..

6 个答案:

答案 0 :(得分:6)

如果您的代码崩溃(我假设您获得了sigsegv),则似乎存在错误。它很可能是某种未定义的行为,比如使用悬空指针或写入缓冲区边界。

未定义行为的不幸之处在于,可能在某些机器上运行。我想你在这里遇到这样的事件。尝试找到错误,你会知道会发生什么: - )

答案 1 :(得分:3)

它以什么方式崩溃?你能更具体一点,提供输出,返回代码等等吗?你试过插入一些有用的printf()吗?

而且,我认为我们还需要更多细节:

  1. testapp是否链接到库?

  2. 图书馆是静态的还是动态的?

  3. 库是否在库搜索路径中,或者您是否已将其目录添加到ld.so.conf?

  4. 您是否正在执行库和testapp的任何安装过程?

  5. 两个库和testapps是否逐位兼容?你期望他们是吗?

  6. 您是否与同事一样以相同的环境和权限运行?

答案 2 :(得分:3)

显然,有些不一样。

尝试使用objdump及其许多选项,尤其是-d,来确定不同的内容。

你没有指出它,所以我猜猜binutils是不同的。这是用于构建二进制文件的一组工具。它包括ld,as和objdump。

交叉编译器需要自己的一组binutils用于目标体系结构。但是,与GCC不同,我不相信binutils工具会执行双引导构建和验证步骤,因此可能与原始x86_64构建环境有一些不同之处。

我尝试使用ARM交叉编译器再次为ARM构建binutils包。看看是否有所作为。

这是我在常规x86 Gentoo stage1安装中看到的:在安装和更新引导系统和编译器之后,建议Gentoo用户使用更新的工具重建系统再次

答案 3 :(得分:1)

您的目标(测试机器)是什么拱门?

您使用的是分发提供的编译器吗?它们通常有一大堆补丁应用于gcc,例如在gentoo上有大约20个补丁,fedora和ubuntu不会那么不同。不是所有补丁都是100%罚款,但是:-( 所以编译器实际上可能不同。

你可能会在你的发行版中寻找一个“vanilla”版本的gcc,也许它可以解决问题。

答案 4 :(得分:1)

我认识一个在大学里有类似经历的人。基本上,在一个相同机器的实验室里,他的项目在他的开发盒上工作,但在教授盒子上可怕地崩溃。这两台机器是同一个拱门,运行相同版本的操作系统。

它归结为一个未初始化的指针。

他的代码看起来像:

if(p == NULL) {
    p = f();
}

由于p是在堆上分配的类的成员,因此它的值实际上是随机的,偶尔实际上是NULL,使得工作正常......问题是有时和在一些机器上,p的内存在程序启动时为NULL,但是在教授的框中,它不是。修复当然是正确初始化p tp NULL并且一切都很好。

你可能正在经历这样的事情。或某种类型的未定义的行为,这是一种奇特的说法,“它可能会或可能不会按预期工作,无论是否有任何理由”

答案 5 :(得分:1)

作为黑暗中的刺刀,我会寻找未初始化的变量。 确保为所有本地和全局变量分配值。 仔细检查构造函数是否具有所有数据成员的初始值设定项。