正如标题所提到的,我有一个问题,一个大项目的一个可执行文件在运行时会产生分段错误,但是正常编译而不是调试。
我们正在开发Linux SUSE服务器,代码主要是C ++。通过gdb中的bt,我已经能够看到问题发生在哪里,这让我想到了这个问题。该文件是一个自动生成的文件,多年来一直没有改变。现在的不同之处在于我们更新了第三方组件gSOAP。在更新第三方版本之前,它在调试时都正常工作。
使用调试标志,问题神奇地消失(对于像我这样的新手)。 我很抱歉,但它不可能包含很多代码,只有以下行:
/*------------------------------------------------------------.
| yynewstate -- Push a new state, which is found in yystate. |
`------------------------------------------------------------*/
yynewstate:
/* In all cases, when you get here, the value and location stacks
have just been pushed. So pushing a state here evens the stacks. */
yyssp++;
yysetstate:
*yyssp = yystate; <------------------ THIS LINE
所以,任何帮助都会受到赞赏。我实际上不明白为什么这个问题会上升以及我应该采取什么步骤来解决它。
编辑,我不希望你为我解决这个特殊情况,因为更多的是为了帮助我理解为什么在编程中会出现这种情况,我在这段代码中的情况只是一个例子。
答案 0 :(得分:4)
首先,请注意您使用的是C ++,而不是Java或任何其他可以预测程序运行的语言,甚至可以预测运行时问题。
在C ++中,事物 不可预测,就像那些语言一样。仅仅因为你的原始程序多年没有改变并不意味着该程序没有错误。这就是C ++的工作原理 - 你认为你有一个没有错误的程序,它并没有真正的错误。
从您的代码中,异常是因为yyssp
指向它不应该指向的内容,并且取消引用此指针会导致异常。这是唯一可以从您发布的代码中得出的结论。为什么指针指向它的位置?我们不知道,这是您需要通过调试发现的。
至于为什么在调试和发布中运行方式不同 - 再次,这样的错误允许程序以不可预测的方式运行。添加或删除代码,在另一台机器上运行它,使用不同的编译器选项运行它,甚至可能在下周运行它,它可能表现不同。
你应该不做的一件事 - 如果你做了一个完全不相关的代码更改并且神奇地你的程序工作,不要声明问题是修复或解决的。不 - 问题是没有修复 - 你要么掩盖了它,要么将bug移到你隐藏的代码的另一部分。每个需要这样的事情的修复必须被推理为为什么修复解决问题。
太多次,一个天真的程序员认为移动东西,添加或删除线条,宾果,事情都有效,这就成了解决方案。不要陷入那个陷阱。
答案 1 :(得分:-3)
-O2
,而在调试时它会发生变化。
使用-O0
构建库(更改makefile)提供了一个临时解决方案。