正如标题所提到的,我遇到了一个问题,一个大项目的可执行文件在运行时出现分段错误,但它是正常编译的,而不是调试。
我们在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
所以,任何帮助都将不胜感激。事实上,我不明白为什么这个问题会出现,以及我应该采取什么措施来解决它
EDIT,我不希望你为我解决这个特殊的情况,因为为了更多地帮助我理解为什么在编程中会发生这种情况,我在这段代码中的情况只是一个例子。
首先,请意识到您使用的是C++,而不是Java或任何其他语言,在这些语言中,程序的运行始终是可预测的,甚至运行时问题也是可预测的。
在C++中,事情是不能像在那些语言中那样可预测的。仅仅因为你的原始程序多年没有更改,并不意味着这个程序没有错误。这就是C++的工作原理——你认为你有一个没有错误的程序,但它并不是真正没有错误的。
从您的代码来看,异常是因为yyssp
指向了它不应该指向的东西,而取消引用该指针会导致异常。这是唯一可以从你发布的代码中得出结论的东西。为什么指针指向它所在的位置?我们不知道,这是您需要通过调试来发现的。
至于为什么在调试和发布时运行方式不同——同样,像这样的错误允许程序以不可预测的方式运行。添加或删除代码,在另一台机器上运行,使用不同的编译器选项运行,甚至可能在下周运行,它的行为可能会有所不同。
有一件事你应该而不是做——如果你做了一个完全无关的代码更改,并且你的程序神奇地工作了,不要声称问题已经解决。不——问题是没有修复——你要么屏蔽了它,要么错误被转移到代码的另一部分,对你隐藏。每一个包含类似的修复都必须解释为什么修复会解决问题。
很多时候,一个天真的程序员认为移动东西,添加或删除行,宾果游戏,事情都会起作用,这就是解决问题的办法。不要落入那个陷阱。
我的团队中有人找到了一个临时解决方案,这个库是用优化标志构建的
我们的构建的默认值是-O2
,而在调试时,此更改发生了。
使用-O0
构建库(更改生成文件)提供了一个临时解决方案。