【问题标题】:Strange crash with WTSOpenServer on Windows 7 (Only in Delphi 2009/2010)Windows 7 上 WTSOpenServer 的奇怪崩溃(仅在 Delphi 2009/2010 中)
【发布时间】:2011-01-01 23:26:24
【问题描述】:

我正在对始终运行良好的现有代码(它是来自Jedi Windows Security LibraryTerminal Server unit)的问题进行故障排除。 经过一番调查,问题部分已归结为致电WTSOpenServer

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

在随机(但很小)的数字或运行后,我们得到一个应用程序完全崩溃,这使得调试变得困难。 以下是我已经尝试过的事情:

  • WTSOpenServer 不写入 pServername 参数(如 CreateProcessW)(实际上我检查了反汇编并复制了一份)
  • 将 nil 作为参数传递时,代码运行良好(因此可以与本地机器一起使用)。
  • 当使用远程服务器、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,因此无法确定它发生在哪里。

目前我不知道如何进一步解决此问题或找到解释。

【问题讨论】:

  • 我在 Delphi 7 和 2007(调用 WTSOpenServerW 版本)上测试了完全相同的代码,并且两者都运行良好。结合它在 c++ 中没有问题的事实,我怀疑 Delphi 在这里......
  • 这可能是 UnicodeString / AnsiString 问题吗?
  • 否:显示的代码是项目中唯一的代码。

标签: delphi winapi windows-7 remote-desktop terminal-services


【解决方案1】:

尝试在 FullDebugMode 下使用 FastMM 运行您的应用程序。它看起来更像是您/第 3 方库代码中的错误 - 可能的内存覆盖/缓冲区溢出(moslty like sth.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;

【讨论】:

  • 我的项目只包含那个代码!我什至把它带回了一个控制台项目,根本不使用任何单位。请注意,只有在 Windows 7 上运行、使用 Delphi 2009 或 Delphi 2010 进行调试时才会发生崩溃。
  • 我也在使用 Windows 7(RC,Ultimate 32 位)和 Delphi 2009(12.0.3420.21218),并且只使用了一个附加到 std。新的 VCL 项目显式导入 - JwaWtsApi32 rev。 820(关于此的更新答案)。从 delphi 运行 5-10 分钟,并且通过该循环逐步运行约 30-40 次。你能在另一台具有相同 OS/Delphi 的机器上重现它吗?我对此非常极端的想法:病毒(rootkit;)/注入到exe的代码中的第三方错误,例如madExcept,EurekaLog,JDBG,../不寻常的默认Delphi编译器/链接器选项是错误的/ sth。操作系统、更新、杀毒软件、LSP 有问题...
  • Windows 7 RC “我也在使用 Windows 7(RC,Ultimate 32 位)...”(从 info@simulates 获取电子邮件...)
  • 虽然我禁用了我的 Virusscanner/Firewall,但我仍然注意到其中注入了 dll(F-Secure Internet Security 2010)。我之前忽略了它,因为它在较旧的 Delphi 版本下运行良好,但决定卸载。你猜怎么着?不再崩溃,将进行更多测试,如果这是问题,我将接受您的回答。
  • 所以这可能是错误的 LSP 库(我最后的“非常极端的想法”->“... LSP 有问题”;)它确实覆盖了内存......你可以使用自动运行(@ 987654321@),列出所有 LSP(WinSock 提供程序),然后您可以禁用/删除其中一些 - 非 Microsoft(您将失去一些功能,例如 F-Secure,但它有问题,所以不值得使用它;) .来自 Windows SDK(来自 MS)的 LSP 样本也有错误(并且会泄漏内存),所以大多数像交付的工作也会有错误。我知道 F-Secure 和 E-Set LSP dll 有问题...
猜你喜欢
  • 2011-08-06
  • 1970-01-01
  • 1970-01-01
  • 2011-06-06
  • 1970-01-01
  • 2014-01-12
  • 1970-01-01
  • 1970-01-01
  • 2011-07-10
相关资源
最近更新 更多