CnPack Forum


 
Subject: Delphi 2009 VCL 源码中一处可能导致死循环的 Bug
Passion (LiuXiao)
管理员
Rank: 9Rank: 9Rank: 9


UID 359
Digest Posts 19
Credits 6750
Posts 3551
点点分 6750
Reading Access 102
Registered 2004-3-28
Status Offline
Post at 2008-11-6 14:23  Profile | Blog | P.M. 
Delphi 2009 VCL 源码中一处可能导致死循环的 Bug

Delphi 2007/2009 的 source\Win32\vcl\Forms.pas 中,GetNonToolWindowPopupParent 函数实现部分:

function GetNonToolWindowPopupParent(WndParent: HWND): HWND;
begin
  Result := GetParent(WndParent);
  while (Result <> 0) and (GetWindowLong(Result, GWL_EXSTYLE) and WS_EX_TOOLWINDOW = WS_EX_TOOLWINDOW) do
    Result := GetParent(WndParent);
    ... // 以下省略
   
很明显,如果第一次进入 while 时判断成立,那么 Result 的值就始终是 WndParent 的 Parent,也就没机会跳出循环了。Result := GetParent(WndParent); 应该改成 Result := GetParent(Result); 才对。

GetNonToolWindowPopupParent 是在 TCustomForm 的 CreateParams 中被调用的,也就是说某些窗口在 Create 的时候,可能就会碰上这个死循环,导致程序挂在这个窗体 Create 的过程中。

网上没搜到这个 Bug 的相关内容,可能一般人的程序中都不会进入这个 while,但 CnPack IDE 专家包的某些窗体代码偏偏就进入了这个 while,导致用户 IDE 失去响应,然后我们在调试过程中才碰到这个问题。

目前还在想办法看如何绕过此 Bug。

感谢 godnumen 和 笑三少 的报告与协助。
Top
kendling (小冬)
高级版主
Rank: 8Rank: 8
MyvNet


Medal No.1  
UID 703
Digest Posts 5
Credits 978
Posts 580
点点分 978
Reading Access 101
Registered 2005-2-18
Location 广东
Status Offline
Post at 2008-11-6 15:46  Profile | Site | Blog | P.M.  | QQ | Yahoo!
D2009的VCL源码也出现这样的低级BUG。




小冬
http://MyvNet.com
Top
Passion (LiuXiao)
管理员
Rank: 9Rank: 9Rank: 9


UID 359
Digest Posts 19
Credits 6750
Posts 3551
点点分 6750
Reading Access 102
Registered 2004-3-28
Status Offline
Post at 2008-11-8 00:20  Profile | Blog | P.M. 
补充一下后来想出的半截子绕过这个问题的办法:

这个问题在TCustomForm的CreateParams被调用时,如果当前Application的ActiveForm的Handle存在,并且这个Handle拿来GetWindowLong一下其GWL_EXSTYLE时具有WS_EX_TOOLWINDOW风格的话,即会产生这个死循环。

在自己的窗体创建并显示的情况下,如要躲过此循环,可override CreateParams函数,在inherited前判断Application的ActiveForm的Handle并设置其GWL_EXSTYLE为 非 WS_EX_TOOLWINDOW,inherited 后再恢复,即可。

如果是多模块协作带包链接,是别人的窗体没法改源码,那就得考虑动态修补vcl120.bpl了。将Result := GetParent(WndParent); 改成 Result := GetParent(Result); 只需要将一处汇编代码 56 push esi 改成 53 push ebx,改一字节即可,但这种方法兼容性比较的差,版本一变偏移量就会变,难以维护。
Top
oyefer
新警察
Rank: 1



UID 41220
Digest Posts 0
Credits 15
Posts 6
点点分 15
Reading Access 10
Registered 2008-11-7
Status Offline
Post at 2008-11-8 12:34  Profile | Blog | P.M. 
Passion,如果修改 vcl120.bpl 的话,能说一下具体的偏移地址吗?谢谢。
BDS2009+Update1:c:\windows\system32\vcl120.bpl,1,995,776字节
Top
Passion (LiuXiao)
管理员
Rank: 9Rank: 9Rank: 9


UID 359
Digest Posts 19
Credits 6750
Posts 3551
点点分 6750
Reading Access 102
Registered 2004-3-28
Status Offline
Post at 2008-11-8 15:26  Profile | Blog | P.M. 
我手头没update1的vcl120.bpl,只有正式版的,3170.16989,这也是我说不推荐手工改VCL120.bpl的原因:每个不同版本都得去拆解看看。
Top
stanleyxu2005
新警察
Rank: 1



UID 5617
Digest Posts 1
Credits 45
Posts 15
点点分 45
Reading Access 10
Registered 2007-2-11
Status Offline
Post at 2009-1-1 08:02  Profile | Site | Blog | P.M. 
用VCLFixPack可以解决这个问题。




http://getgosurf.com/forum/
Top
jyh11111 (觉悟)
新警察
Rank: 1



UID 20792
Digest Posts 0
Credits 14
Posts 5
点点分 14
Reading Access 10
Registered 2007-7-21
Status Offline
Post at 2009-3-13 14:19  Profile | Blog | P.M. 
delphi2009  UPDATE 4修正了此问题!
Top
 




All times are GMT++8, the time now is 2024-3-29 01:56

    本论坛支付平台由支付宝提供
携手打造安全诚信的交易社区 Powered by Discuz! 5.0.0  © 2001-2006 Comsenz Inc.
Processed in 0.008216 second(s), 8 queries , Gzip enabled

Clear Cookies - Contact Us - CnPack Website - Archiver - WAP