【问题标题】:How to narrow down a stack overflow exception?如何缩小堆栈溢出异常?
【发布时间】:2012-09-12 09:13:08
【问题描述】:

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

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

我昨晚用 MAD except 尝试过,但没有成功,大概是因为没有堆栈可以这样做。我是从 IDE 运行的,所以我中断了执行并查看了调用堆栈,但除了细节之外,它充满了 MAD(我已经联系了作者,但我们之间的时间差很大)。

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

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

无人值守,当计时器每 30 秒或每小时到期时,程序正在执行一些数据库访问,所以我将它们设置为 1 秒,希望能加速崩溃。嗯,我可以减少堆栈大小以加速崩溃吗?如果有,怎么做?

我还能做什么?我已经将我的应用程序主文件(创建表单和运行应用程序的地方)包装在 Try ... except 中。

是否有一些点,例如消息处理循环,我可以在其中检查堆栈大小并查看它是否增长“太大”? (如果有,能否提供详细信息?)

还有什么建议吗?提前致谢

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

【问题讨论】:

  • 您可以在链接器选项(或 $MAXSTACKSIZE)中设置最大堆栈大小(对于可执行文件)。
  • +1 我已将其设置为允许的最小值。对于 XE2,这是 65536。我希望问题会尽快出现。
  • 查看类中的“类型数组”字段并搜索“While”和“repeat”循环,这是我过去发现最多问题的地方...
  • JCLDebug 单元(来自 JCL)允许您获取堆栈。您可以使用它来检查堆栈大小。
  • 这很奇怪 - 但我尝试了一些 Profiler。怀疑无限递归,我希望最常用的程序是那些参与可怕舞蹈的程序

标签: delphi


【解决方案1】:

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

您说您使用计时器,您是在计时器事件中调用 Application.ProcessMessages 吗?如果队列中有很多消息,如果它是另一个 WM_TIMER,这可能会导致 stackoverflow。

【讨论】:

    【解决方案2】:

    作为。我上面提到的 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 分钟记录一次当前堆栈的使用情况 - 只是为了查看模式,如果它是稳定缓慢地运行,或者它是一些罕见但严重的代码路径。 如果有多个线程 - 那么每个线程有多个日志文件 它还允许估计“正常”堆栈使用情况。

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

    【讨论】:

      猜你喜欢
      • 2010-11-27
      • 1970-01-01
      • 2021-04-07
      • 2016-02-19
      • 2012-05-28
      • 1970-01-01
      • 2010-12-08
      相关资源
      最近更新 更多