常に正常に動作していた既存のコード ( Jedi Windows Security LibraryのTerminal Server ユニット)の問題をトラブルシューティングしています。いくつかの調査の後、問題の部分はWTSOpenServerへの呼び出しに帰着しました:
while true do
begin
hServer := WTSOpenServer(PChar('server'));
WTSCloseServer(hServer);
hServer := 0;
end;
ランダムな (しかし小さい) 数または実行の後、アプリ全体がクラッシュし、デバッグが難しくなります。私がすでに試したことは次のとおりです。
- WTSOpenServer は (CreateProcessW のように) pServername パラメーターに書き込みません (実際、逆アセンブルを確認したところ、コピーが作成されます)
- nil をパラメーターとして渡すと、コードは正常に実行されます (したがって、ローカルマシンで動作します)。
- リモート サーバー、localhost、またはダミーを pServerName として使用すると、結果は常にクラッシュします (Vista 以降では、無効なサーバー名でも、ドキュメントに従って有効なハンドルが返されます)。
- Delphi 2009 と 2010 の両方でテスト済み
- 同じコードが Visual Studio (c++) で正常に動作します。
Visual Studio で逆アセンブリを確認し、Delphi から asm で WTSOpenServer を呼び出しました (そして、ハンドル型を 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 バージョンの両方でコードをテストする
- Delphi デバッガーの代わりに外部デバッガーを使用します (その場合は正常に動作するように見えるので、何らかのタイミング/スレッド/デッドロックの問題であると推測されます)。
- AddVectoredExceptionHandlerを追加すると、EXCEPTION_ACCESS_VIOLATION が表示されますが、スタックが破損しているように見えます。EIP は 1 であるため、どこで発生したかを判断できません。
現時点では、これをさらにトラブルシューティングする方法や説明を見つける方法がわかりません。