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