c++ - 具有相同编译器的相同程序代码会导致不同的二进制文件

标签 c++ multithreading segmentation-fault qnx

我的代码有问题,有一些非常奇怪的症状。

  1. 代码是在我的电脑上编译的,版本如下:

    一个。 GCC 版本:4.4.2

    CMAKE 版本:2.8.7

    QNX(操作系统)版本:6.5.0

并且代码在释放一些内存并退出函数时出现段错误(不会死于任何代码,只是在函数退出时)。

奇怪的是:

  1. 代码在 Release模式而非 Debug模式下执行:

    一个。代码是线程化的,因此这表明存在竞争条件。

    我无法通过将其置于 Debug模式来进行调试。

  2. 在同事机器上编译时所有的东西都相同版本的代码没有这个问题。

    一个。奇怪的是,同事的代码可以工作,而且在他的机器上编译生成的二进制文件(相同)大约大 6mB。

现在烦人的是,我无法发布代码,因为它太大而且不适合工作。但是任何人都可以指出我解决这个问题的途径。

由于我使用的是 QNX,因此我的调试工具受到限制,我无法使用 Valgrind,而且由于 QNX 不支持它,GDB 并没有真正帮助。

我正在寻找遇到类似/相同问题的任何人,以及原因是什么以及他们是如何解决的。

编辑:

Sooo...我发现了它是什么,但我仍然对它是如何发生的感到有点困惑。

罪魁祸首代码是这样的:

Eigen::VectorXd msBb = data.modelSearcher->getMinimumBoundingBox();

getMinimumBoundingBox 的定义是这样的:

Eigen::VectorXd ModelSearcher::getMinimumBoundingBox();

它返回一个始终初始化为 VectorXd output(6, 1) 的 VectorXd。于是我马上想到,对了,一定是因为VectorXd没有被初始化,而是改成了这样:

Eigen::VectorXd msBb(6, 1); msBb = data.modelSearcher->getMinimumBoundingBox();

但这没有用。事实上,我必须通过将函数的定义更改为此来修复它:

void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);

以及对此的调用

Eigen::VectorXd msBb(6, 1); data.modelSearcher->getMinimumBoundingBox(msBb);

那么现在是新问题:

什么鬼?为什么第一个更改不起作用但第二个更改起作用,为什么我必须通过引用传递?哦,还有个大问题,当我的同事编译它并运行它时,这到底是怎么回事?这是一个直接的内存错误,当然它不应该取决于哪台计算机编译它,特别是因为编译器和所有其他重要的东西都是一样的!??

感谢您的帮助。

最佳答案

... the binary created from compiling on his machine, which is the same, is about 6mB bigger

值得弄清楚有什么区别(即使只是他的构建隐藏了一个真正的错误,而你的暴露了一个真正的错误):

  • 仔细检查您正在编译完全相同的代码(没有未提交的本地更改,包含搜索路径中没有额外的标题等)
    • 通过在 cmake 中向您的 gcc 参数添加一个 -E 开关来进行三次检查,因此它将使用与常规编译相同的包含路径来预处理您的文件;区分预处理器输出
  • 比较来自 nmobjdump 的输出或任何你必须为你的两个链接的可执行文件做的事情:如果某个系统或第 3 方库在一个盒子上是不同的版本,它可能会出现在这里
  • 比较 ldd 的输出,如果它是动态链接的,确保它们都获得相同的库版本
    • 如果可能的话,也比较它实际上在运行时获得的库版本。希望您可以执行以下操作之一:运行 pldd,比较 /proc/pid/map 中的 .so 条目,在 下运行进程>strace/dtrace/truss 并比较运行时链接器事件

至于代码...如果这不起作用:

Eigen::VectorXd ModelSearcher::getMinimumBoundingBox();
// ...
Eigen::VectorXd msBb(6, 1); msBb = data.modelSearcher->getMinimumBoundingBox();

这样做:

void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);
// ...
Eigen::VectorXd msBb(6, 1); data.modelSearcher->getMinimumBoundingBox(msBb);

您可能对赋值运算符有疑问。如果它执行浅拷贝并且 vector 中有动态分配的内存,您最终会得到两个持有相同指针的 vector ,并且它们都将free/delete它。

请注意,如果根本未定义运算符,则默认执行此浅拷贝。

关于c++ - 具有相同编译器的相同程序代码会导致不同的二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13409029/

相关文章:

java - 使用显式锁是否被认为是昂贵的?

c# - 锁定困惑的串口端口句柄

java - 强制终止我不是用 Java 编写的线程

c++ - 访问 boost::unordered_multimap 或结构时很少出现段错误

c++ - 在 C 中返回 NULL 指针

c++ - 将 vector 指针传递给函数会导致段错误

c++ - 在 C++ 中计算每次调用的最佳方法是什么

c++ - 试图绘制点云,只是 opengl 中心的一个点

c - 使用 SDL_image 保存 PNG 时出现段错误

c++ - 将指针分配给指针时出现段错误