我有一个用Delphi W32编写的测试版。
在测试PC上,它会在使用几个小时后随意发出“堆栈溢出”消息。
如何捕获错误并查找原因?
我可以增加堆栈大小吗?
答案 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,那么您仍然可以通过远程调试来完成此操作。如果您提供有关您的方案的更多信息,我们可以提供更多帮助。
具体来说,了解一下可能会有所帮助:
答案 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
。