This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: block of commands


Philippe Waroquiers writes:
 > On Mon, 2016-01-11 at 21:40 +0000, Doug Evans wrote:
 > > Heya.
 > >
 > > One feature I've always wanted gdb's cli to have is the
 > > ability to catch errors and be able to continue.
 > > There's always a tension of whether to add things to the cli
 > > or just say "do it in python". gdb scripts are still useful
 > > and thus sometimes I think it's ok to extend the cli, such
 > > as in this case.
 > > Thus instead of /c in this patch I'd prefer something
 > > along the lines of "try ... end".
 > > ["end" is gdb's canonical "trailing }", and I'm all for
 > > Consistency Is Good here.]
 > > The actual details and semantics of "try" I would
 > > leave to a separate thread. For one, I'd have to think
 > > about it some more :-), but I would support someone
 > > wanting to go down that path.
 > >
 > > OTOH, trying to extend the cli's syntax with { and ; is not
 > > something I can support, at least not without more discussion.
 > > This example:
 > >
 > >      thread apply all { set $prevsp = $sp; bt \{ p $ebp - $prevsp\; set
 > > $prevsp = $sp \} }
 > >        => print the size of each frame
 > >
 > > suggests things could be better; having to escape braces within
 > > subcommands feels excessively error prone.
 > > gdb has one line per command, and changing that
 > > may make things too unwieldly.
 > The { (and have the terminating } optional) was chosen in order
 > to make the interactive typing of a block of command faster/easier.
 > I agree that this new syntax is very different of the
 > 'usual gdb multi-lines terminated by end'.
 >
 > However, multi-lines with end means the user cannot simply type e.g.
 >    thread apply all { p i; p j}
 > Instead, the user must type:
 >    define pij
 >    p i
 >    p j
 >    end
 >   thread apply all pij
 > And after, if the user wants to also print k,
 > then the pij sequence must be retyped (I do not know a way
 > to change/edit/complete a user defined command).

Yeah. I recognize the difficulty.
But adding {...; ...} on top of what's there now
is going to be a slippery slope I fear.
[maybe not, but we're adding syntax to what
has until now been pretty free form]
I want to make sure that if we add this,
we don't some day end up regretting it.

Note that at least within emacs I can repeat/edit
multi-line commands by going back through the history.
Plus one can redefine user-defined commands
from the keyboard. So it's possible, if tedious.

 > An alternative might be to make the terminating } mandatory.
 > Then I think we could get rid of the { and } escaping

I'd prefer to be strict (e.g., require }), at least for now.
Once we add { ...; ... }, someone is going to want to extend it,
and then we've got if/while/etc. that can all be done as one-liners.
[If we're going to make interactive use easier, why can't
if/while/etc. be done as one-liners? It feels like if a
compelling argument can't be made to allow them to be one-liners,
then supporting one-liners in a more restricted fashion
isn't very compelling and maybe we should just punt.]
Let's think this through.

 > So, the question is how much we want to make the block of commands
 > easy to use interactively ?
 >
 > Maybe it is not that unusual to have 2 concepts
 > of 'list of commands' :
 >     one command per line, with some 'begin/end' keywords
 >    several commands per lines, separated by ;
 > (i.e. similar to what a shell is providing with if/fi and ;).
 >
 > The ; separated list versus multi-lines is clearly the main
 > point of discussion.
 >
 > Note that if ever the {}; idea survives, we have to take care
 > about parsing of existing scripts that would do e.g.
 >    echo { is an open bracket
 > Not too sure it will be easy to make the {}; idea fully backward
 > compatible :(

That's going to be a tricky part, yeah.

Existing "echo {" may not be so bad, as echo doesn't take a command
as an argument. While less than ideal, we could defer parsing
{ ... } until we're parsing a command that takes a command as
an argument (either literally, as in "thread apply ...",
or conceptually, as in "if expr ...").
Of course, extending "if/while" like this would be problematic if
a language allowed { in an expression.

Another thought is: If we extend this to if/while/etc.
then it'd be odd to not be able to terminate a multi-line "if"
with }, except that there is no opening { in a multi-line "if".
So does that mean { ... } is restricted to one line?
Probably, but it may trip people up from time to time.

Another thought: What does this do?

if a == b { echo foo }

If we don't enforce a trailing } then is that "echo foo" or "echo foo }"?
Maybe a good example to suggest we should indeed require a trailing }?

Similarly with ;

if a == b { echo foo; }

These questions apply even if we don't extend "if":

thread apply all { echo foo; }

 > > There are still
 > > macros so one could still do "thread apply all print-frame-size",
 > > and put the guts of frame size computation in a macro named
 > > print-frame-size.
 > True, but that makes the interactive use and editing
 > not so easy (cfr above).

Yep.
This is a significant addition,
I'm just asking for a thorough vetting of it.

Deciding how to parse embedded {/;/} is probably
the important part (as you've mentioned).

E.g., if a == b { if c == d { echo foo; }; echo bar }

or

thread apply all { frame apply all { echo \{foo\}; printf "\{foo\}"; } }

We have to find the outer } so we know what command to
execute for each thread, but in order to do that we
have to do some parsing of the inner command in order
to handle the nesting.
Plus, as you've mentioned, we'll need some kind of escaping;
when we run the "frame apply all" command is it:
echo {foo}; printf "\{foo\}"
?

Since this is new syntax, we're free to define things
however we like, within reason.

 > > Also, I'd prefer to have generally composable commands
 > > over extending individual commands.
 > > E.g., one common thing to do with "thread apply" is backtrace,
 > > as in "thread apply all bt". I like that much better than
 > > if we had extended backtrace to work on each thread.
 > >
 > > Following "Consistency Is Good", and given that we have
 > > "thread apply", for your "bt {/c p i" case how about
 > > something like:
 > >
 > > frame apply all foo
 > Yes, that looks better than adding an optional command to
 > backtrace.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]