有谁能解决 Delphi 的这个 Bug?(200分)

  • 主题发起人 主题发起人 andin
  • 开始时间 开始时间
A

andin

Unregistered / Unconfirmed
GUEST, unregistred user!
我写了一个简单的测试程序,用这个程序就可以暴露 Delphi 的Bug:
程序定义了两个单元,一个主界面,放两个按钮,另外一个是线程单元;
主界面单元的程序如下:
unit UnitMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,UnitTest;
type
TfrmMain = class(TForm)
btnStart: TButton;
Button1: TButton;
procedure btnStartClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
test : TTest;
implementation
{$R *.dfm}
procedure TfrmMain.btnStartClick(Sender: TObject);
begin
if test = nil then
test := TTest.Create(False);
end;

procedure TfrmMain.Button1Click(Sender: TObject);
begin
FreeAndNil(test);
end;
end.

线程单元的程序如下:
unit UnitTest;
interface
uses
Classes,Graphics,SysUtils;
type
TTest = class(TThread)
private
FCurrentBitmap : TBitmap;
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean);
destructor Destroy;override;
end;

implementation
constructor TTest.Create(CreateSuspended: Boolean);
begin
FCurrentBitmap := TBitmap.Create;
FCurrentBitmap.LoadFromFile('c:/test.bmp');

Inherited;
end;
destructor TTest.Destroy;
begin
inherited;
FreeAndNil(FCurrentBitmap);
end;
procedure TTest.Execute;
var
number : integer;
begin
number := 0;
while not Terminated do
begin
FCurrentBitmap.Canvas.TextOut(0,0,IntToStr(number));
FCurrentBitmap.SaveToFile('c:/ret.bmp');
Inc(number);
sleep(10);
end;
end;
end.

测试办法:
1. 用Delphi5 或 Delphi6 编译都可以;
2. 在C盘根目录下放一个 test.bmp 文件;
3. 单击“start Test”按钮,工作线程开始不断反复产生 c:/ret.bmp 文件;

Delphi Bug 的表现:
1.以上程序运行一段时间后,就报告奇怪的异常:“当文件存在时,不能创建该文件”
2.如果创建 ret.bmp 文件之前,调用 DeleteFile 函数删除这个文件,运行一段时间后,就会报告奇怪的异常:“Out of system resource”
3.大家测试时,一定要有耐心,这个一段时间,一般是3分钟左右,也可能得等1个小时!
 
由这个bug?不会把?
 
没碰到过
 
D7下也有這種情況大概45秒出現
 
D7 下也有这个 Bug !!!本来,我将 Delphi 从 5 升级到 6,就是期望解决这个问题,可 delphi 还是让我失望了!

大家可以将这个程序拷贝下来,作一个测试,亲自体验一下,不过,一定要有耐心,因为有的时候,需要运行一个小时,才能出现这个异常,有的时候,2分钟内就会出现这个异常
 
这个问题和内存的申请、释放以及硬盘的读取速度有关。
 
我试过了:
只有当在集成环境,并且菜单 tools/debugger option/lenguage Exception/Stop on Delphi Exception 被选择时出现该错误,不选之后没有错误.
 
1把TTest.Create,TTest.Destroy的错误改掉。
2用其他语言如Vc写一个类似的,看是否同样问题。
3你对delphi还知之甚少,不要哗众取宠
 
请问zhukewen,好像你是 Delphi 高手,不过如果你能解决这个问题,我才这么认为。
1. 请问,TTest.Create ,TTest.destroy 的错误在哪里?
2. 你提出这样的问题,让我不明白。我怀疑 Delphi 的 Graphic.pas 单元有问题,用VC作这方面的程序,能验证什么问题?
3. 我有没有哗众取宠,那就看你能否解决这个问题。

 
To Watter:
你已经发现了这个现象了?
你这样的解释只是在包庇 Delphi 的 Bug
 
To tianhf:
你这样去解决问题,放心吗?
还是让我们去研究 Graphic.pas 吧,搞清楚 Delphi 在哪个地方造成了 GDI 资源泄漏;
 
我觉得如果sleep设的大一些不出问题的话,就不是bug,而是系统的问题,不信
你换vc试试
 
Watter 说得对,这不是BUG!
你把
sleep(10);
改为
sleep(100); // 或更长看看,而且我一般不用这个API,自己写一个 Delay()

这个与 Graphic.pas 一点关系也没有,不信你可以用 TStrings 替代
是保存文件的问题,你还可以把 I/O 例外关闭试试。
....
{$I-}
FCurrentBitmap.SaveToFile('c:/ret.bmp');
{$I+}
....

我只是奇怪怎么会有这种需求,我写了7,8年的程序也没有遇过.

==============
聪明的人绕过去
高明的的钻进去
 
To: wfzha
为什么用 VC 去作同样的程序?要知道 VC 的 MFC 与 Delhi 的 VCL 根本就是两回事。
我们现在的问题是:Delphi 的 VCL 的这个Bug在 Graphic 单元的哪个位置?

另外,不要人工去增大 Sleep 时间,相反,要减少 Sleep 时间,这样才能检测出 Delphi的 VCL 的可靠性
 
To: andin
我不能不引用 zhukewen 的话说, 你对 DELPHI 甚至于编程都 "还知之甚少"
 
To:bundur
1. Sleep 是 Windows 的 API 函数,肯定没有问题(不够精确,那是另外一件事情);
2. 这个程序暴露两个奇怪的异常:第一个异常,可能正如你说的那样,不是 Graphic 的问题,因为,如果在SaveToFile这一句前面,增加这一行代码:
DeleteFile('c:/ret.bmp');
就不会出现第一个异常,但是,肯定会出现第二个异常,Out of system resource,而这个异常出现的原因就是系统的 GDI 资源申请失败,所以,我判定 Graphic 单元肯定有问题;
3. 至于说需求,当然,我这里贴出的这段程序,纯粹是技术讨论,没有任何作用,可是你如果开发多媒体方面软件,必然要同时用 TThread 以及 TBitmap,到那个时候,你必然会遇到这个问题
 
To:bundur
我承认我对 Delphi 知道得太少了,编程经验也没有你丰富。
可是,不现在不是在讨论这个问题,我现在只关心:谁能解决这个问题,并且能合理的解释这个问题!
 
如果注释了这行
// FCurrentBitmap.SaveToFile('c:/ret.bmp');
再试会发生什么? 如果没有出“Out of system resource”错,
则可以认为 Graphic 没有问题.
我说自己写代码替代Sleep不是Sleep有问题,这是因为 Sleep 把控制权交给了系统,
而自己用 Application.ProcessMessages 处理是把控制权交给这支程序本身。
 
To:bundur
绝对不能屏蔽 SaveToFile 这句话,这段程序虽然短小,但是为了暴露问题的本质,我经过了精心设计:
通过阅读 Graphic 单元,我发现 Delphi 的 TBitmap 对象有这么几个特点:
1.默认状态下,TBitmap 保存了一个 DDB 对象;
2.如果用户调用了 SaveToFile SaveToStream LoadFromFile ScanLine SetPixelFormat 等函数或方法,Delhpi 就会创建一个DIB对象;如果马上调用 Canvas.TextOut 之类函数,Delhpi 就会释放 DIB 对象,如果你马上调用SaveToFile,Delhpi又要构建 DIB 对象。。。
3。我的程序就是要“折磨”Delphi,看看Delphi 在DDB 与 DIB之间反复的切换,会不会出现问题,如果没有问题,那么说明很稳定。可到目前为止,只能说明,在这一点上,有GdI 资源泄漏,可是因为时间关系以及本人才疏学浅,Graphic单元,我还没有研究透彻,只好有求各位了!
 
To : bundur
关于 Delay 与 Sleep
你的作法让我惊讶不已,你这样去作,岂不是你的程序要独占CPU? 在工作线程里,调用Sleep 的主要目的就是,让CPU有时间去处理其他事情。
 

Similar threads

S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
897
SUNSTONE的Delphi笔记
S
后退
顶部