我正在对始终运行良好的现有代码进行故障排除(它是 Jedi Windows 安全库中的终端服务器单元)。经过一番调查,问题部分已归结为对WTSOpenServer的调用:
while true do
begin
hServer := WTSOpenServer(PChar('server'));
WTSCloseServer(hServer);
hServer := 0;
end;
在一个随机(但很小)的数字或运行之后,我们会得到一个完全的应用程序崩溃,这使得调试变得很困难。以下是我已经尝试过的事情:
- WTSOpenServer 不写入 pServername 参数(如 CreateProcessW)(实际上我检查了反汇编并复制了一份)
- 将 nil 作为参数传递时,代码运行良好(因此可以与 localmachine 一起使用)。
- 当使用远程服务器、localhost 甚至是虚拟服务器作为 pServerName 时,结果总是崩溃(在 Vista 和更高版本中,即使是无效的服务器名也会根据文档返回有效的句柄)。
- 用 Delphi 2009 和 2010 测试
- 相同的代码在 Visual Studio (c++) 中运行良好。
检查了 Visual Studio 中的反汇编,并从 Delphi 调用了 asm 中的 WTSOpenServer(并将 Handle 类型更改为 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 的调用
- 在 x64 和 x86 版本的 Windows 7 上测试代码
- 使用外部调试器而不是 Delphi 一个(在这种情况下似乎运行良好,所以我的猜测是它是某种时间/线程/死锁问题)
- 添加了 AddVectoredExceptionHandler然后我看到一个 EXCEPTION_ACCESS_VIOLATION 但堆栈似乎已损坏,EIP 为 1,因此无法确定它发生在哪里。
此时我不知道如何进一步解决此问题或找到解释。