Delphi 诊断和修复TControl中的访问冲突。是否在当前调用堆栈中不涉及用户编写的代码的情况下执行?
我有一个delphi 2007应用程序,它在TControl.Perform方法的标准VCL unit Controls.pas中定期出现访问冲突。调用堆栈如下所示:Delphi 诊断和修复TControl中的访问冲突。是否在当前调用堆栈中不涉及用户编写的代码的情况下执行?,delphi,delphi-2007,access-violation,Delphi,Delphi 2007,Access Violation,我有一个delphi 2007应用程序,它在TControl.Perform方法的标准VCL unit Controls.pas中定期出现访问冲突。调用堆栈如下所示: exception message : Access violation at address 00000000. Read of address 00000000. Main ($1cac): 00000000 +000 ??? 004cd644 +024 mainexe.exe Controls 5021 +5 TC
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”风格的访问冲突,并对根本原因有一些了解
我的#1怀疑是一个表单已经被我的代码的其他区域“释放”,一个窗口消息正在被处理,而TControl(作为某个实际表单中某个实际控件的基类)只是因为Self为nil而失败,或者像窗口句柄这样的资源无效
我正在寻找一种可以帮助我诊断这个问题的技术,这种技术可以在客户端计算机上执行,而无需访问delphi调试器。我的想法包括添加一些日志记录(但是什么?),甚至在客户端机器上运行WinDbg(windows SDK调试器工具)。上面的问题是由旧版本的TMS StringGrid控件引起的,所讨论的代码是在WM_MOUSEMOVE上执行的,但责任完全在于我,而不是TMS,因为我没有对我的TMS组件文件夹进行干净的更新 当我使用更高版本的代码重新构建并删除与我的应用程序链接的旧
DCU
文件时,问题就消失了
简而言之,你有你认为在你的应用程序中的源代码,如果你的库或项目搜索路径中有一些旧的
DCU
文件夹,对于你的发布版本,你的代码中有一些神秘的预编译内容。我已经知道,您不应该以一种可能保留旧DCU的方式构建您的项目,并且您的版本控制系统中不应该有任何DCU,但这一个从我身边溜走了。上面的问题是由过时的TMS StringGrid控件版本引起的,所讨论的代码是在WM_MOUSEMOVE上执行的,但责任完全在我,而不是TMS,因为我没有对我的TMS组件文件夹进行干净的更新
当我使用更高版本的代码重新构建并删除与我的应用程序链接的旧DCU
文件时,问题就消失了
简而言之,你有你认为在你的应用程序中的源代码,如果你的库或项目搜索路径中有一些旧的
DCU
文件夹,对于你的发布版本,你的代码中有一些神秘的预编译内容。我已经知道,您不应该以旧的DCU可以保留的方式构建项目,也不应该在版本控制系统中有任何DCU,但这一个从我身边溜走了。我今天有点慢。+5表示第5行。TControl.exe中唯一的代码是调用WindowProc
。这意味着您有一个t控件
实例,其WindowProc
为nil
。出现了一些非常糟糕的问题。从调用堆栈来看,这似乎是一条TButtonControl
后代处理WM_MOUSEMOVE
消息,请参阅TWinControl.WndProc
。看起来问题出在按钮控件的父控件上(请参见TControl.CMMouseEnter
第5542行)-出于某种原因,它的WindowProc
为零。也许您正在使用WindowProc
属性进行子类化,但没有正确替换原始属性?如果多次子类化但以错误的顺序恢复原始方法,也很容易发生这种情况……我正在调试的代码是由不知道如何正确实例化对象和管理对象生命周期的人编写的。我猜是一个自由的t控件,在show模式循环期间,表单对象被过早地破坏。我已经把它缩小到客户可能会提出的180个模式表单中的一个,这些表单正在被创建,然后很快就被释放了。@WarrenP,我会浏览代码以寻找它们被破坏的方式,特别是当应该使用发布时调用的免费。(我在以前的一家公司遇到过这样的情况,它混合了Free
——而不是-Release
和ProcessMessages
)我不明白为什么一个被释放的对象在WindowProc中会有nil。也许是一个陈旧的指针,但零似乎不太可能。我今天有点慢。+5表示第5行。TControl.exe中唯一的代码是调用WindowProc
。这意味着您有一个t控件
实例,其WindowProc
为nil
。出现了一些非常糟糕的问题。从调用堆栈来看,这似乎是一条TButtonControl
后代处理WM_MOUSEMOVE
消息,请参阅TWinControl.WndProc
。看起来问题出在按钮控件的父控件上(请参见TControl.CMMouseEnter
第5542行)-出于某种原因,它的WindowProc
为零。也许您正在使用WindowProc
属性进行子类化,但没有正确替换原始属性?如果多次子类化但以错误的顺序恢复原始方法,也很容易发生这种情况……我正在调试的代码是由不知道如何正确实例化对象和管理对象生命周期的人编写的。我猜是一个自由的t控件,在show模式循环期间,表单对象被过早地破坏。我已经把它缩小到180个模态形式中的一个,客户可能会提出这些模态形式,它们正在被创建,然后很快就被释放了。@WarrenP,我会浏览一下t