2010-01-06 81 views
2

我正在解決現有代碼始終正常工作的問題(它是Jedi Windows Security LibraryTerminal Server unit)。 經過一番調查問題部分已經回落到一個呼叫WTSOpenServerWindows 7上WTSOpenServer的奇怪崩潰(僅在Delphi 2009/2010中)

while true do 
    begin 
     hServer := WTSOpenServer(PChar('server')); 
     WTSCloseServer(hServer); 
     hServer := 0; 
    end; 

隨機(但小)數量或運行後,我們得到一個總的應用程序崩潰,這使得它很難調試。 以下是我已經嘗試過的事情:

  • WTSOpenServer不寫pServername參數(如CreateProcessW)(其實我查了拆卸和它使一個副本)
  • 的代碼運行正常傳遞時零作爲參數(並因此與本地機器一起工作)。
  • 當使用遠程服務器,本地主機甚至虛擬爲pServerName時,結果總是崩潰(在Vista及更高版本上,即使無效的服務器名稱也會根據文檔返回有效的句柄)。
  • 使用Delphi 2009和2010進行了測試
  • 相同的代碼在Visual Studio(C++)中運行良好。
  • 經過在Visual Studio中拆卸和進行呼叫的WTSOpenServer在距離Delphi ASM(和用C改變手柄類型爲指針等):

    hModule := LoadLibrary('wtsapi32.dll'); 
    if hModule = 0 then 
        Exit; 
    
    WTSOpenServer := GetProcAddress(hModule, 'WTSOpenServerW'); 
    if WTSOpenServer = nil then 
        Exit; 
    
    while true do 
    begin 
        asm 
        push dword ptr pServerName; 
        call dword ptr WTSOpenServer; 
        mov [hServer], eax; 
        end; 
    
        hServer := nil; 
    end; 
    
  • 離開了呼叫WTSCloseServer

  • 測試在Windows 7的兩個x64和x86版本的代碼
  • 使用外部調試器,而不是德爾福一個(好像運行在這種情況下細所以我的猜測是,它是某種定時/線程/死鎖問題)
  • 添加AddVectoredExceptionHandler然後我看到一個EXCEPTION_ACCESS_VIOLATION,但堆棧似乎已損壞,EIP爲1,因此無法確定它發生的位置。

在這一點上,我不知道如何進一步排除故障或找到解釋。

+0

我測試了完全相同的代碼在兩個德爾福7和2007年(稱爲WTSOpenServerW版本),並在這兩個工作正常。結合事實,它在C++中沒有問題,我在這裏懷疑Delphi ... – Remko 2010-01-06 13:19:29

+0

這可能是一個UnicodeString/AnsiString的問題? – 2010-01-06 15:07:21

+0

否:顯示的代碼是該項目中唯一的代碼。 – Remko 2010-01-06 20:58:27

回答

1

嘗試在FullDebugMode中使用FastMM運行您的應用程序。它看起來更像是你的第三方lib代碼中的一個錯誤 - 可能的內存覆蓋/緩衝區溢出(比如某些GetMem對於UnicodeString/String類似的操作太小了,它「起作用」,但遲早會崩潰/ AV) 。

將大型應用程序遷移到D2009時,我遇到過幾種類似的情況,在大多數情況下,這是由於假定Char = 1個字節。有時會發生很奇怪的事情,但總是FullDebugMode的幫助。例外是CreateProcessW,但它是知道/記錄的行爲。

FullDebugMode如果應用程序覆蓋內存,那麼當你釋放它時,FastMM會在你分配它的地方給你例外,所以你可以很容易地找到這個錯誤。它在開始和分配結束時添加一些字節,因此會知道它是否被覆蓋。

我不能用新的/空VCL項目重現它,你可以試試你的自我(這個循環運行了大約5分鐘):

uses JwaWtsApi32; 
procedure TForm7.FormCreate(Sender: TObject); 
var 
    hServer: DWORD; 
begin 
    while true do 
    begin 
     hServer := WTSOpenServer(PChar('server')); 
     WTSCloseServer(hServer); 
     hServer := 0; 
    end; 
end; 
+0

我的項目只包含該代碼!我甚至把它帶回到一個沒有使用任何單元的控制檯項目。 請注意,崩潰只發生在Windows 7上運行時,使用Delphi 2009或Delphi 2010進行調試時。 – Remko 2010-01-06 20:53:38

+0

我還使用Windows 7(RC,Ultimate 32位)和Delphi 2009(12.0.3420.21218),以及只使用一個額外的標準。新的VCL項目顯式導入 - JwaWtsApi32 rev。 820(關於這個更新的答案)。從delphi運行5-10分鐘,並通過該循環逐步執行約30-40次。 你可以在具有相同OS/Delphi的另一臺機器上重現它嗎? 我對此非常極端的想法:病毒(rootkit;)/代碼注入exe的第三方bug,如madExcept,EurekaLog,JDBG,.. /不尋常的默認Delphi編譯器/鏈接器選項是越野車/某事。錯誤的操作系統,更新,antivir,LSP ... – kibab 2010-01-06 21:34:12

+0

您在RC或RTM上測試過嗎? – Remko 2010-01-06 21:45:46