C++ 不在调试上运行时的分段

C++ 不在调试上运行时的分段,c++,segmentation-fault,debug-symbols,gsoap,C++,Segmentation Fault,Debug Symbols,Gsoap,正如标题所提到的,我有一个问题,一个大项目的一个可执行文件在运行时会出现分段错误,但它是正常编译的,而不是调试的 我们正在研究Linux SUSES服务器,代码主要是C++。通过gdb中的bt,我能够看到问题到底发生在哪里,这就引出了这个问题。该文件是自动生成的,多年未更改。现在的区别是我们已经更新了第三方组件gSOAP。在更新第三方版本之前,它在debug和not上都正常工作 有了调试标志,问题神奇地消失了(对于像我这样的新手来说)。 很抱歉,不可能包含很多代码,只有以下行: /*------

正如标题所提到的,我有一个问题,一个大项目的一个可执行文件在运行时会出现分段错误,但它是正常编译的,而不是调试的

我们正在研究Linux SUSES服务器,代码主要是C++。通过gdb中的bt,我能够看到问题到底发生在哪里,这就引出了这个问题。该文件是自动生成的,多年未更改。现在的区别是我们已经更新了第三方组件gSOAP。在更新第三方版本之前,它在debug和not上都正常工作

有了调试标志,问题神奇地消失了(对于像我这样的新手来说)。 很抱歉,不可能包含很多代码,只有以下行:

/*------------------------------------------------------------.
| 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
/*-------------------------------------------------------------------------。
|yynewstate——推送在yystate中找到的新状态|
`------------------------------------------------------------*/
yynewstate:
/*在所有情况下,当您到达这里时,值和位置会堆叠起来
刚刚被推了。因此,将一个状态推到这里会使堆栈均匀*/
yyssp++;
yysetstate:

*yyssp=yystate<首先,请认识到你使用C++,而不是java或任何其他语言,你的程序运行总是可以预测的,甚至运行时问题也是可以预测的。p> C++中,事物在语言中是不可预测的。仅仅因为您的原始程序多年没有更改,并不意味着该程序是无错误的。C++就是这样工作的——你认为你有一个无错误的程序,而且它并不是真正的无错误。p> 从您的代码中,异常是因为
yyssp
指向它不应该指向的东西,而取消引用此指针会导致异常。这是从你发布的代码中可以得出的唯一结论。为什么指针指向它所在的位置?我们不知道,这是您需要通过调试发现的

至于为什么调试和发布时的运行方式不同——同样,这样的错误会让程序以不可预测的方式运行。添加或删除代码,在另一台机器上运行,使用不同的编译器选项运行,甚至可能在下周运行,它的行为可能会有所不同

有一件事你不应该做——如果你做了一个完全无关的代码更改,并且你的程序神奇地工作了,不要声称问题已经解决了。不--问题没有解决--您要么掩盖了它,要么将错误转移到代码的另一部分,对您隐藏。每一个包含这类内容的修复都必须解释为什么修复会解决问题


很多时候,一个天真的程序员认为移动东西、添加或删除行,以及宾果游戏,这些东西都能工作,这就成了解决办法。不要落入那个陷阱。

我的团队中有人找到了一个临时解决方案, 构建此库时使用的是优化标志。
调试此更改时,构建的默认值为
-O2


使用
-O0
(更改生成文件)构建库提供了一个临时解决方案。

我们不知道
yyssp
指向的是什么,也不知道它在多大的缓冲区上漫游——如果它已经初始化的话。无法从这段小代码中分辨出发生了什么。@Paul我提到我不能包含更多的代码,问题更一般,一个程序如何在调试模式下运行良好,而在正常编译时不运行。当然,你不能从这段代码中理解,我想理解的是森林,而不是树。可能发生的原因有很多。我们可以开始随机想象其中的一些,但这不会有帮助。从
#ifdef DEBUG
块,到编译器初始化未在优化版本中初始化的调试变量,到不同的调试/发布库,再到…@thahgr,我们拥有的信息比你更少,因为你有完整的跟踪,而我们没有,你知道程序做什么,我们不做什么,你知道如果程序是多线程的,我们不知道,如果问题是零星的或可预测的,我们不知道,你可以访问完整的代码,我们也不知道。@ thHGRR我认为你应该找到一个在C++中有经验的人来帮助你。这可能是一个很容易解决的问题,但它也可能是非常微妙的问题,以至于只有有经验的人才能识别问题。Java程序并不总是可预测的。线程是不可预测行为的明显例子,但任何对外部资源的依赖都可能导致这种情况;考虑文件系统或网络连接。我们不要忘记本机方法和终结器。关键是,仅仅因为某人已经习惯了Java,我们不应该假设此人不理解非确定性程序执行。是的,线程和发生的外部事件是一回事。我所指的是未定义的行为是C++语言固有的。Java不是这样的。作为语言规范的一部分,未定义的行为在C和C++中除了太多的其他语言外没有发现。@ PaulMcKenzie,感谢大家花时间写一个广泛的答案,您已经得到了帮助,这是一个很好的答案。遗憾的是,OP认为不适合接受它,而是选择了他们自己的。这不是一个“解决方案”,不管是暂时的还是其他的。您的代码已损坏,并且随时可能损坏。事实上,您甚至没有假装解决“发布版本中的代码中断”问题,因为您现在所做的一切都不是发布版本。你的团队成员应该受到严厉的训斥……对不起,但这不是解决办法。您是否仔细阅读了我的回答,关于对代码(生成的代码或源代码)进行不相关的更改,然后事情开始“工作”了?代码不起作用——您所做的只是重新排列代码,因此现在错误已转移到其他地方。