mirror of https://gitlab.com/basile.b/dexed.git
#97, redirect inferior output to file
This commit is contained in:
parent
ae740f0782
commit
49ecb0aa0a
|
|
@ -338,7 +338,10 @@ type
|
||||||
procedure Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
|
procedure Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||||
protected
|
protected
|
||||||
procedure setToolBarFlat(value: boolean); override;
|
procedure setToolBarFlat(value: boolean); override;
|
||||||
|
procedure updateLoop; override;
|
||||||
private
|
private
|
||||||
|
fExe: string;
|
||||||
|
fOutputName: string;
|
||||||
fUpdateMenu: boolean;
|
fUpdateMenu: boolean;
|
||||||
fGdbState: TGdbState;
|
fGdbState: TGdbState;
|
||||||
fSubj: TCEDebugObserverSubject;
|
fSubj: TCEDebugObserverSubject;
|
||||||
|
|
@ -350,6 +353,7 @@ type
|
||||||
fDocHandler: ICEMultiDocHandler;
|
fDocHandler: ICEMultiDocHandler;
|
||||||
fMsg: ICEMessagesDisplay;
|
fMsg: ICEMessagesDisplay;
|
||||||
fGdb: TCEProcess;
|
fGdb: TCEProcess;
|
||||||
|
fOutput: TFileStream;
|
||||||
fInspState: TInspectableCPU;
|
fInspState: TInspectableCPU;
|
||||||
fStackItems: TStackItems;
|
fStackItems: TStackItems;
|
||||||
fCatchPause: boolean;
|
fCatchPause: boolean;
|
||||||
|
|
@ -379,6 +383,7 @@ type
|
||||||
procedure setFpr(reg: TFpuRegister; val: extended);
|
procedure setFpr(reg: TFpuRegister; val: extended);
|
||||||
procedure setSsr(reg: TSegRegister; val: TCPUSegValue);
|
procedure setSsr(reg: TSegRegister; val: TCPUSegValue);
|
||||||
procedure setFlag(val: PtrUint);
|
procedure setFlag(val: PtrUint);
|
||||||
|
procedure readOutput;
|
||||||
//
|
//
|
||||||
procedure projNew(project: ICECommonProject);
|
procedure projNew(project: ICECommonProject);
|
||||||
procedure projChanged(project: ICECommonProject);
|
procedure projChanged(project: ICECommonProject);
|
||||||
|
|
@ -498,6 +503,12 @@ begin
|
||||||
if fname.fileExists then
|
if fname.fileExists then
|
||||||
loadFromFile(fname);
|
loadFromFile(fname);
|
||||||
EntitiesConnector.addObserver(self);
|
EntitiesConnector.addObserver(self);
|
||||||
|
fShowGdbOutput:=false;
|
||||||
|
fShowOutput:= true;
|
||||||
|
fAutoDemangle:= true;
|
||||||
|
fAutoGetCallStack:= true;
|
||||||
|
fAutoGetRegisters:= true;
|
||||||
|
fAutoGetVariables:= true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TCEDebugOptions.destroy;
|
destructor TCEDebugOptions.destroy;
|
||||||
|
|
@ -833,6 +844,7 @@ end;
|
||||||
|
|
||||||
destructor TCEGdbWidget.destroy;
|
destructor TCEGdbWidget.destroy;
|
||||||
begin
|
begin
|
||||||
|
fOutput.Free;
|
||||||
fOptions.commandsHistory.Assign(edit1.Items);
|
fOptions.commandsHistory.Assign(edit1.Items);
|
||||||
fOptions.Free;
|
fOptions.Free;
|
||||||
fFileLineBrks.Free;
|
fFileLineBrks.Free;
|
||||||
|
|
@ -1033,6 +1045,8 @@ begin
|
||||||
if fProj <> project then
|
if fProj <> project then
|
||||||
exit;
|
exit;
|
||||||
fProj := nil;
|
fProj := nil;
|
||||||
|
if fOutputName.fileExists then
|
||||||
|
deleteFile(fOutputName);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEGdbWidget.projFocused(project: ICECommonProject);
|
procedure TCEGdbWidget.projFocused(project: ICECommonProject);
|
||||||
|
|
@ -1196,8 +1210,9 @@ begin
|
||||||
exit;
|
exit;
|
||||||
if fProj.binaryKind <> executable then
|
if fProj.binaryKind <> executable then
|
||||||
exit;
|
exit;
|
||||||
str := fProj.outputFilename;
|
fExe := fProj.outputFilename;
|
||||||
if not str.fileExists then
|
fOutputName := fExe + '.gdbout';
|
||||||
|
if not fExe.fileExists then
|
||||||
exit;
|
exit;
|
||||||
gdb := exeFullName('gdb');
|
gdb := exeFullName('gdb');
|
||||||
if not gdb.fileExists then
|
if not gdb.fileExists then
|
||||||
|
|
@ -1208,7 +1223,7 @@ begin
|
||||||
fGdb := TCEProcess.create(nil);
|
fGdb := TCEProcess.create(nil);
|
||||||
fGdb.Executable:= gdb;
|
fGdb.Executable:= gdb;
|
||||||
fgdb.Options:= [poUsePipes, poStderrToOutPut];
|
fgdb.Options:= [poUsePipes, poStderrToOutPut];
|
||||||
fgdb.Parameters.Add(str);
|
fgdb.Parameters.Add(fExe);
|
||||||
|
|
||||||
//TODO-cGDB: debugee environment
|
//TODO-cGDB: debugee environment
|
||||||
//TODO-cGDB: debugee command line
|
//TODO-cGDB: debugee command line
|
||||||
|
|
@ -1247,7 +1262,10 @@ begin
|
||||||
gdbCommand('-gdb-set mi-async on');
|
gdbCommand('-gdb-set mi-async on');
|
||||||
fGdb.OnReadData := @gdboutJsonize;
|
fGdb.OnReadData := @gdboutJsonize;
|
||||||
// launch
|
// launch
|
||||||
gdbCommand('run');
|
gdbCommand('run >' + fExe + '.gdbout');
|
||||||
|
FreeAndNil(fOutput);
|
||||||
|
if fOutputName.fileExists then
|
||||||
|
fOutput := TFileStream.Create(fOutputName, 0);
|
||||||
setState(gsRunning);
|
setState(gsRunning);
|
||||||
end;
|
end;
|
||||||
{$ENDREGION}
|
{$ENDREGION}
|
||||||
|
|
@ -1293,19 +1311,6 @@ procedure parseGdbout(const str: string; var json: TJSONObject);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure parseInferior(node: TJSONObject; r: PStringRange);
|
|
||||||
begin
|
|
||||||
while true do
|
|
||||||
begin
|
|
||||||
// TODO-cGDB: detect invalid command after GDB prefix, maybe inferior output
|
|
||||||
if r^.empty or (r^.front in ['~','^','*','=','&',(*'+',*)'@']) then
|
|
||||||
break;
|
|
||||||
node.Arrays['OUT'].Add(r^.takeUntil(#10).yield);
|
|
||||||
if not r^.empty then
|
|
||||||
r^.popFront;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure parseProperty(node: TJSONArray; r: PStringRange);
|
procedure parseProperty(node: TJSONArray; r: PStringRange);
|
||||||
var
|
var
|
||||||
c: char;
|
c: char;
|
||||||
|
|
@ -1455,7 +1460,7 @@ begin
|
||||||
rng.popFront;
|
rng.popFront;
|
||||||
end;
|
end;
|
||||||
// async notify / status / out stream when remote (@)
|
// async notify / status / out stream when remote (@)
|
||||||
'=', (*'+',*)'@':
|
'=', '+','@':
|
||||||
begin
|
begin
|
||||||
rng.popUntil(#10);
|
rng.popUntil(#10);
|
||||||
if not rng.empty then
|
if not rng.empty then
|
||||||
|
|
@ -1463,11 +1468,9 @@ begin
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
if rng.startsWith('(gdb)') then
|
rng.popUntil(#10);
|
||||||
rng.popFrontN(7)
|
if not rng.empty then
|
||||||
// empty line, inferior output
|
rng.popFront;
|
||||||
else
|
|
||||||
parseInferior(json, @rng);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
@ -1532,6 +1535,7 @@ begin
|
||||||
fDocHandler.openDocument(fullname);
|
fDocHandler.openDocument(fullname);
|
||||||
setState(gsPaused);
|
setState(gsPaused);
|
||||||
autoGetStuff;
|
autoGetStuff;
|
||||||
|
readOutput;
|
||||||
subjDebugBreak(fSubj, fullname, line, brkreason);
|
subjDebugBreak(fSubj, fullname, line, brkreason);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -1567,6 +1571,7 @@ begin
|
||||||
fDocHandler.openDocument(fullname);
|
fDocHandler.openDocument(fullname);
|
||||||
autoGetStuff;
|
autoGetStuff;
|
||||||
setState(gsPaused);
|
setState(gsPaused);
|
||||||
|
readOutput;
|
||||||
subjDebugBreak(fSubj, fullname, line, dbSignal);
|
subjDebugBreak(fSubj, fullname, line, dbSignal);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|
@ -1584,6 +1589,7 @@ begin
|
||||||
fDocHandler.openDocument(fullname);
|
fDocHandler.openDocument(fullname);
|
||||||
autoGetStuff;
|
autoGetStuff;
|
||||||
setState(gsPaused);
|
setState(gsPaused);
|
||||||
|
readOutput;
|
||||||
subjDebugBreak(fSubj, fullname, line, dbSignal);
|
subjDebugBreak(fSubj, fullname, line, dbSignal);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
@ -1591,6 +1597,9 @@ begin
|
||||||
|
|
||||||
else if (reason = 'exited-normally') or (reason = 'exited-signalled') then
|
else if (reason = 'exited-normally') or (reason = 'exited-signalled') then
|
||||||
begin
|
begin
|
||||||
|
readOutput;
|
||||||
|
if not fOptions.showGdbOutput then
|
||||||
|
fMsg.message('debugging terminated: ' + reason, nil, amcMisc, amkInf);
|
||||||
setState(gsNone);
|
setState(gsNone);
|
||||||
subjDebugStop(fSubj);
|
subjDebugStop(fSubj);
|
||||||
end;
|
end;
|
||||||
|
|
@ -1718,14 +1727,6 @@ begin
|
||||||
fMsg.message(arr.Strings[i], nil, amcMisc, amkBub);
|
fMsg.message(arr.Strings[i], nil, amcMisc, amkBub);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if fOptions.showOutput then
|
|
||||||
begin
|
|
||||||
arr := TJSONArray(fJson.Find('OUT'));
|
|
||||||
if arr.isNotNil then
|
|
||||||
for i := 0 to arr.Count-1 do
|
|
||||||
fMsg.message(arr.Strings[i], nil, amcMisc, amkBub);
|
|
||||||
end;
|
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEGdbWidget.gdboutJsonize(sender: TObject);
|
procedure TCEGdbWidget.gdboutJsonize(sender: TObject);
|
||||||
|
|
@ -1738,8 +1739,8 @@ begin
|
||||||
|
|
||||||
fLog.Clear;
|
fLog.Clear;
|
||||||
fGdb.getFullLines(fLog);
|
fGdb.getFullLines(fLog);
|
||||||
for str in fLog do
|
//for str in fLog do
|
||||||
fMsg.message(str, nil, amcMisc, amkAuto);
|
// fMsg.message(str, nil, amcMisc, amkAuto);
|
||||||
|
|
||||||
if flog.Text.isEmpty then
|
if flog.Text.isEmpty then
|
||||||
exit;
|
exit;
|
||||||
|
|
@ -1758,6 +1759,35 @@ begin
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCEGdbWidget.updateLoop;
|
||||||
|
begin
|
||||||
|
if fGdbState <> gsNone then
|
||||||
|
readOutput;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCEGdbWidget.readOutput;
|
||||||
|
var
|
||||||
|
str: TMemoryStream;
|
||||||
|
lst: TStringList;
|
||||||
|
lne: string;
|
||||||
|
begin
|
||||||
|
if (fGdbState = gsNone) or not fOptions.showOutput or fOutput.isNil then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
str := TMemoryStream.Create;
|
||||||
|
lst := TStringList.Create;
|
||||||
|
try
|
||||||
|
str.size := fOutput.Size - fOutput.Position;
|
||||||
|
fOutput.Read(str.Memory^, str.Size);
|
||||||
|
lst.LoadFromStream(str);
|
||||||
|
for lne in lst do
|
||||||
|
fMsg.message(lne, nil, amcMisc, amkBub);
|
||||||
|
finally
|
||||||
|
lst.Free;
|
||||||
|
str.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCEGdbWidget.gdboutQuiet(sender: TObject);
|
procedure TCEGdbWidget.gdboutQuiet(sender: TObject);
|
||||||
begin
|
begin
|
||||||
fGdb.OutputStack.Clear;
|
fGdb.OutputStack.Clear;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue