RFC: block of commands
Philippe Waroquiers
philippe.waroquiers@skynet.be
Fri Jan 22 21:47:00 GMT 2016
I think that effectively, the principles you suggest below
should allow to make a reasonable syntax, and no backward
incompatibility.
So basically:
* trailing } is mandatory
* inside a block of commands, { } and ; must be escaped
* a command block is limited to be on a single line
I guess multiple lines will be ok if each line is terminated
by a \.
The above principles should also allow to extend if/while/...
to have 'one line' if/while/...
I also think that 'one line if' will allow to do things such as:
thread apply all if $ebp -$esp > 1000000 { echo big frame in this thread }
(today, trying to use an 'if' in thread apply gives a quite strange
behaviour : the rest of the 'if' command is read during each execution
for each thread, which is not very user friendly :).
I will work based on the above idea, and resubmit a draft patch
but that will for sure have to wait after FOSDEM, which
will already consume the night and week-end free time :).
Thanks for the comments/help/nice suggestions
Philippe
On Thu, 2016-01-21 at 01:29 +0000, Doug Evans wrote:
> 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.
More information about the Gdb-patches
mailing list