如何缩小堆栈溢出异常?

时间:2012-09-20 02:08:25

标签: delphi

我有截止日期。我正在谷歌搜索,我是代码阅读,我需要帮助......

我的应用程序正在抛出EStackOverFlow。它需要通过隔夜测试才能发现错误,所以我需要一些好的想法,或者需要很长的时间来追踪。

昨晚我尝试使用MAD Except,但是没有抓住它,大概是因为它没有堆栈这样做。我是从IDE运行的,所以我打破了执行并查看了调用堆栈,但除了详细信息之外它已经填充了MAD(我已经联系了作者,但我们之间存在很大的时间差异。)

没有(故意)递归递归例程。没有OnChange处理程序(可能会意外地更改它们监视的组件,因此递归调用它们)。没有大型数据结构(可能作为参数在堆栈上传递)。

我的第一个想法是关闭MAD Except,但我不能再等12或16个小时才能崩溃。

无人值守,当计时器每30秒或每小时到期时,程序正在进行一些数据库访问,因此我将其设置为1秒,希望加速崩溃。嗯,我可以减少堆栈大小以加速崩溃吗?如果是这样,怎么样?

我还能做什么?我已经在Try ... Except。

中包装了我的应用程序主文件,其中创建了表单并运行了应用程序

是否有一些观点,例如消息处理循环,我可以检查堆栈大小,看看它是否“增长”太大了? (如果是的话,你能详细说明吗?)

还有其他建议吗?提前致谢

(p.s代码太大而无法发布)

2 个答案:

答案 0 :(得分:1)

AS。我上面提到的Profiler方法可能会给你带来纯粹的运气结果(如果有一些杂散分支导致您罕见但瞬间快速泄漏。比如,在100个案例变体中,只有一个导致无限递归)。但是,如果存在稳定的累积泄漏,需要整夜累积,那么分析器结果将无法与正常工作区分开来。

我想了一下。目前的假设是堆栈跟踪器因没有堆栈而失败。让我们抓住它。然后我们将在堆栈结束之前抛出异常,是吗?所以我试试这个序列:

1)我将堆栈跟踪器设置为记录包含行号的完整堆栈跟踪。它可以在Delphi IDE使用的JCL跟踪器中完成,我认为madExcept也可以。

2)我想知道当前的堆栈大小。例如Determining Stack Space with Visual Studio

3)我会定期检查用过的堆栈空间。例如What is a safe Maximum Stack Size or How to measure use of stack?

注意:因为我们几乎不知道哪个线程导致了这个 - 如果我有很少的线程,我会尝试使用所有这些。我只是不知道如果某个辅助线程因SO而失败,应用程序会如何反应,是否可以截获并记录,或者整个应用程序只会因为一个线程而被炸毁

4)〜每5分钟我会记录当前的堆栈使用情况 - 只是为了查看模式,如果它是稳定缓慢的goring,或者它是一些罕见但严重的代码路径。 如果有几个线程 - 那么每个线程有几个日志文件 它还可以估算“正常”的堆栈使用情况。

5)如果堆栈使用率提高到80%以上(我认为你的“正常”用法不会超过它,不会吗?)我会提出手动异常,一些特殊的类,直到线程才会被捕获/应用程序顶层,顶级甚至可能做一些复杂的事情,比如暂停应用程序进入调试器并唤醒你,这样你就可以远程连接并检查生病而尚未死的app的内部状态。

答案 1 :(得分:1)

最常见的stackoverflow问题是函数调用自身,尽量避免它,或者至少限制它。

你说你使用了一个计时器,你在你的计时器事件中调用Application.ProcessMessages吗?如果队列中有很多消息,如果是另一个WM_TIMER,则可能导致堆栈溢出。