程序空闲时访问冲突 - 不跟踪信息以追踪错误
Posted
技术标签:
【中文标题】程序空闲时访问冲突 - 不跟踪信息以追踪错误【英文标题】:Access violation while the program was idle - not trace information to track down the bug 【发布时间】:2011-04-26 14:21:52 【问题描述】:我有一个刚刚弹出 AV 的程序。到目前为止,Eureka Log 可以找到产生错误的源代码行,但现在它只显示:
Access violation at address 7E452E4E in module 'USER32.dll'. Read of address 00000015.
Call Stack Information:
--------------------------------------------------------------------------------------------
|Address |Module |Unit |Class|Procedure/Method |Line |
--------------------------------------------------------------------------------------------
|Running Thread: ID=2640; Priority=0; Class=; [Main] |
|------------------------------------------------------------------------------------------|
|77F16A7E|GDI32.dll | | |IntersectClipRect | |
|7E433000|USER32.dll | | |EditWndProc | |
|7E42A993|USER32.dll | | |CallWindowProcA | |
|7E42A97D|USER32.dll | | |CallWindowProcA | |
|7E429011|USER32.dll | | |OffsetRect | |
|7E4196C2|USER32.dll | | |DispatchMessageA | |
|7E4196B8|USER32.dll | | |DispatchMessageA | |
|00625E13|Amper.exe |Amper.DPR | | |76[16]|
|7C915511|ntdll.dll | | |RtlFindActivationContextSectionString| |
|7C915D61|ntdll.dll | | |RtlFindCharInUnicodeString | |
|7C910466|ntdll.dll | | |RtlFreeUnicodeString | |
|7C80B87C|kernel32.dll | | |IsDBCSLeadByte | |
|7C9113ED|ntdll.dll | | |RtlDeleteCriticalSection | |
|7C80EEF5|kernel32.dll | | |FindClose | |
|7C901000|ntdll.dll | | |RtlEnterCriticalSection | |
|7C912CFF|ntdll.dll | | |LdrLockLoaderLock | |
|7C9010E0|ntdll.dll | | |RtlLeaveCriticalSection | |
|7C912D19|ntdll.dll | | |LdrUnlockLoaderLock | |
|7C9166C1|ntdll.dll | | |LdrGetDllHandleEx | |
|7C9166B3|ntdll.dll | | |LdrGetDllHandle | |
|7C9166A0|ntdll.dll | | |LdrGetDllHandle | |
|7C912A8D|ntdll.dll | | |RtlUnicodeToMultiByteN | |
|7C912C21|ntdll.dll | | |RtlUnicodeStringToAnsiString | |
|7C901000|ntdll.dll | | |RtlEnterCriticalSection | |
|7C912CC9|ntdll.dll | | |LdrLockLoaderLock | |
|7C912CFF|ntdll.dll | | |LdrLockLoaderLock | |
|7C9010E0|ntdll.dll | | |RtlLeaveCriticalSection | |
|7C912D19|ntdll.dll | | |LdrUnlockLoaderLock | |
|7C90CF78|ntdll.dll | | |ZwAllocateVirtualMemory | |
|7C90CF6E|ntdll.dll | | |ZwAllocateVirtualMemory | |
|7C9010E0|ntdll.dll | | |RtlLeaveCriticalSection | |
|7C80BA57|kernel32.dll | | |VirtualQueryEx | |
|7C80BA40|kernel32.dll | | |VirtualQueryEx | |
|7C80BA81|kernel32.dll | | |VirtualQuery | |
|7C901000|ntdll.dll | | |RtlEnterCriticalSection | |
|7C912CC9|ntdll.dll | | |LdrLockLoaderLock | |
|7C912CFF|ntdll.dll | | |LdrLockLoaderLock | |
|7C9010E0|ntdll.dll | | |RtlLeaveCriticalSection | |
--------------------------------------------------------------------------------------------
当我收到错误时程序完全空闲,并且它的窗口被其他窗口隐藏。 FastMM 处于活动状态并设置为完全调试,但它表示没有内存覆盖。 关于如何找到这个 AV 的来源的任何提示?
Win XP、Delphi 7
【问题讨论】:
【参考方案1】:我在 user32.dll 中没有看到 EditWndProc() 方法,但 Delphi 有一对——一个处理组合框消息,一个处理树视图。鉴于 MS 的 comctrl 混乱,我猜你有一个树视图?
检查您的树视图内容。给定 IntersectClipRect 的参数,很容易猜到它被传递了一个无效的设备上下文——所以......你是否正在为你的树视图做任何自定义绘画?如果是这样,您是否正在检查以确保画布手柄是! NIL 在你开始绘画之前(如果没有别的尝试断言)?
【讨论】:
嗨,埃里克。感谢您的回答。我没有任何TTreeView、TShellTreeView 之类的。但如果这很重要,我有一个 TFileList 和 TDirectoryList 。我在这些控件中没有自定义绘画。我有很多其他控件可以在其中进行自定义绘画,但不幸的是它们分散在许多形式中。当我什至不知道是哪个表单生成错误时,很难找到错误:( 是的,这些确实很重要。我的猜测是它们正在动态更新以反映特定文件夹中的更改。不要再考虑“空闲循环”了——你正在处理一条没有被正确处理的常规 Windows 消息。仔细查看您附加到这些控件的事件处理程序;如有必要,将所有代码注释掉,看看是否一切正常。 哦,IIRC,在 Windows 不希望你绘制东西的情况下,TCanvas 肯定会以 NIL 句柄结束(即 GetDC() 返回 0)。尝试使用该句柄会很麻烦。【参考方案2】:我只是想知道 Amper.exe 中的第 76[16] 行是什么...该行号可能是错误位置的提示。 再说一次,当它只是在空闲时刻发生时,它基本上发生在系统处理 Windows 消息时,如鼠标移动、键盘事件、计时器更新等等。 有时有助于search for 错误消息和代码。我进行了快速扫描,发现 this KB from MS 这表明当您使用无效参数调用某些 Windows API 时可能会发生这种错误。但是这个知识库不适用于您的错误。尽管如此,它还是让您了解要检查的内容:您在自己的代码中进行的任何 Windows API 调用。 在您调试时,它是否也会在 IDE 中生成此异常?
【讨论】:
1) 第 76 行是“Application.Run”,意思是……嗯……整个程序。 2)“要检查的内容:您在自己的代码中进行的任何 Windows API 调用” - 小更正:我可能应该检查程序空闲时执行的任何 Windows API 调用。这将稍微限制搜索区域。 3) 不。仅在运行时。 好吧,可能已经猜到它会是 Application.Run 部分。 :-) 不过,这不是整个应用程序。只是当时处于活动状态的部分。您打开的任何表单、这些表单上的组件、在后台运行的线程以及 - 考虑到错误 - 很可能某些 Windows 消息和 API 调用使用不正确。 (尽管即使是 Delphi 源代码也可能存在这种缺陷。) 您可能不喜欢它,但是您是否尝试过使用不同的 Delphi 版本编译您的应用程序?不确定您是否有其他版本可用,但可能是 Delphi 源代码本身的一些错误已在较新版本中得到修复... @Alex - 我只有 Delphi 7 的许可证。我想我可以使用 Delphi 2010 左右的试用版。 |应用程序处于空闲状态。我的代码都没有运行(也许除了一些组件的自定义绘制,尽管我不明白为什么在应用程序不可见时需要绘制组件)。所以,它一定是 IDLE 循环中的东西。如何查看应用程序空闲时执行的代码类型? 该试用版可能至少表明这是您的代码或 D78 运行时的问题。关于那些自定义绘画控件。绘画不太可能被执行,但您可能想检查您在这些方法中所做的调用。关于检查调用了哪些代码,我通常会创建一个全局文本文件变量并让关键程序向其中写入行。这并不理想,但有助于在没有调试器的情况下检查运行时错误。【参考方案3】:这就是 EurekaLog 在没有任何东西可以使用时所做的事情。您需要重建并让链接器生成详细的映射文件。这就是它知道将堆栈跟踪应用于什么的方式。
【讨论】:
嗨梅森。生成地图文件。它是从那时起生成的,我从未禁用该设置。这就是 Eureka 可以捕获其他错误的原因。这份报告是唯一一份看起来很奇怪的报告。我认为它无法捕获错误,因为该程序实际上并未通过其任何分支运行。它只是闲置。以上是关于程序空闲时访问冲突 - 不跟踪信息以追踪错误的主要内容,如果未能解决你的问题,请参考以下文章
Laravel SQLSTATE[42000]:语法错误或访问冲突:1064