如何解决Delphi 10.4 + msbuild = 不稳定的二进制文件
我刚刚用Delphi 10.4+gitlab+build机实现了一个CI/CD环境 一切显然都是正确的,构建过程运行顺利,但是在使用该程序时,它会随机显示与我通过 Delphi 内部通过“shift+F9”(构建)手动构建相比从未发生过的错误。 构建过程:
call "C:\\Program Files (x86)\\Embarcadero\\Studio\\21.0\\bin\\rsvars.bat"
msbuild /target:rebuild /property:config=Debug;DCC_BuildAllUnits=true /p:platform=Win32 project.dproj
此外,我尝试了其他 msbuild 变体,例如:
msbuild /target:rebuild /property:config=Debug /p:platform=Win32 project.dproj
(还有 2 个步骤(target:clean 和 target:build)
我还将 msbuild dcc32.exe 命令与“Delphi”dcc32.exe 命令进行了比较,它们基本相同,但对于 msbuild 输出的附加(不存在)文件夹:
-I"c:\program files (x86)\embarcadero\studio\21.0\lib\Win32\release\EN";...
最奇怪的是:在执行 msbuild 构建后,如果我用 Delphi 打开我的项目,执行干净+编译程序变得更奇怪,并给出其他错误,但如果我执行完整构建 (shift+F9) 然后它运行再次顺利 在我看来,使用的某些组件似乎没有在 msbuild 下正确编译或与其他参数一起使用,但我不知道它是什么或如何找到它。
使用 cmd msbuild
+ clean
在 Delphi + compile
在 Delphi 构建后出错:
First chance exception at $0019FB95. Exception class $C0000096 with message 'privileged instruction at 0x0019fb95'. Process project.exe (11324)
关注:
First chance exception at $0040AE84. Exception class $C0000005 with message 'access violation at 0x0040ae84: read of address 0x0000000b'. Process project.exe (11324)
procedure TAdvancedField.asImageLoadToBitMap(var outBitmap:TBitmap); var FS : TMemoryStream;
FirstBytes: AnsiString;
Graphic : TGraphic;
begin try
FS := TMemoryStream.Create;
(Self as TBlobField).SavetoStream(FS);
fs.Position := 0;
SetLength(FirstBytes,8);
FS.Read(FirstBytes[1],8);
//Graphic := nil; //I add this line after my debug,and commented to confirm
//if copy(FirstBytes,1,2) = 'BM' then
//begin
// Graphic := TBitmap.Create;
//end else
//if FirstBytes = #137'PNG'#13#10#26#10 then
//begin
// Graphic := TPngImage.Create;
//end else
//if copy(FirstBytes,3) = 'GIF' then
//begin
// Graphic := TGIFImage.Create;
//end else
//if copy(FirstBytes,2) = #$FF#$D8 then
//begin
// Graphic := TJPEGImage.Create;
// TJPEGImage(Graphic).CompressionQuality := 100;
//end;
if Assigned(Graphic) then
begin
try
FS.Seek(0,soFromBeginning);
Graphic.LoadFromStream(FS); //The error raised HERE
outBitmap.Assign(Graphic);
except
end;
Graphic.Free;
end
else
begin
outBitmap.Assign(nil);
end;
finally
fs.Free;
end;
end;
如您所见,Graphic
变量未在任何地方初始化。但是使用干净的 Delphi 构建它可以完美运行,Assigned(Graphic)
总是返回 false
,但是在 msbuild 之后它返回为 true
。如果这对其他类似的情况是正确的,它将导致整个项目出现意外行为。
另一种情况: 我在我的主窗体上放了一个按钮,带有单个引发异常 + 应用程序异常处理程序 + JCvstackTrace 处理程序,这是捕获的堆栈:
[017B7DE5] pcnConversao.RegTribisSQNToStr (Line 1301,"pcnConversao.pas" + 1) + $104
[006B6973] Vcl.Controls.TWinControl.ArrangeControl + $147
[006BB36F] Vcl.Controls.TWinControl.DoKeyUp + $73
[005A4998] Vcl.StdCtrls.TCustomCheckBox.SetChecked + $0
[006BB4CF] Vcl.Controls.TraverseControls + $37
[006BB36F] Vcl.Controls.TWinControl.DoKeyUp + $73
[0067E227] Vcl.Forms.TCustomForm.CreateWnd + $97
[006BA8BC] Vcl.Controls.TWinControl.WMInputLangChange + $8
[004F4A18] System.Classes.TStreamWriter.WriteLine + $C
[006BB47A] Vcl.Controls.TWinControl.WMChar + $2
[006BB36F] Vcl.Controls.TWinControl.DoKeyUp + $73
[005A4998] Vcl.StdCtrls.TCustomCheckBox.SetChecked + $0
[004F4A18] System.Classes.TStreamWriter.WriteLine + $C
顺便说一下,pcnConversao
仅被我的项目间接使用
正确的应该是:
[01709661] UModulo.TModulo.BitBtn3Click (Line 568,"UModulo.pas" + 0) + $11
[006BB3E7] Vcl.Controls.TWinControl.WndProc + $693
[005A4A10] Vcl.StdCtrls.TButtonControl.WndProc + $6C
[006BB547] Vcl.Controls.DoControlMsg + $23
[006BB3E7] Vcl.Controls.TWinControl.WndProc + $693
[0067E29F] Vcl.Forms.TCustomForm.WndProc + $6DB
[006BA934] Vcl.Controls.TWinControl.MainWndProc + $2C
[004F4A90] System.Classes.StdWndProc + $14
[006BB4F2] Vcl.Controls.TWinControl.DefaultHandler + $E6
[006BB3E7] Vcl.Controls.TWinControl.WndProc + $693
[005A4A10] Vcl.StdCtrls.TButtonControl.WndProc + $6C
[004F4A90] System.Classes.StdWndProc + $14
注意:
看起来不同的堆栈与Delphi中检查的Stack Frames
直接相关Compiler->Compiling->Code Generation
,仍然与编译器在未初始化变量处的发散方式无关
解决方法
问题正是那个未初始化的变量。仍然不知道为什么行为与通过 IDE 的默认构建不同,但是初始化为 nil 解决了问题
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。