gdb com, allow to pass stdin upon debugging starts

close #101
This commit is contained in:
Basile Burg 2021-11-10 04:08:35 +01:00
parent ba2489d3e6
commit 6281f395cd
3 changed files with 54 additions and 17 deletions

View File

@ -1,6 +1,13 @@
# v3.9.16-dev
## Enhancements
- DUB projects, options, removed _dependencyCheck_ and replaced with a new _skipRegistry_ option that maps 1:1 to the official documentation.
- GDB commander: add debugee option _queryInput_ in addition to the existing system. That has for effect to query the input, pass it to the inferior stdin and close the stream. (#101)
- GDB commander: allow to close the input stream using _>_ in the widget field at the bottom.
## Bugs fixed
- editor, option _textCompletionMinLength_ min length off-by-one.
# v3.9.15

View File

@ -36,7 +36,8 @@ This page allows to edit the options passed to the debugger target (also called
- **arguments**: Allows to set the target command line arguments. One item per line. Items can include [symbolic strings](features_symbolic_strings.html) and be deactiviated by prepending `\\`.
- **environmentPaths**: Allows to add additional folders to the PATH variable. One item per line.
- **queryArguments**: When checked and when the debugging cession starts a small input dialog is displayed. It can be used to pass more **--para --meters** to the target.
- **queryArguments**: When checked and when the debugging cession starts an input dialog is displayed. It can be used to pass more **--para --meters** to the target.
- **queryInput**: When checked an when debugging starts, an input dialog allows to pass some test to the inferior input stream.
- **target**: Read-only. Indicates clearly which is the project or the runnable module that will be debugged.
- **workingDirectory**: Allows to set the target working directory. Can include [symbolic strings](features_symbolic_strings.html).
@ -76,11 +77,6 @@ The option **showRawMiOutput** must be activated in order to get the GDB answer
Learn more about the commands and the MI syntax in [the official manual](http://sourceware.org/gdb/current/onlinedocs/gdb/).
Example of useful commands:
- **-stack-list-variables --skip-unavailable --all-values**: prints a more complete list of variable that the default one. Can be used to set a watchpoint on a variable that's not listed by default.
- **-data-list-register-values xmm0 d**: prints the value of XMM0 as a decimal number. For now the CPU inspector doesn't display the SSE registers so this is the only way to inspect them.
Note that even if in most of the cases the results of a custom command are displayed in the messages a special processing may happen:
- Any commands that may cause an execution break is handled by the interpreter (.so library events, fork events, system calls, function finished, etc).
@ -92,6 +88,10 @@ The field at the bottom is also used to pass new lines to the target standard in
To differentiate a custom command from an input line, use the `>` (greater than) symbol.
The text following the symbol is written to the input stream, with an implicit new line character at the end.
If not text follows `>` then the inferir stdin stream get closed.
Note that if the option _queryInput_ is used then the input stream is not available anymore for write.
## Options
![](img/options_gdb_commander.png)

View File

@ -377,6 +377,7 @@ type
TDebugeeOption = class(TCollectionItem)
strict private
fQueryArguments: boolean;
fQueryInput: boolean;
fFname: string;
fWorkingDir: TPathname;
fAgruments: TStringList;
@ -388,6 +389,7 @@ type
property filename: string read fFname write fFname;
property arguments: TStringList read fAgruments write setOptions;
property queryArguments: boolean read fQueryArguments write fQueryArguments default false;
property queryInput: boolean read fQueryInput write fQueryInput default false;
property target: string read fFname;
property workingDirectory: TPathname read fWorkingDir write fWorkingDir;
public
@ -526,6 +528,7 @@ type
fStackItems: TStackItems;
fCatchPause: boolean;
fSilentPause: boolean;
fInputClosed: boolean;
fOptions: TDebugOptions;
fAddWatchPointKind: TAddWatchPointKind;
fBreakPoints: TPersistentBreakPoints;
@ -1156,8 +1159,10 @@ end;
constructor TDebugeeOption.Create(ACollection: TCollection);
begin
inherited create(ACollection);
fAgruments := TStringList.Create;
fEnvPaths := TStringList.Create;
fAgruments := TStringList.Create;
fEnvPaths := TStringList.Create;
fQueryInput := false;
fQueryArguments := false;
fAgruments.Delimiter:= ' ';
end;
@ -1933,6 +1938,7 @@ end;
procedure TGdbWidget.startDebugging;
var
str: string = '';
inp: string = '';
gdb: string;
i: integer;
b: TPersistentBreakPoint;
@ -1940,6 +1946,7 @@ var
const
asmFlavorStr: array[TAsmSyntax] of string = ('intel','att');
begin
fInputClosed := false;
clearDisplays;
if (fDebugTargetKind = dtkProject) and fProj.isNotAssigned then
begin
@ -2096,6 +2103,13 @@ begin
str += o.arguments[i] + ' ';
str := fSyms.expand(str);
end;
if o.queryInput and InputQuery('Inferior stdin', 'GDB commander', inp) then
begin
fInput.WriteBuffer(inp[1], inp.length);
FileFlush(fInput.Handle);
FileClose(fInput.Handle);
fInputClosed := true;
end;
gdbCommand('-exec-arguments '+ str + '> ' + fOutputName + '< ' + fInputName);
// non-MI command "run" has the same problem as https://sourceware.org/bugzilla/show_bug.cgi?id=18077
gdbCommand('-exec-run');
@ -3116,15 +3130,31 @@ begin
cmd := fSyms.expand(cmd);
if (cmd.length > 1) and (cmd[1] = '>') and fInput.isAssigned then
begin
cmd := cmd[2..cmd.length] + #10;
fInput.Write(cmd[1], cmd.length);
{$IFDEF UNIX}
fpfsync(fInput.Handle);
{$ELSE}
FlushFileBuffers(fInput.Handle);
{$ENDIF}
sleep(100);
readOutput;
if not fInputClosed then
begin
cmd := cmd[2..cmd.length] + #10;
if cmd <> '' then
begin
fInput.Write(cmd[1], cmd.length);
{$IFDEF UNIX}
fpfsync(fInput.Handle);
{$ELSE}
FlushFileBuffers(fInput.Handle);
{$ENDIF}
sleep(100);
readOutput;
end;
end
else fMsg.message('inferior stdin is closed', nil, amcMisc, amkWarn);
end
else if (cmd.length = 1) and (cmd[1] = '>') then
begin
if not fInputClosed then
begin
FileClose(fInput.Handle);
fInputClosed:=true;
end
else fMsg.message('inferior stdin is already closed', nil, amcMisc, amkWarn);
end
else
begin