我需要一些调试Delphi XE2应用程序崩溃的建议。我自己从来没有见过崩溃 - 事实上它很少发生,并且不能按要求重现。
我们确实从MadExcept获得了一组10个崩溃报告。这些表明主线程在主窗体的列表视图中处理WM_PAINT消息。每种情况下的调用堆栈都没有显示对我自己的代码的引用,只显示了comctl32.dll,ntdll.dll和USER32.dll中的VCL代码和函数。
有问题的列表视图是TColorListView,它派生自TCustomListView,并处理OnCustomDrawItem和OnDeletion事件。但正如我所说,当崩溃发生时,我的TColorListView代码都没有在调用堆栈中。
每种情况下崩溃的实际位置都有所不同,但是通向它的调用顺序(从早到晚)始终是:
KiUserCallbackDispatcher
RtlAnsiStringToUnicodeString
StdWndProc
TWinControl.MainWndProc
TCustomListView.WndProc
TWinControl.WndProc
TControl.WndProc
TCustomListView.WMPaint
TWinControl.WMPaint
TWinControl.WMPaint
TWinControl.DefaultHandler
CallWindowProcA
TControl.WndProc
之后它进入StdWndProc / SendMessageW / TControl.Perform之一,每次路径都不同。最终它最终出现在comctl32.dll,USER32.dll,GDI32.dll或者只是TControl.WndProc中,并引发了EAccessViolation。遗憾的是,我没有关于用户当时尝试做什么的信息,因为用户没有填写错误报告的那部分。
你能否建议我可以使用任何'通灵调试'技术来确定这次崩溃的原因(从而修复它)?
更新以回答以下评论中的问题:
procedure TColorListView.HandleCustomDrawItem(aSender: TCustomListView; aItem: TListItem;
aState: TCustomDrawState; var aDefaultDraw: Boolean);
begin
Canvas.Font.Color := ItemColors[aItem.Index];
end;
在(仅)其中一个崩溃报告中,它似乎进入TListItem.GetIndex并进一步崩溃了几个堆栈帧。那可能是红鲱鱼。
什么是'执行'消息?对不起,我不知道。 MadExcept没有给我方法参数值;只是方法名称。
5月31日
虽然我更愿意根据我的信息找到错误,但我也欢迎我可以添加到程序中的任何新诊断的建议,以便如果在下一个版本之后再次发生这种崩溃我会有更多继续。我很茫然,因为在崩溃时我甚至没有修改的代码甚至都在调用堆栈上。
6月13日
我在MadExcept报告中添加了一行,告诉我发生异常时应用程序处于什么状态 - Starting / Active / Idle / ModalDlg / Terminated。 (感谢Chris Thornton提出的建议。)我认为在关机期间发生异常的可能性是合理的。不幸的是,直到2014年我们才发布新版本并且有可能通过新的诊断程序获取错误报告。
答案 0 :(得分:1)
有趣的读到这里。也许类似的事情正在发生? 检查画布并不会受伤<>零
Access violation while the program was idle - not trace information to track down the bug
答案 1 :(得分:1)
首先,对于deBUG访问冲突错误,您必须找到引用您的进程未拥有内存的区域的变量(内存指针)。
大多数非初始化变量会导致问题。
所以我的建议是按照以下方式改变作品
procedure TColorListView.HandleCustomDrawItem(aSender: TCustomListView; aItem: TListItem;
aState: TCustomDrawState; var aDefaultDraw: boolean);
begin
if Canvas = nil then
.... ; // a breakpoint here
if ItemColors = nil then
.... ; // a breakpoint here
if aItem = nil then
.... ; // a breakpoint here
Canvas.Font.Color := ItemColors[aItem.Index];
end;
我希望这会告诉你哪个变量未按预期传递。
我的猜测是针对aItem。
答案 2 :(得分:1)
这只是一个猜测,但也许你面临同样的问题(看起来很相似)
我的问题是在不同的线程中销毁WinAPI窗口而不是创建它们
在这种情况下Windows不会销毁窗口并返回错误,但是一些Delphi组件只是忽略了这个错误,所以最终会出现挂起窗口,其中 WndProc指向垃圾内存(它将被Delphi释放组件破坏,但窗口会留下来。)
当此窗口将尝试处理任何消息时,它将转到WndProc(未定义)并导致带AV的随机callstack。
因此,请确保您在同一个帖子中创建和删除窗口(特别注意 TTimer ,他们还会创建窗口)