2010-01-06 110 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