Dll在Delphi 10.2中崩溃但仅在调试模式下崩溃

时间:2017-05-09 04:22:05

标签: delphi debugging exception delphi-10.2-tokyo

我最近从Delphi 2010升级到Delphi 10.2 Tokyo 许多第三方库已经开始在调试模式下抛出异常,并且只在调试模式下。 最常见的错误是$ C0000005一般保护错误。 这些是我多年来一直使用的图书馆,并且已经建立。

这些是第三方库,我无权访问源代码。

这包括jvm.dll和msxml

之类的内容

任何线索?解决方法?问题是一致的和持久的,并且当不在调试中时,所讨论的应用程序运行得相当愉快。

在每种情况下,我都看到它发生了动态链接而不是静态链接。我怀疑这个问题与处于调试模式时的不同权限有关。

编辑:我跟踪了一个DLL调用,结果发现它试图写入DLL本地内存DATA或BSS。在Delphi 2010中,它非常乐观。在东京,它会抛出$ C0000005错误。我假设这是最新的Delphi调试器的错误或设置问题。

编辑2:我设法拔出一个最小的应用程序来重现这个问题。 https://www.dropbox.com/s/uy8e9rw0qjxspie/testdll.zip?dl=0 下载包含一个最小的32位可执行文件(testdll)。它静态链接到第三方dll mirixafind.dll。这是一个旧的DLL,我无法访问源。 如果您单独运行testdll或没有调试,则点击“Mirixa”按钮会在屏幕上打印一些行并停止。 如果运行WITH调试,它将会因$ C0000005错误而失败,尝试将字符串写入一段内存,该内存似乎是dll的DATA(或可能的BSS)段的一部分。 一位同事在单独的安装中复制了它。它在Delphi 2010中不会发生。

编辑3: 堆栈跟踪:

%U

dll的Tdump提供以下信息:

:757db78d user32.GetWindowTextA + 0x1d
:0068fbbf ; C:\Users\Robbie\Documents\Embarcadero\Studio\Projects\Win32\Debug\mirixafind.dll
:757e9275 ; C:\WINDOWS\SysWOW64\user32.dll
:757e757a user32.EnumWindows + 0x1a
:0068fca5 ; C:\Users\Robbie\Documents\Embarcadero\Studio\Projects\Win32\Debug\mirixafind.dll
:00691afa ; C:\Users\Robbie\Documents\Embarcadero\Studio\Projects\Win32\Debug\mirixafind.dll
:00690bcd ; C:\Users\Robbie\Documents\Embarcadero\Studio\Projects\Win32\Debug\mirixafind.dll
testdll1.TForm1.Button2Click($234B380)
Vcl.Controls.TControl.Click
Vcl.StdCtrls.TCustomButton.Click
Vcl.StdCtrls.TCustomButton.CNCommand(???)
Vcl.Controls.TControl.WndProc((48401, 3796, 1117908, 0, 3796, 0, (), 3796, 17, (), 0, 0, ()))
Vcl.Controls.TWinControl.WndProc((48401, 3796, 1117908, 0, 3796, 0, (), 3796, 17, (), 0, 0, ()))
Vcl.StdCtrls.TButtonControl.WndProc((48401, 3796, 1117908, 0, 3796, 0, (), 3796, 17, (), 0, 0, ()))
Vcl.Controls.TControl.Perform(???,???,1117908)
Vcl.Controls.DoControlMsg(???,(no value))
Vcl.Controls.TWinControl.WMCommand((273, (), 3796, 0, (), 1117908, 0))
Vcl.Controls.TControl.WndProc((273, 3796, 1117908, 0, 3796, 0, (), 3796, 17, (), 0, 0, ()))
Vcl.Controls.TWinControl.WndProc((273, 3796, 1117908, 0, 3796, 0, (), 3796, 17, (), 0, 0, ()))
Vcl.Controls.TWinControl.MainWndProc(???)
System.Classes.StdWndProc(1575384,273,3796,1117908)
:757ed2b3 user32.SetManipulationInputTarget + 0x53
:757ce88a ; C:\WINDOWS\SysWOW64\user32.dll
:757f764b ; C:\WINDOWS\SysWOW64\user32.dll
:757d0c00 ; C:\WINDOWS\SysWOW64\user32.dll
:6ccdd36f ; C:\WINDOWS\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.14393.953_none_89c2555adb023171\comctl32.dll
:6cced065 ; C:\WINDOWS\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.14393.953_none_89c2555adb023171\comctl32.dll
:757ed2b3 user32.SetManipulationInputTarget + 0x53
:757ce88a ; C:\WINDOWS\SysWOW64\user32.dll
:757cdf17 user32.CallWindowProcW + 0x97
Vcl.Controls.TWinControl.DefaultHandler(???)
:00521b5b TWinControl.DefaultHandler + $EB
:00521a4a TWinControl.WndProc + $5EE
:00536559 TButtonControl.WndProc + $71
:004c2b5a StdWndProc + $16
:757ed2b3 user32.SetManipulationInputTarget + 0x53
:757ce88a ; C:\WINDOWS\SysWOW64\user32.dll
:757ce1e4 ; C:\WINDOWS\SysWOW64\user32.dll
:757cdfa0 user32.DispatchMessageW + 0x10

First chance exception at $757DB78D. Exception class $C0000005 with message 'access violation at 0x757db78d: write of address 0x00974409'. Process testdll.exe (26036)

Module Load: MirixaFind.dll. No Debug Info. Base Address: $00970000. Process testdll.exe (26036)

据我所知,在这种情况下,0x00974409应该是一个完全合法的地址。

3 个答案:

答案 0 :(得分:2)

事实证明,我看到的是调试器捕获正在dll中处理的异常。

工具 - >选项 - >调试器选项 - > Embarcadero调试器 - >本机操作系统异常 - > 32位Windows操作系统异常 - >访问冲突($ C0000005)已设置“由调试器处理”

在Delphi的早期版本中,这违反了“用户程序”(与所有其他Native OS异常一样)

它看起来比它更糟糕,因为它发生在一个循环的中间,所以它不断被抛出......但如果我只是告诉Delphi忽略它的例外,它就会消失。 (Headdesk)

答案 1 :(得分:0)

错误5是拒绝访问。

这可能是尝试写入null(或在前64k数据中的任何位置),或者(因为你猜测)它正在调用Win32 API函数,它没有正确的安全设置。

我认为您已尝试在管理员帐户下运行您的应用,看看它是否与此相关?

答案 2 :(得分:0)

发布作为答案,以便正确格式化代码。

因此,从堆栈跟踪看起来代码是枚举所有窗口以获取窗口文本(可能是每个窗口的标题?)。很难理解,但如果您可以将程序集转储到0x0068fbbf,您将看到传递给GetWindowText的参数。原型(下面)很难出错。

int WINAPI GetWindowText(_In_ HWND hWnd, _Out_ LPTSTR lpString, _In_ int nMaxCount);

我的猜测是lpString为空。

请阅读GetWindowText上的文档:

  

复制指定窗口标题栏的文本(如果有的话)   进入缓冲区。如果指定的窗口是控件,则为文本   控制被复制。 但是,GetWindowText无法检索文本   另一个应用程序中的控件

我想知道你是否试图在一个不属于你的应用程序上枚举Windows?