Delphi中的外部异常EEFFACE

23

在使用Delphi 2009调试我的应用程序时,有时会出现以下异常:

这是什么?
(来源: beholdgenealogy.com)

这种情况只会偶尔发生,但是在按下“确定”后,我的IDE和程序都可能会冻结。如果我很幸运的话,有时可以在Delphi中进行文件/全部保存,但有时却无法保存。无论如何,我都被卡住了,然后我能做的唯一事情就是使用Windows任务管理器关闭Delphi。当然,如果我无法SaveAll,那么我将失去自上次保存以来所做的所有编辑。

我已经安装了所有Delphi 2009更新,包括Update 4。我还安装了IDE Fix Pack 2009 2.9。

该错误由EurekaLog为我捕获,并且错误报告给出了以下调用堆栈:

Call Stack Information:
-----------------------------------------------------------------------------------------------------------
|Address |Module              |Unit               |Class             |Procedure/Method          |Line     |
-----------------------------------------------------------------------------------------------------------
|Running Thread: ID=5068; Priority=0; Class=; [Main]                                                      |
|---------------------------------------------------------------------------------------------------------|
|205669C6|dbkdebugide120.bpl  |Debug.pas          |TDebugger         |DBKWndProc                |11598[6] |
|777DE49A|ntdll.dll           |                   |                  |KiUserExceptionDispatcher |         |
|7705E0CB|kernel32.dll        |                   |                  |RaiseException            |         |
|03E8E3E8|dcc120.dll          |WRITEOBJ.OBJ       |                  |C62_0                     |         |
|03E3066D|dcc120.dll          |SYMTAB.OBJ         |                  |MakeOverloadedPropertyList|         |
|03E3064C|dcc120.dll          |SYMTAB.OBJ         |                  |MakeOverloadedPropertyList|         |
|03E30D76|dcc120.dll          |SYMTAB.OBJ         |                  |EnterMethod               |         |
|03E30D6C|dcc120.dll          |SYMTAB.OBJ         |                  |FindBaseClassMethod       |         |
|03DE8D30|dcc120.dll          |DECL.OBJ           |                  |PatchConstRecordParameter |         |
|777DE590|ntdll.dll           |                   |                  |RtlLeaveCriticalSection   |         |
|03DBBF70|dcc120.dll          |BROWCMGR.OBJ       |                  |PutToAddress              |         |
|03DBC436|dcc120.dll          |BROWCMGR.OBJ       |                  |GetNearestSymName         |         |
|777DE550|ntdll.dll           |                   |                  |RtlEnterCriticalSection   |         |
|219C5BDA|win32debugide120.bpl|Win32Debug.pas     |TWin32LinkUnit    |GetCppDebugHook           |1923[3]  |
|219C5BB8|win32debugide120.bpl|Win32Debug.pas     |TWin32LinkUnit    |GetCppDebugHook           |1920[0]  |
|219C644E|win32debugide120.bpl|Win32Debug.pas     |TWin32Process     |DoLinkUnitCreated         |2198[10] |
|50001CE4|rtl120.bpl          |System.pas         |                  |InterlockedIncrement      |3200[0]  |
|5000CD59|rtl120.bpl          |System.pas         |TInterfacedObject |_AddRef                   |21759[1] |
|2055F40F|dbkdebugide120.bpl  |Debug.pas          |TProcess          |LinkUnitCreated           |8454[1]  |
|2055F408|dbkdebugide120.bpl  |Debug.pas          |TProcess          |LinkUnitCreated           |8453[0]  |
|2055CEC7|dbkdebugide120.bpl  |Debug.pas          |TEvaluatorCallback|ntfyLinkUnitDelta         |7167[7]  |
|77050DF0|kernel32.dll        |                   |                  |VirtualProtect            |         |
|50003FE4|rtl120.bpl          |System.pas         |                  |_ReallocMem               |3512[0]  |
|500093F6|rtl120.bpl          |System.pas         |                  |_LStrSetLength            |15889[38]|
|50004508|rtl120.bpl          |System.pas         |                  |Move                      |4414[0]  |
|5001DDB9|rtl120.bpl          |SysUtils.pas       |                  |StrLCopy                  |7852[5]  |
|5007E559|rtl120.bpl          |UxTheme.pas        |                  |DrawThemeTextEx           |5226[2]  |
|5007E524|rtl120.bpl          |UxTheme.pas        |                  |DrawThemeTextEx           |5224[0]  |
|2110A98D|vclactnband120.bpl  |ThemedActnCtrls.pas|TThemedMenuButton |DoDrawText                |488[23]  |
|50009E88|rtl120.bpl          |System.pas         |                  |_UStrClr                  |16961[0] |
|2110A9A2|vclactnband120.bpl  |ThemedActnCtrls.pas|TThemedMenuButton |DoDrawText                |490[25]  |
|75FC7BFE|USER32.dll          |                   |                  |CallNextHookEx            |         |
|20AA9C5E|designide120.bpl    |DeskUtil.pas       |                  |SetFocusHook              |435[4]   |
|210E8B83|vclactnband120.bpl  |ActnMenus.pas      |                  |CallWindowHook            |741[20]  |
|50057F7D|rtl120.bpl          |Classes.pas        |TComponent        |UpdateAction              |11881[1] |
|50006EE4|rtl120.bpl          |System.pas         |                  |_CallDynaInst             |10209[0] |
|501EA802|vcl120.bpl          |Forms.pas          |                  |ProcessUpdate             |6739[1]  |
|50006F3C|rtl120.bpl          |System.pas         |TObject           |InheritsFrom              |10281[0] |
|50006E1A|rtl120.bpl          |System.pas         |                  |_IsClass                  |10107[1] |
|50006E0C|rtl120.bpl          |System.pas         |                  |_IsClass                  |10106[0] |
|501EA870|vcl120.bpl          |Forms.pas          |                  |TraverseClients3          |6756[5]  |
|501EA818|vcl120.bpl          |Forms.pas          |                  |TraverseClients3          |6751[0]  |
|501EA88A|vcl120.bpl          |Forms.pas          |                  |TraverseClients3          |6756[5]  |
|50047748|rtl120.bpl          |Classes.pas        |TList             |Get                       |3366[0]  |
|501C865E|vcl120.bpl          |Controls.pas       |TWinControl       |GetControl                |8473[4]  |
|50006F3C|rtl120.bpl          |System.pas         |TObject           |InheritsFrom              |10281[0] |
|50006E1A|rtl120.bpl          |System.pas         |                  |_IsClass                  |10107[1] |
|501C8668|vcl120.bpl          |Controls.pas       |TWinControl       |GetControlCount           |8478[0]  |
|501EA87B|vcl120.bpl          |Forms.pas          |                  |TraverseClients3          |6756[5]  |
|501EA818|vcl120.bpl          |Forms.pas          |                  |TraverseClients3          |6751[0]  |
|501EA8E2|vcl120.bpl          |Forms.pas          |TCustomForm       |CMActionUpdate            |6778[11] |
|501C565A|vcl120.bpl          |Controls.pas       |TControl          |WndProc                   |6642[91] |
|501C5388|vcl120.bpl          |Controls.pas       |TControl          |WndProc                   |6551[0]  |
|501C9CE7|vcl120.bpl          |Controls.pas       |TWinControl       |WndProc                   |9336[136]|
|75FC7C2B|USER32.dll          |                   |                  |CallNextHookEx            |         |
|75FCC477|USER32.dll          |                   |                  |InvalidateRect            |         |
|75FCC41E|USER32.dll          |                   |                  |InvalidateRect            |         |
|75FCC49D|USER32.dll          |                   |                  |CallWindowProcW           |         |
|75FCC487|USER32.dll          |                   |                  |CallWindowProcW           |         |
|205669A5|dbkdebugide120.bpl  |Debug.pas          |TDebugger         |DBKWndProc                |11595[3] |
|500591DC|rtl120.bpl          |Classes.pas        |                  |StdWndProc                |12703[8] |
|75FC9467|USER32.dll          |                   |                  |IsWindowVisible           |         |
|75FC8B0B|USER32.dll          |                   |                  |DispatchMessageW          |         |
|75FC8B01|USER32.dll          |                   |                  |DispatchMessageW          |         |
|501EEABD|vcl120.bpl          |Forms.pas          |TApplication      |ProcessMessage            |9660[30] |
|501EE9A0|vcl120.bpl          |Forms.pas          |TApplication      |ProcessMessage            |9630[0]  |
|501EEB02|vcl120.bpl          |Forms.pas          |TApplication      |HandleMessage             |9690[1]  |
|501EEAF8|vcl120.bpl          |Forms.pas          |TApplication      |HandleMessage             |9689[0]  |
|501EEE2D|vcl120.bpl          |Forms.pas          |TApplication      |Run                       |9827[26] |
|501EED64|vcl120.bpl          |Forms.pas          |TApplication      |Run                       |9801[0]  |
|004259E6|bds.exe             |bds.dpr            |                  |bds                       |198[8]   |
|770CECC9|kernel32.dll        |                   |                  |BaseThreadInitThunk       |         |
-----------------------------------------------------------------------------------------------------------

正如您所看到的,整个调用栈都在Delphi和Windows中。它根本没有与我的程序中的任何一行连接。
我查看了网页: External Exception EEFFACE 并将其从德语翻译成英语,但它似乎在谈论Delphi C ++,而我根本不使用C ++。
我的问题是我不知道可能会导致这种情况,因为它并不始终发生。我甚至不知道该去哪里找到它或如何跟踪它。
有人知道这是什么以及我如何追踪它或至少防止它发生吗?

以下是EurekaLog的Alex在我的论坛提问后的回复:

我认为这可能是Delphi调试器的一个错误。可能与评估工具提示或类似内容有关。

亲自看看-我们在系统模块中有一个C++异常(EEFFACE是VCL异常的特殊代码。当VCL遇到未知的C++异常时,它会将其包装成代码为EEFFACE的EExternalException对象),并且调用堆栈包括Delphi调试器的单元:

|205669C6|dbkdebugide120.bpl |Debug.pas |TDebugger |DBKWndProc |11598[6] |
|7705E0CB|kernel32.dll | | |RaiseException | |
|03E8E3E8|dcc120.dll |WRITEOBJ.OBJ | |C62_0 | |
|03E3066D|dcc120.dll |SYMTAB.OBJ | |MakeOverloadedPropertyList| |
|03E3064C|dcc120.dll |SYMTAB.OBJ | |MakeOverloadedPropertyList| |
|03E30D76|dcc120.dll |SYMTAB.OBJ | |EnterMethod | |
|03E30D6C|dcc120.dll |SYMTAB.OBJ | |FindBaseClassMethod | |
|03DE8D30|dcc120.dll |DECL.OBJ | |PatchConstRecordParameter | |
|03DBBF70|dcc120.dll |BROWCMGR.OBJ | |PutToAddress | |
|03DBC436|dcc120.dll |BROWCMGR.OBJ | |GetNearestSymName | |
|219C5BDA|win32debugide120.bpl|Win32Debug.pas |TWin32LinkUnit |GetCppDebugHook |1923[3] |
|219C5BB8|win32debugide120.bpl|Win32Debug.pas |TWin32LinkUnit |GetCppDebugHook |1920[0] |
|219C644E|win32debugide120.bpl|Win32Debug.pas |TWin32Process |DoLinkUnitCreated |2198[10] |
|50001CE4|rtl120.bpl |System.pas | |InterlockedIncrement |3200[0] |
|5000CD59|rtl120.bpl |System.pas |TInterfacedObject |_AddRef |21759[1] |
|2055F40F|dbkdebugide120.bpl |Debug.pas |TProcess |LinkUnitCreated |8454[1] |
|2055F408|dbkdebugide120.bpl |Debug.pas |TProcess |LinkUnitCreated |8453[0] |
|2055CEC7|dbkdebugide120.bpl |Debug.pas |TEvaluatorCallback|ntfyLinkUnitDelta |7167[7] |  

我认为您应该将这个描述发布到Embarcadero的Quality Central。

尝试禁用“IDE集成”复选框(位于IDE的“EurekaLog” / “EurekaLog IDE选项”菜单中),然后运行应用程序-查看行为是否有变化。


我现在已经向Quality Central提交了一份报告,地址为:

http://qc.embarcadero.com/wc/qcmain.aspx?d=81881

希望有了这些信息,Embarcadero将能够在未来的版本中避免这种情况发生。

我在四年后回到了这个问题,意识到几个月前我找到了解决方案,所以现在我在这里发布它,为了任何可能遇到此问题的人。

该问题和解决方案在Olaf Monien的博客文章中提供,在2009/07/22发布了题为Delphi 2009 / Windows 7 / 64位调试器崩溃解决方法的文章。

Olaf在那篇文章中的指令完美地解决了我的问题。我在他的博客文章下评论中向他表示感谢。

正如@rossmcm在评论中指出的那样,Olaf的博客文章已经消失了,但是该文章仍然可以在Internet Archive上找到。相反,请查看Chris Miller关于该问题的信息(现在也只能在Internet Archive上找到),其中包括现在已经在Embarcadero上有永久家园的补丁工具的链接


3
您可以安装Andreas Hausladen的DDevExtensions。它有一个选项,可以在编译成功后备份您的文件。当然,它不会修复这个错误,但至少您不会丢失数据。 - The_Fox
5
顺便提一下,我的文章也有英文版可供阅读: http://www.audacia-software.de/en/bcb/external-exception-eefface.htm 你只需要点击左边的小英国旗就可以找到它了 :) - Moritz Beutel
@Moritz:感谢提供英文链接。不知道我怎么错过了你的小旗帜。但是你有什么想法,可能会发生什么事情呢? - lkessler
1
调试器中的一些代码(大部分是用C++编写的)会引发C++异常。当然,我无法确定具体发生了什么,但您可以使用我的SystemCppException单元,将其放入专家(或包,但这不太安全),并将其安装到IDE中,然后VCL将能够从C++异常中提取合理的错误消息。 - Moritz Beutel
(然而,艾伦说这更像是评估器/编译器而不是调试器。我猜他是对的。) - Moritz Beutel
Olaf的解决方法链接已经失效。该网站仍然活跃,但是它会重定向到另一个域名,但是没有帖子的迹象。不过,Olaf提供了这个链接,它引用了修复程序,现在托管在embarcadero这里。链接为:http://cc.embarcadero.com/item/27521。 - rossmcm
5个回答

10

明显是 Delphi 评估器(编译器的一部分)发生了异常。奇怪的是,如果实际上它正在通过 writeobj.c 进行处理,那么肯定有些地方出了问题。如果您能用一个测试用例重现此问题,请在 QualityCentral(http://qc.embarcadero.com)中报告。

EEFFACE 是 C++ 使用的 SEH 异常代码,它正在“泄漏”到某些 Delphi 代码中(在这种情况下是 IDE 本身)。当异常代码不是由 Delphi 生成的异常或硬件相关的异常时,Delphi 简单地将其映射为 EExternalException。


当异常代码不是由Delphi生成的异常或与硬件有关的异常时,Delphi只是将其映射到EExternalException。:) - IDE难道不能意识到C++异常吗? - Moritz Beutel
这更多是Delphi运行时的问题,是的,我们可以让Delphi更加意识到EEFFACE是一个C++异常。问题在于以合理的方式解释有效载荷。最简单的方法就是仅将其映射到另一种异常类型,如ECPPBuilderException。 - Allen Bauer
3
关于“解析有效负载”:我前段时间编写了一个 Delphi 封装类,模仿 C++ RTL 中的几个函数,并使用它们来提取异常类型名称和(在 std::exception 的情况下)std::exception::what() 返回的异常消息。它还提供对实际的 C++ 异常对象的访问,以便 C++Builder 代码可以在 TApplicationEvents::OnException 处理程序中执行动态异常分派。你可以在http://www.audacia-software.de/en/win/bcb/sc.htm#SystemCppException找到我的封装类。 - Moritz Beutel
我在自动化Delphi 2010中的MS办公应用程序时,一直收到“External exception EEFFACE”错误。最终我会得到Abort/Try Again选项,如果我中止调试选项将被禁用。我唯一能够恢复正常的方法是重新启动IDE。我特别使用GetActiveOleObject/CreateOleObject方法,在使用其中任一方法时都会抛出该异常。 - James

3
这并不是一个确切的答案,但可以通过描述我的经验来帮助您克服该错误。当我使用Windows Vista和7时,我经常收到此错误。在Windows XP上,相同的代码从未收到过该错误消息。我可以在dpr文件的第一行上设置断点,并发现它似乎总是在创建应用程序的闪屏界面时发生。我尝试了各种其他方法来制作闪屏界面,但最终总是会在调试时出现EEFFACE错误。因此,为了解决这个问题,我现在将
if DebugHook = 0 then

当我创建和访问启动画面时,现在在调试时我的应用程序的启动画面不再显示,但至少我不再收到EEFFACE错误。


非常有趣,Peter。不幸的是,在我的程序中,我没有闪屏,所以这不是唯一的原因。 - lkessler
我注意到像James(上面提到的人)这样自动化Office时他能解决这个问题,因此看起来可能有很多原因。我的回答更多是为了传达我在这方面的经验,希望它能在未来的某个地方引发一个解决方案。我相信这个问题在XE中仍然存在(不确定XE2是否存在)。 - Peter Meier
1
我很感激你在这里的贡献。但实际上,如果你去看一下我一年半前提交的Quality Central报告(链接在我的问题中),你会发现有很多关于这个bug的活动和评论。但是到Delphi XE为止,他们仍然没有解决方案。因此,如果你在那个案例中分享你使用EEFFACE的经验,可能会对他们有所帮助。 - lkessler
这在我的情况下起作用了。当调试时显示启动画面 => EEFFACE。现在使用DebugHook进行绕过 => 不再出现EEFFACE。 - FileVoyager

1

看起来“外部异常”不是Delphi的错误,我以前遇到过这个异常,可能是主板或硬件问题,因为在其他机器上程序运行良好。


谢谢gadriano。主板可能并没有问题,因为它在其他方面运行良好。但是我有一个AMD主板,也许与Intel主板有所不同。从未考虑过这种可能性,这可以解释为什么不是每个人都会遇到这种情况。 - lkessler

0

最近我遇到了这个问题,它与Delphi IDE有些关联。以下代码在ShellExecute行上导致异常:

url:='https://translate.google.com/#hu/en/%C3%A1';
ShellExecute(0,PChar('open'),PChar(url),nil,nil,SW_SHOWNORMAL);

但这不是:

url:='https://translate.google.com/#hu/en/%C3%A1';
ShowMessage(url);    
ShellExecute(0,PChar('open'),PChar(url),nil,nil,SW_SHOWNORMAL);

但是,如果我在IDE之外运行我的应用程序,没有ShowMessage额外行的情况下一切都很好。我不知道它是否有帮助,但也许在其他需要调试的情况下,这个“技巧”可能会有所帮助。

系统:DELL Optiplex,英特尔Core2Duo,Win7 x64,Delphi 7


0

我已经苦恼了几周的EEFFACE问题。最终发现原因是这条指令:

PDFForgePDF.CopyPDFFile(pdffile,pdfcreatorfile,1,1);

变量pdffile和pdfcreatorfile的内容是相同的...

也许这可以帮助像我这样可怜的程序员...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接