【问题标题】:TOpenFileDialog Access violation in XE6XE6 中的 OpenFileDialog 访问冲突
【发布时间】:2015-02-26 05:01:41
【问题描述】:

我有一个带有打开文件对话框的简单 Delphi 程序

unit Unit1;    
interface    
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation    
{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  openDialog : TOpenDialog;
  i : Integer;
begin    
  openDialog := TOpenDialog.Create(self);    
  openDialog.InitialDir := GetCurrentDir;    

  if not openDialog.Execute
  then ShowMessage('Open file was cancelled')
  else
  begin

  end;

  openDialog.Free;    
end;

end.

当我单击表单上的按钮并取消文件打开对话框时,这似乎可以正常工作。

但是,在这样做之后,当我让程序运行时 我遇到了访问冲突。

这可能是 XE6 中的错误吗?


编辑

以防万一你们想知道我的窗口是否是最新的


编辑

这是我收到的错误消息列表:

【问题讨论】:

  • 这不是你的主线程吧?异常似乎来自FunDisc.dll,它可能指向 COM。当您将应用程序作为 64 位应用程序编译和运行时会发生什么?
  • 您可以尝试使用 TOpenDialog.Create(nil) 创建对话框吗?
  • 为什么你认为异常与OpenDialog有关?
  • 我们如何重现这个错误?
  • 我刚刚在 XE6 上尝试过你的代码,它工作得很好。所以你有你的 AV 在其他地方。

标签: delphi crash windbg windows-7-x64 access-violation


【解决方案1】:

我首先在您的转储上运行 analyze -v。不幸的是,这并没有发现任何有用的东西。

接下来的尝试是使用(~*) 查看所有堆栈。这确实出现在有趣的堆栈之后。

10 TID:1a08 kb kbn kbnL kn knL kpn kPn
 # ChildEBP RetAddr  
00 0668f128 77c7b230 ntdll!RtlLookupFunctionTable+0x85
01 0668f178 77c7b3f5 ntdll!RtlIsValidHandler+0x26
02 0668f1f8 77c30133 ntdll!RtlDispatchException+0x10e
03 0668f1f8 0668f7b1 ntdll!KiUserExceptionDispatcher+0xf
WARNING: Frame IP not in any known module. Following frames may be wrong.
04 0668f6c0 77c7b499 0x668f7b1
05 0668f6e4 77c7b46b ntdll!ExecuteHandler2+0x26
06 0668f708 77c7b40e ntdll!ExecuteHandler+0x24
07 0668f794 77c30133 ntdll!RtlDispatchException+0x127
08 0668f794 7632c99e ntdll!KiUserExceptionDispatcher+0xf
09 0668fc84 76335d00 ole32!CStdMarshal::Disconnect+0x223
0a 0668fc98 76335ce1 ole32!DisconnectSwitch+0x16
0b 0668fcb0 76335d3f ole32!CStdMarshal::DisconnectAndRelease+0x44
0c 0668fe60 76368f82 ole32!COIDTable::ThreadCleanup+0xcb
0d 0668fea4 76368ec3 ole32!FinishShutdown+0x9d
0e 0668fec4 7635bac3 ole32!ApartmentUninitialize+0x96
0f 0668fedc 763688e8 ole32!wCoUninitialize+0x153
10 0668fef8 6ef2314a ole32!CoUninitialize+0x72
11 0668ff00 764943c0 NetworkItemFactory!FDBackgroundThreadHandler+0x21
12 0668ff88 7662338a shlwapi!WrapperThreadProc+0x1b5
13 0668ff94 77c59f72 kernel32!BaseThreadInitThunk+0xe
14 0668ffd4 77c59f45 ntdll!__RtlUserThreadStart+0x70
15 0668ffec 00000000 ntdll!_RtlUserThreadStart+0x1b

至少,这证实了我们最初的怀疑,即它与 COM/system 相关,而不是 Delphi。深入堆栈寻找有用的字符串出现在字符串之后

d:\w7rtm\com\ole32\com\class\compobj.cxx

现在我们要搜索一些新内容:w7rtm compobj

这导致 SO 上的以下线程(注意 相同的堆栈跟踪
Crashes in ole32!COIDTable::ThreadCleanup … NetworkItemFactory!FDBackgroundThreadHandler

Thomas W 提出了这个问题,Hans Pasant 对此进行了评论,并且两者都使用 WinDbg 或 Windows Internals 知识渊博,但没有找到明确的解决方案(至少,没有发布解决方案)所以恐怕你只剩下汉斯给托马斯的以下建议了

你被埋在 COM 管道中,清楚地暗示它 内部状态已损坏。这是一个环境问题,有些 一种被注入进程并搞砸的DLL。 早在崩溃发生之前,你就几乎没有希望了 用调试器诊断它。找出问题的共同根源 从模块列表中。怀疑任何外壳扩展、反恶意软件、任何 类似于 Dropbox 的实用程序。使用 SysInternals 的 AutoRuns 禁用 他们。 (Hans Pasant)

假设故障出在注入到您的进程中的 dll 中,我已经从您的转储和我的计算机上运行的应用程序中获取了已加载 dll 的横截面(它不会在我的计算机上崩溃) 留下以下可疑 dll 的

ATL90    EhStorAPI EhStorShell  FWPUCLNT GROOVEEX_64a40000 GrooveIntlResource_63d20000 MsftEdit  OFFICE        RpcRtRemote TortoiseSVN32 TortoiseStub32
WMASF    WMVCore   WSHTCPIP     WcnApi   Wldap32           atl                         atl100    audiodev      cfgmgr32    crypt32       cryptsp
davhlpr  devobj    dnsapi       dui70    duser             fdWNet                      fundisc   gdiplus       gdiplus     ieframe       ieproxy
iertutil imm32     intl3_tsvn32 kernel32 libapr_tsvn32     libaprutil_tsvn32           libsasl32 libsvn_tsvn32 linkinfo    lpk           mpr
msasn1   msctf     msls31       msvcp100 msvcp110          msvcp90                     msvcr100  msvcr110      msvcr90     msxml6        netmsg
normaliz nsi       ntmarta      psapi    rpcrt4            secur32                     setupapi  shdocvw       shlwapi     slc           sspicli
userenv  usp10     wininet      winmm    winnsi            winsta                      wintrust  wpdshext      wpdshext    ws2_32        wship6         xmllite
api_ms_win_downlevel_advapi32_l1_1_0
api_ms_win_downlevel_normaliz_l1_1_0
api_ms_win_downlevel_shell32_l1_1_0
api_ms_win_downlevel_shlwapi_l1_1_0
api_ms_win_downlevel_shlwapi_l2_1_0
api_ms_win_downlevel_user32_l1_1_0
api_ms_win_downlevel_version_l1_1_0

如果我们省略所有 Microsoft 和 Unloaded dll,则以下 dll 将保留

TortoiseSVN32    
TortoiseStub32   
intl3_tsvn32     
libapr_tsvn32    
libaprutil_tsvn32
libsasl32        
libsvn_tsvn32    

所以我在您的系统上的第一次尝试是卸载或禁用加载(使用自动运行) TortoiseSVN 插件,看看是否能解决您的问题。

【讨论】:

  • 这实际上是解决方案!我尝试卸载乌龟,问题消失了。我印象深刻:)
  • 我经常完全错过球,但时不时地把它钉起来很好。感谢您随时通知我们。
  • 阅读Sertac Akyuz cmets 并回答,让我很困惑。如果它是第一次机会异常,但遵循我链接到的答案并且它具有完全相同的堆栈跟踪类型的计数器,你不应该担心这个异常是正确的?!
  • @Lieven - 我不认为有任何矛盾,类似的堆栈跟踪可能并不意味着它应该是相同的错误。如果这意味着,这里的海报应该有word,excel,firefox崩溃。
【解决方案2】:

您在 ole32.dll 中有一个“第一次机会异常”。当程序在调试器之外运行时没有出现任何错误(如 cmets 中所述)表明了这一点。当它引用一个看似伪地址时,总是怀疑第一次机会异常,如本例中的 0xFEEEFEEE。不过不要怀疑太久,检查 IDE 的“事件日志”调试窗口,您应该会看到类似 “First chance exception at ....”这样的条目。

第一次机会异常意味着代码遇到了异常情况。这并不意味着异常不会被处理。这就像您自己在代码中提出的异常。对于外部调试器,这是第一次机会异常。

这里没有什么可做或担心的。只要程序在此之后正常运行,您就不必尝试避免出现变通方法或任何异常。

【讨论】:

    猜你喜欢
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多