2017-05-09 47 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)

相關問題