如何挂起程序时如何调试程序?

Maw*_*awg 3 delphi debugging hang

我有一个应用程序每秒进行一次测量(我在演示模式下运行它并生成随机数据,因此问题与从连接到串行端口的设备读取时没有关系).

5或6分钟后,它会挂起.

我已经添加了

try
  // entire body of procedure/function goes here

except
     on E: Exception do
        begin
           MessageDlg('Internal coding error in <function name>()', 
                          mtError, [mbOK], 0);
        end;
end;
Run Code Online (Sandbox Code Playgroud)

到每个函数(和项目文件中的Application.Run()),但我没有看到任何消息对话框.知道我怎么测试这个吗?


更新:我猜测是资源问题,无论是RAM还是MySql数据库 - 其他程序运行正常,并且每次测量只保存5个浮点数和时间戳,因此在这么短的时间后似乎都不太可能.


解决方案:有很多很棒的答案(感谢和+1全能),但我终于通过在IDE中运行并使用Run/Pause来查看它是一个不断增加的循环.

再次感谢大家.

Sch*_*999 5

我试试以下内容:

  1. 附加并单击Pause并查看它的位置,正在运行的线程,正在等待的线程(如果所有线程都存在死锁).

  2. 将主要方法重构为一堆小方法(您可能已经这样做了)然后用虚拟/硬编码值替换小方法.这可能有所帮助,但不一定能识别故障块.

  3. 使用PerfMon或其他东西观察系统资源消耗(句柄,线程等).查看内存是否耗尽并开始使用HDD.

  4. 如果使用套接字,请检查读取超时是否设置为无穷大.如果是,则更改为某个值并观察超时.

  5. 在.NET中,可以启用所有异常的处理,这意味着在代码处理之前(如在catch语句中),IDE会在异常点处中断.如果可能的话,在Delphi中启用它,看看你是否得到任何.


dth*_*rpe 5

使用调试器查看应用程序在挂起时正在执行的操作.

在调试器下运行程序.让它一直运行直到它挂起.当它挂起时,切换到调试器并选择"Debug:Break All"(或等效)以使调试器冻结所有线程并控制进程.

现在打开调试器中的Threads视图,检查程序中每个线程的堆栈跟踪.显然,从主线程开始.请务必回顾几次调用的调用堆栈,看看是否识别出任何代码.如果找到位于循环中间的堆栈跟踪,请检查局部变量以查看循环控制变量是否以某种方式滑过退出条件并使您进入无限循环.

如果你的堆栈跟踪指示每个线程都被阻塞等待一些外部事件,你可能有一个线程死锁 - 线程A获取锁定A,然后尝试获取锁定B,而线程B持有锁定B并尝试获取锁定A.如果你没有在你的程序中使用线程,这种可能性较小,但仍然要留意它.

如果在查看线程的堆栈跟踪后没有什么奇怪的事情跳出来,让程序运行几秒钟,然后再用调试器再次进入它并再看一遍.查看堆栈跟踪中的不同之处.

这应该可以帮助您缩小至少挂起的代码体.