我有一个 delphi 2007 应用程序,它在标准 VCL 单元 Controls.pas 的 TControl.Perform 方法中存在周期性访问冲突。调用堆栈如下所示:
exception message : Access violation at address 00000000. Read of address 00000000.
Main ($1cac):
00000000 +000 ???
004cd644 +024 mainexe.exe Controls 5021 +5 TControl.Perform
004ce705 +015 mainexe.exe Controls 5542 +2 TControl.CMMouseEnter
004cd9b7 +2bb mainexe.exe Controls 5146 +83 TControl.WndProc
004d19bb +4fb mainexe.exe Controls 7304 +111 TWinControl.WndProc
004a8ff8 +06c mainexe.exe StdCtrls 3684 +13 TButtonControl.WndProc
004cd644 +024 mainexe.exe Controls 5021 +5 TControl.Perform
004d182b +36b mainexe.exe Controls 7255 +62 TWinControl.WndProc
004a8ff8 +06c mainexe.exe StdCtrls 3684 +13 TButtonControl.WndProc
004d10e4 +02c mainexe.exe Controls 7073 +3 TWinControl.MainWndProc
0048af08 +014 mainexe.exe Classes 11583 +8 StdWndProc
75ce7bc5 +00a USER32.dll DispatchMessageA
004ecaf4 +0fc mainexe.exe Forms 8105 +23 TApplication.ProcessMessage
004ecb2e +00a mainexe.exe Forms 8124 +1 TApplication.HandleMessage
004ece23 +0b3 mainexe.exe Forms 8223 +20 TApplication.Run
0136cac7 +383 mainexe.exe mainexe 326 +45 initialization
75563398 +010 kernel32.dll BaseThreadInitThunk
我无法在办公室重现它,因此我只能通过 MadExcept 直接从客户那里获取调用堆栈。
我不确定如何诊断或以其他方式确定原因,然后纠正以这种方式发生的故障。我希望有人已经看到这种“TControl.Perform”类型的访问冲突,并对根本原因有一些了解。
我的第一怀疑是表单已被我的代码的其他区域“释放”,并且正在处理窗口消息,并且 TControl (作为某些实际表单中某些实际控件的基类)只是失败,因为 Self 为零,或者某些资源(例如窗口句柄)无效。
我正在寻找一种技术来帮助我诊断这个问题,该技术可以在客户端计算机上执行,而无需访问delphi调试器。我的想法包括添加一些日志记录(但是什么?),甚至在客户端计算机上运行 WinDbg(Windows SDK 调试器工具)。
最佳答案
上面的问题是由 TMS StringGrid 控件的过时版本引起的,并且有问题的代码是在 WM_MOUSEMOVE 上执行的,但责任完全在于我,而不是 TMS,因为我是那个没有对我的 TMS 组件文件夹进行彻底更新。
当我使用更高版本的代码重建并删除与我的应用程序链接的旧 DCU
文件时,问题就消失了。
简而言之,您拥有您认为应用程序中的源代码,并且如果您的库或项目搜索路径中有一些旧的 DCU
文件夹,那么对于您的发布版本,您你的代码中有一些神秘的预编译的东西。我已经知道你不应该以一种可能遗留旧 DCU 的方式构建你的项目,并且你的版本控制系统中不应该有任何 DCU,但这个问题我却忽略了。
关于delphi - 在当前调用堆栈中不涉及用户编写的代码的情况下诊断和修复 TControl.Perform 中的访问冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11650529/