2017-05-09 102 views
1

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

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

这包括像jvm.dll和msxml的东西

任何线索?解决方法?这些问题是一致的和持久的,而且在调试时,所讨论的应用程序运行得非常愉快。

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

编辑:我追溯了一个DLL调用,事实证明它试图写入DLL本地内存DATA或BSS。在德尔福2010年,它让人相当高兴。在东京它会抛出$ C0000005错误。我假设这是最新的Delphi调试器的错误或安装问题。

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

编辑发生3: 堆栈跟踪:

DLL的
: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) 

TDUMP提供了以下信息:

Object table: 
# Name    VirtSize RVA  PhysSize Phys off Flags 
-- --------   -------- -------- -------- -------- -------- 
01 CODE    00052714 00001000 00052800 00000400 60000020 [CER] 
02 DATA    000013D8 00054000 00001400 00052C00 C0000040 [IRW] 
03 BSS    00000B7D 00056000 00000000 00054000 C0000000 [RW] 
04 .idata   00001F86 00057000 00002000 00054000 C0000040 [IRW] 
05 .edata   0000139F 00059000 00001400 00056000 50000040 [IRS] 
06 .reloc   0000588C 0005B000 00005A00 00057400 50000040 [IRS] 
07 .rsrc    00004800 00061000 00004800 0005CE00 50000040 [IRS] 

Key to section flags: 
    C - contains code 
    E - executable 
    I - contains initialized data 
    R - readable 
    S - shareable 
    W - writeable 

据我所知,在这大小写0x00974409应该是完全合法的地址。

+0

有一些迹象表明,堆栈正在搞乱一些如何。 –

+0

结果不是这样的情况。这绝对是一个写入许可的事情。 –

+0

如果你正在调试器中运行,你会有一个堆栈跟踪,不是?您能否将问题的堆栈跟踪回供给您控制的代码? – Neil

回答

0

错误5是访问被拒绝。

这可能是尝试写入null(或在数据的第一个64k内的任何地方),或者(正如你猜测的那样)它调用的Win32 API函数没有正确的安全设置。

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

+0

好想法,但没有......运行Delphi作为管理员没有任何区别。 (请注意,问题发生在调试模式下) –

0

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

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

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

我的猜测是lpString为空。

刚阅读GetWindowText函数的文档:

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

我不知道你是否想在应用程序上枚举Windows,这不是你的吗?

+0

我已经完成了所有这些。 lpString的位置似乎是dll的数据(或BSS,很难说)段的一部分。在Delphi 2010中,这是一个完全合法的地址,并且工作正常。在东京之下,仍然应该是一个完全合法的地址,但它会抛出GP错误。除非在调试器中运行,否则不会引发故障。 –

+0

nMaxCount呢?可能是仅在调试内存管理器中体现的缓冲区溢出。 – Neil

0

事实证明,我所看到的是调试器捕获在dll中处理的异常。工具 - >选项 - >调试器选项 - > Embarcadero调试器 - > Native OS异常 - > 32位Windows操作系统异常 - >访问冲突($ C0000005)被设置为“由调试器处理“

在Delphi此之前的版本默认为‘用户程序’(所有其他本地OS例外所做的那样)

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

相关问题