mirror of https://gitlab.com/basile.b/dexed.git
add a protection against large process output, close #424
This commit is contained in:
parent
6e922954e8
commit
c65592d659
|
@ -937,6 +937,7 @@ var
|
||||||
lst: TStringList;
|
lst: TStringList;
|
||||||
str: string;
|
str: string;
|
||||||
proc: TProcess;
|
proc: TProcess;
|
||||||
|
dproc: TDexedProcess = nil;
|
||||||
begin
|
begin
|
||||||
lst := TStringList.Create;
|
lst := TStringList.Create;
|
||||||
try
|
try
|
||||||
|
@ -956,9 +957,17 @@ begin
|
||||||
getprocInputHandler.removeProcess(TProcess(sender));
|
getprocInputHandler.removeProcess(TProcess(sender));
|
||||||
SetCurrentDirUTF8(fRunnerOldCwd);
|
SetCurrentDirUTF8(fRunnerOldCwd);
|
||||||
|
|
||||||
|
if proc is TDexedProcess then
|
||||||
|
dproc := TDexedProcess(proc);
|
||||||
|
|
||||||
if (proc.ExitStatus <> 0) then
|
if (proc.ExitStatus <> 0) then
|
||||||
|
begin
|
||||||
fMsgs.message(format('error: the process (%s) has returned the status %s',
|
fMsgs.message(format('error: the process (%s) has returned the status %s',
|
||||||
[proc.Executable, prettyReturnStatus(proc)]), fAsProjectItf, amcProj, amkErr);
|
[proc.Executable, prettyReturnStatus(proc)]), fAsProjectItf, amcProj, amkErr);
|
||||||
|
if dproc.isNotNil and dproc.autoKilled then
|
||||||
|
fMsgs.message(format('the process was autokilled because the size of its output exceeded %d',
|
||||||
|
[dproc.autoKillProcThreshold]), nil, amcProj, amkWarn);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
|
@ -1060,6 +1060,9 @@ begin
|
||||||
dubCmd2PostMsg[fNextTerminatedCommand], fAsProjectItf, amcProj, amkWarn);
|
dubCmd2PostMsg[fNextTerminatedCommand], fAsProjectItf, amcProj, amkWarn);
|
||||||
fMsgs.message(format('error: DUB has returned the status %s',
|
fMsgs.message(format('error: DUB has returned the status %s',
|
||||||
[prettyReturnStatus(fDubProc)]), fAsProjectItf, amcProj, amkErr);
|
[prettyReturnStatus(fDubProc)]), fAsProjectItf, amcProj, amkErr);
|
||||||
|
if fDubProc.autoKilled then
|
||||||
|
fMsgs.message(format('the process was autokilled because the size of its output exceeded %d',
|
||||||
|
[fDubProc.autoKillProcThreshold]), nil, amcProj, amkWarn);
|
||||||
end;
|
end;
|
||||||
subjProjCompiled(fProjectSubject, fAsProjectItf, fCompiled);
|
subjProjCompiled(fProjectSubject, fAsProjectItf, fCompiled);
|
||||||
SetCurrentDirUTF8(fPreCompilePath);
|
SetCurrentDirUTF8(fPreCompilePath);
|
||||||
|
|
|
@ -614,6 +614,7 @@ type
|
||||||
fAutoCheckUpdates: boolean;
|
fAutoCheckUpdates: boolean;
|
||||||
fShowBuildDuration: boolean;
|
fShowBuildDuration: boolean;
|
||||||
fToolBarScaling: TToolBarScaling;
|
fToolBarScaling: TToolBarScaling;
|
||||||
|
fAutoKillProcThreshold: dword;
|
||||||
function getConsoleProgram: string;
|
function getConsoleProgram: string;
|
||||||
procedure setConsoleProgram(const value: string);
|
procedure setConsoleProgram(const value: string);
|
||||||
function getAdditionalPATH: string;
|
function getAdditionalPATH: string;
|
||||||
|
@ -624,6 +625,7 @@ type
|
||||||
published
|
published
|
||||||
property additionalPATH: string read getAdditionalPATH write setAdditionalPath;
|
property additionalPATH: string read getAdditionalPATH write setAdditionalPath;
|
||||||
property autoCheckUpdates: boolean read fAutoCheckUpdates write fAutoCheckUpdates;
|
property autoCheckUpdates: boolean read fAutoCheckUpdates write fAutoCheckUpdates;
|
||||||
|
property autoKillProcThreshold: dword read fAutoKillProcThreshold write fAutoKillProcThreshold default 1024 * 1024 * 2;
|
||||||
property consoleProgram: string read getConsoleProgram write setConsoleProgram;
|
property consoleProgram: string read getConsoleProgram write setConsoleProgram;
|
||||||
property coverModuleTests: boolean read fCovModUt write fCovModUt;
|
property coverModuleTests: boolean read fCovModUt write fCovModUt;
|
||||||
property floatingWidgetOnTop: boolean read fFloatingWidgetOnTop write fFloatingWidgetOnTop;
|
property floatingWidgetOnTop: boolean read fFloatingWidgetOnTop write fFloatingWidgetOnTop;
|
||||||
|
@ -839,6 +841,7 @@ begin
|
||||||
fReloadLastDocuments:=true;
|
fReloadLastDocuments:=true;
|
||||||
fFlatLook:=true;
|
fFlatLook:=true;
|
||||||
fDcdPort:=DCDWrapper.port;
|
fDcdPort:=DCDWrapper.port;
|
||||||
|
fAutoKillProcThreshold := 1024 * 1024 * 2;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TApplicationOptionsBase.getNativeProjecCompiler: DCompiler;
|
function TApplicationOptionsBase.getNativeProjecCompiler: DCompiler;
|
||||||
|
@ -929,6 +932,7 @@ begin
|
||||||
MainForm.fDscanUnittests := fDscanUnittests;
|
MainForm.fDscanUnittests := fDscanUnittests;
|
||||||
nativeProjectCompiler:= fBackup.nativeProjectCompiler;
|
nativeProjectCompiler:= fBackup.nativeProjectCompiler;
|
||||||
fToolBarScaling:= fBackup.fToolBarScaling;
|
fToolBarScaling:= fBackup.fToolBarScaling;
|
||||||
|
fAutoKillProcThreshold:= fBackup.fAutoKillProcThreshold;
|
||||||
end
|
end
|
||||||
else inherited;
|
else inherited;
|
||||||
end;
|
end;
|
||||||
|
@ -945,6 +949,7 @@ begin
|
||||||
MainForm.fPrjGrpMru.maxCount:= fMaxRecentGroups;
|
MainForm.fPrjGrpMru.maxCount:= fMaxRecentGroups;
|
||||||
MainForm.updateFloatingWidgetOnTop(fFloatingWidgetOnTop);
|
MainForm.updateFloatingWidgetOnTop(fFloatingWidgetOnTop);
|
||||||
MainForm.fDscanUnittests := fDscanUnittests;
|
MainForm.fDscanUnittests := fDscanUnittests;
|
||||||
|
TDexedProcess.autoKillProcThreshold:= fAutoKillProcThreshold;
|
||||||
DcdWrapper.port:=fDcdPort;
|
DcdWrapper.port:=fDcdPort;
|
||||||
for i := 0 to MainForm.fWidgList.Count-1 do
|
for i := 0 to MainForm.fWidgList.Count-1 do
|
||||||
begin
|
begin
|
||||||
|
@ -968,6 +973,7 @@ begin
|
||||||
fBackup.fAutoCheckUpdates:= fAutoCheckUpdates;
|
fBackup.fAutoCheckUpdates:= fAutoCheckUpdates;
|
||||||
fBackup.fShowBuildDuration:= fShowBuildDuration;
|
fBackup.fShowBuildDuration:= fShowBuildDuration;
|
||||||
fBackup.nativeProjectCompiler:= nativeProjectCompiler;
|
fBackup.nativeProjectCompiler:= nativeProjectCompiler;
|
||||||
|
fBackup.fAutoKillProcThreshold := fAutoKillProcThreshold;
|
||||||
end
|
end
|
||||||
else inherited;
|
else inherited;
|
||||||
end;
|
end;
|
||||||
|
@ -2978,8 +2984,13 @@ begin
|
||||||
if inph.isNotNil then
|
if inph.isNotNil then
|
||||||
(inph as IProcInputHandler).removeProcess(proc);
|
(inph as IProcInputHandler).removeProcess(proc);
|
||||||
if (proc.ExitStatus <> 0) then
|
if (proc.ExitStatus <> 0) then
|
||||||
|
begin
|
||||||
fMsgs.message(format('error: the process (%s) has returned the status %s',
|
fMsgs.message(format('error: the process (%s) has returned the status %s',
|
||||||
[proc.Executable, prettyReturnStatus(proc)]), fDoc, amcEdit, amkErr);
|
[proc.Executable, prettyReturnStatus(proc)]), fDoc, amcEdit, amkErr);
|
||||||
|
if proc.autoKilled then
|
||||||
|
fMsgs.message(format('the process was autokilled because the size of its output exceeded %d',
|
||||||
|
[proc.autoKillProcThreshold]), nil, amcEdit, amkWarn);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.actSetRunnableSwExecute(Sender: TObject);
|
procedure TMainForm.actSetRunnableSwExecute(Sender: TObject);
|
||||||
|
|
|
@ -32,6 +32,8 @@ type
|
||||||
}
|
}
|
||||||
TDexedProcess = class(TASyncProcess)
|
TDexedProcess = class(TASyncProcess)
|
||||||
private
|
private
|
||||||
|
class var FAutoKillProcThreshold: dword;
|
||||||
|
var
|
||||||
fErrToOut: boolean;
|
fErrToOut: boolean;
|
||||||
fRealOnTerminate: TNotifyEvent;
|
fRealOnTerminate: TNotifyEvent;
|
||||||
fRealOnReadData: TNotifyEvent;
|
fRealOnReadData: TNotifyEvent;
|
||||||
|
@ -40,6 +42,7 @@ type
|
||||||
fTerminateChecker: TTimer;
|
fTerminateChecker: TTimer;
|
||||||
fDoneTerminated: boolean;
|
fDoneTerminated: boolean;
|
||||||
fHasRead: boolean;
|
fHasRead: boolean;
|
||||||
|
fAutoKilled: boolean;
|
||||||
procedure checkTerminated(sender: TObject);
|
procedure checkTerminated(sender: TObject);
|
||||||
procedure setOnTerminate(value: TNotifyEvent);
|
procedure setOnTerminate(value: TNotifyEvent);
|
||||||
procedure setOnReadData(value: TNotifyEvent);
|
procedure setOnReadData(value: TNotifyEvent);
|
||||||
|
@ -65,6 +68,10 @@ type
|
||||||
property hasRead: boolean read fHasRead;
|
property hasRead: boolean read fHasRead;
|
||||||
// indicates if OnTerminated was called
|
// indicates if OnTerminated was called
|
||||||
property doneTerminated: boolean read fDoneTerminated;
|
property doneTerminated: boolean read fDoneTerminated;
|
||||||
|
// indicates of the process was autokilled
|
||||||
|
property autoKilled: boolean read fAutoKilled;
|
||||||
|
// auto kill the process if its output reach this size
|
||||||
|
class property autoKillProcThreshold: dword read FAutoKillProcThreshold write FAutoKillProcThreshold;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -188,6 +195,7 @@ end;
|
||||||
|
|
||||||
procedure TDexedProcess.Execute;
|
procedure TDexedProcess.Execute;
|
||||||
begin
|
begin
|
||||||
|
fAutoKilled := false;
|
||||||
fHasRead := false;
|
fHasRead := false;
|
||||||
fStdoutEx.Clear;
|
fStdoutEx.Clear;
|
||||||
fStderrEx.Clear;
|
fStderrEx.Clear;
|
||||||
|
@ -214,6 +222,16 @@ procedure TDexedProcess.fillOutputStack;
|
||||||
outStr.SetSize(s + 1024);
|
outStr.SetSize(s + 1024);
|
||||||
c := inStr.Read((outStr.Memory + s)^, 1024);
|
c := inStr.Read((outStr.Memory + s)^, 1024);
|
||||||
s += c;
|
s += c;
|
||||||
|
|
||||||
|
if (FAutoKillProcThreshold <> 0) and not fDoneTerminated and
|
||||||
|
(fStderrEx.Size + fStdoutEx.Size >= FAutoKillProcThreshold) then
|
||||||
|
begin
|
||||||
|
fStdoutEx.Clear;
|
||||||
|
fAutoKilled := true;
|
||||||
|
Terminate(1);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
outStr.SetSize(s);
|
outStr.SetSize(s);
|
||||||
end;
|
end;
|
||||||
|
|
|
@ -272,6 +272,9 @@ begin
|
||||||
begin
|
begin
|
||||||
fMsgs.message(format('error: the tool (%s) has returned the status %s',
|
fMsgs.message(format('error: the tool (%s) has returned the status %s',
|
||||||
[fProcess.Executable, prettyReturnStatus(fProcess)]), nil, amcMisc, amkErr);
|
[fProcess.Executable, prettyReturnStatus(fProcess)]), nil, amcMisc, amkErr);
|
||||||
|
if fProcess.autoKilled then
|
||||||
|
fMsgs.message(format('the process was autokilled because the size of its output exceeded %d',
|
||||||
|
[fProcess.autoKillProcThreshold]), nil, amcMisc, amkWarn);
|
||||||
u_processes.killProcess(fProcess);
|
u_processes.killProcess(fProcess);
|
||||||
exit;
|
exit;
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue