9

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

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

    一种。GCC 版本:4.4.2

    湾。CMAKE 版本:2.8.7

    C。QNX(操作系统)版本:6.5.0

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

这件事的奇怪之处在于:

  1. 代码在发布模式而不是调试模式下执行:

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

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

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

    一种。奇怪的是,同事的代码可以工作,而且在他的机器上编译创建的二进制文件也是一样的,大约大 6mB。

现在烦人的是我不能发布代码,因为它太大而且也不能工作。但是任何人都可以指出我解决这个问题的道路。

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

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

编辑:

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

罪魁祸首是这样的:

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

的定义getMinimumBoundingBox是这样的:

Eigen::VectorXd ModelSearcher::getMinimumBoundingBox();

它返回一个 VectorXd,它总是初始化为VectorXd output(6, 1). 所以我立刻想到,这一定是因为 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);

所以现在新的问题:

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

谢谢你们的帮助。

4

2 回答 2

8

...在他的机器上编译创建的二进制文件是相同的,大约大 6mB

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

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

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

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);

您可能对赋值运算符有问题。如果它做了一个浅拷贝并且向量中有动态分配的内存,你最终会得到两个持有相同指针的向量,它们都会free/delete它。

请注意,如果根本没有定义操作符,则默认是执行这个浅拷贝。

于 2012-11-20T10:11:40.677 回答
0

你说你必须改变:

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

以前是什么?

如果它是:

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

并且复制构造函数/赋值运算符没有正确实现,它可能会导致问题。

请检查它们是如何实现的。这里有一些信息可能会有所帮助。

于 2012-11-20T09:07:04.960 回答