运行'堆栈溢出'错误

时间:2009-12-03 13:20:56

标签: delphi stack-overflow

我有一个用Delphi W32编写的测试版。

在测试PC上,它会在使用几个小时后随意发出“堆栈溢出”消息。

如何捕获错误并查找原因?

我可以增加堆栈大小吗?

6 个答案:

答案 0 :(得分:15)

您应该在链接器选项中减少堆栈大小。然后在调试器下运行它,希望问题会出现,而不必等待两个小时。

答案 1 :(得分:13)

获取madExcept,它会告诉您故障发生时到底发生了什么。你会看到完整的堆栈,特别是它正在逃跑的地方。

答案 2 :(得分:6)

我几乎要说:在调试器中运行它; ^)

我以前做的是在每种方法中添加进入和离开日志功能。通过适当的缩进,我可以在日志中跟踪调用路径。

当发生堆栈溢出时,它会在日志中显示,因为缩进级别应该通过屋顶

 void someMethod()
 {
      logMethodEnter("someMethod");

      ... do stuff...
      log("something")
      ... do stuff...

      logMethodLeave("someMethod");

 }

记录器会跟踪当前的logdepth并记录这样的内容:

 >someMethod
   something
 <someMethod

答案 3 :(得分:2)

您是否在测试计算机上安装了IDE?如果是这样,请尝试从IDE中重现该问题。发生堆栈溢出时,请查看调用堆栈(View-&gt; Debug Windows-&gt; Call Stack)。它可能会被多次调用相同的函数,如下所示:

FunctionA
FunctionB
FunctionA
FunctionB
FunctionA
FunctionB
...

如果你看到了,那么你知道这些功能在没有结束的情况下相互呼叫。

如果您没有在测试计算机上安装IDE,那么您仍然可以通过远程调试来完成此操作。如果您提供有关您的方案的更多信息,我们可以提供更多帮助。

具体来说,了解一下可能会有所帮助:

  • 你可以复制吗?
  • 是否在测试中安装了IDE 机?
  • 什么版本的Delphi?

答案 4 :(得分:0)

您可以使用项目链接器选项或$ M编译器指令来增加堆栈大小,但我认为它不会解决堆栈非常小的问题。

如果在调试器中运行应用程序,它最终会在异常处中断。

答案 5 :(得分:0)

如果您使用的是线程(不是主要的:sock连接)和主线程,那么它们共享相同的堆栈。解决这个问题:只需为每个连接创建一个带有自己堆栈的线程。

问题&gt;每个调用你做它调用堆栈为框架(共享一个这么大的问题) 例如,在调用proc aa(a,b:integer)时,总是调用相同的函数或不同的函数;

你有一个套接字线程在运行,而onconnect你调用proc a;并坚持做5秒钟的事情。

如果有人在连接关闭连接(释放堆栈)之前连接。 您有2个连接的客户端(每个不同数据有2个差异堆栈帧)

  

     

按a,b(整数);值5,10 - 来自1 conn

     

按a,b(整数);值7,3 - 来自2 conn

如果onconnect调用函数a(5,10)并且保持执行某些操作大约5秒。 有些人再次连接到服务器套接字,再次呼叫连接。

堆栈老了第一个调用帧但没有超出proc。所以没有弹出a,b来自(5,10)

如果你再次调用它会比它更复杂,那么它将覆盖2帧(2连接的本地proc变量)上的数据,所以当2连接从堆栈获取数据时,肯定会被其他信息覆盖。所以它会做错误的行为。

当第一次连接断开时,弹出a,b但是7,3(从第二次连接)而不是它保存的5,10。所以它不会暂时堆叠溢出,但随后程序运行和堆栈释放错误最终会得到$FFFFFFFF $SP堆栈。因此,当你调用一个函数时,它将尝试$FFFFFFAA,因此大于ya stack ex:$M 65536而不是4千兆字节$FFFFFFAA