From: Andrew Burgess <andrew.burgess@embecosm.com>
To: Marco Barisione <mbarisione@undo.io>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH 2/2] Add a way to preserve redefined GDB commands for later invocation
Date: Mon, 5 Oct 2020 19:11:00 +0100 [thread overview]
Message-ID: <20201005181100.GI605036@embecosm.com> (raw)
In-Reply-To: <27432854-8CFD-47A2-BB9C-62B8D921E1EA@undo.io>
* Marco Barisione <mbarisione@undo.io> [2020-10-05 12:44:03 +0100]:
> On 5 Oct 2020, at 11:24, Andrew Burgess <andrew.burgess@embecosm.com> wrote:
> >> +/* Implementation of the "uplevel" command. */
> >> +
> >> +static void
> >> +uplevel_command (const char *arg, int from_tty)
> >> +{
> >> + /* Extract the level argument and update arg to point to the remaining
> >> + string. */
> >> + size_t level_end_offset;
> >> + int level;
> >> + try
> >> + {
> >> + level = std::stoi (arg, &level_end_offset);
> >> + }
> >> + catch (const std::exception &)
> >> + {
> >> + level = -1;
> >> + }
> >> + if (level < 0)
> >> + error (_("uplevel command requires a non-negative number for the "
> >> + "level argument."));
> >
> > I don't understand why the Python API allows for negative values while
> > the CLI command does not. In my mind, negative values are the only
> > really useful way to use this feature as it should be considered bad
> > practice to assume that there are not some unknown number of overrides
> > above you in the command stack.
>
> This is briefly explained in the first email
> (https://sourceware.org/pipermail/gdb-patches/2020-September/171829.html).
>
> I didn’t want to do too much for this patch series in case the whole approach
> was wrong.
> One of the things I didn’t do (for now) was this as I couldn't find an obvious
> way for the "uplevel" command to know which command you are currently
> executing. An option could be to implement something similar way to how
> command arguments are kept around with scoped_user_args_level, so we could
> keep a stack of all (user and non-user) commands which are being executed.
> By checking the latest one you can know what "uplevel -1" would
> apply to.
I think this would be a fine approach. I'd pack the command pointer
and arguments into a single object and store these in a newly renamed
scoped_user_args_level I think.
>
> Another question I couldn’t answer is what "uplevel -1 …" would do if used
> outside a definition.
> Should it show an error or should it just invoke the latest defined command?
> In the latter case, wouldn’t it confusing that "-1" has a different meaning
> inside or outside commands?
Yeah I don't think the last case would be a good way to go, but what
about executing the last but one version of the command, this would
seem exactly inline with the behaviour inside a command, so:
(gdb) define cmd_1
echo v1\n
end
(gdb) define cmd_1
echo v2\n
uplevel -1 cmd_1
end
(gdb) cmd_1
v2
v1
(gdb) uplevel 0 cmd_1
v1
(gdb) uplevel -1 cmd
v1
>
> Note that there’s another bit of useful work that I didn’t do, that is the
> addition of a way of accessing all the untokenized arguments from a command
> definition.
>
> > I think that there is another useful check that should be added to
> > this patch, I think we should prohibit calling a command further down
> > the command stack. That is we should make this invalid:
> >
> > define cmd_1
> > echo this is level 0 cmd_1\n
> > uplevel 1 cmd_1
> > end
> >
> > define cmd_1
> > echo this is level 1 cmd_1\n
> > uplevel 0 cmd_1
> > end
> >
> > What I'd like to see is that when we execute 'uplevel 1 cmd_1' GDB
> > throws an error about '... requested command at higher level
> > than current command...' or similar.
> >
> > The above will eventually error with 'Max user call depth exceeded --
> > command aborted.', but I think explicitly catching this case would
> > improve the user experience.
>
> How about the case where a command on the same level is invoked?
> I considered this (there should be a comment somewhere) but thought it’s
> not a real problem as there may be some legitimate cases (for instance
> if the arguments are changed) and, if things go wrong, you just get a
> max user call depth exceeded.
But at the same level can't you just call the command by name with no
'uplevel' at all?
>
> The same weird but legitimate case may in theory exist also for
> invoking a command at a higher level, i.e. the arguments are
> changed.
Yeah... no.
I'm sure it's possible to craft an example where this might work, but
I think we should start off by blocking this, then if someone comes up
with a really good example of why this is needed, and is the _only_
way to solve there problem then we can rip the check out.
In general I think you could only call to a higher level if you had
full control over how the commands are written and the order they are
registered, in which case (I boldly claim) there would be a better way
to rewrite the code to avoid calling to a higher level.
IF you don't have full control over what was registered later, or the
order in which parts are registered then this would never work.
In short I think blocking this will help far more than it hurts.
>
> > I also wonder how we might handle _really_ redefining a command now
> > that past commands hang around.
> >
> > When writing the above cmd_1 example the first thing I did was open
> > GDB and try to write the commands at the CLI. I made a typo when
> > writing the second version of cmd_1. So now I'm stuck with a chain:
> >
> > working level 0 cmd_1 --> broken level 1 cmd_1
> >
> > Sure I can write a level 2 version that knows to skip over the broken
> > level 1, but it might be nice if there was a flag somewhere that I
> > could pass to say, no, really replace the last version of this command
> > please.
>
> Is this really what a user would want? Or would they want the ability
> to delete commands?
Deleting too might be useful, but I think the case I gave is not
unique to me, I tried writing a command, I got it slightly wrong.
Sure I can delete and start again, but being able to just do:
(gdb) define --redefine cmd_1
...
would be nice.
>
> > Also, when I define cmd_1 (at the CLI) I get asked:
> >
> > Redefine command "cmd_1"? (y or n)
> >
> > Maybe this could/should be changed to:
> >
> > "cmd_1" already exists, type 'o' to override, 'r' to replace, or 'q' to quit:
> >
> > I'm thinking about the pager prompt which is more than just y/n. I
> > haven't looked how easy it would be to do something similar here.
>
> I don’t think it would be too difficult but it means that the user must
> decide what they want early and they can’t change their minds.
> What happens if you accidentally replace a command but you wanted to
> override it instead?
Well, GDB offers a programmable environment, we don't allow undoing
most (or hardly any) actions, so I think users are OK with the idea
that some action might not be reversible.
>
> > One last thing I note is that this new functionality is very similar
> > to the existing "hook-" and "hookpost-" functionality, though I think
> > this new approach is much better.
>
> My goal with my patches was to get rid of hooks in my own code.
>
> > I think as a minimum the documentation for the old hook approach
> > should be updated to indicate that that technique is deprecated, and
> > this new approach should be used instead.
>
> Good point.
>
> > Where I really think we should be going is adding a patch #3 to this
> > series that replaces the implementation of the old functionality using
> > your new code. Meaning, when someone writes:
> >
> > define hook-echo
> > echo before\n
> > end
> >
> > GDB would internally change this to effectively be:
> >
> > define echo
> > echo before\n
> > uplevel -1 echo
> > end
> >
> > this will work for many trivial cases. There's a few nasty corners,
> > like hooks for sub-commands (see the docs on hooking 'target remote'),
> > the pseudo-command 'stop', and calling the same command from within a
> > hook.
>
> Hm, difficult to say how difficult it could be but I will have a look.
>
> There may also be other subtle different behaviours we don’t know about
> and which could break existing scripts. Is this acceptable?
Nothing is completely risk free, and I don't know how well tested the
hooks support is, but it would be nice if we could fully replace hooks
with your code (which is a much better approach).
Thanks,
Andrew
>
> --
> Marco Barisione
>
next prev parent reply other threads:[~2020-10-05 18:11 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-14 9:39 Add a way to invoke redefined (overridden) GDB commands Marco Barisione
2020-09-14 9:39 ` [PATCH 1/2] Move the code to execute a cmd_list_element out from execute_command Marco Barisione
2020-10-05 9:08 ` Andrew Burgess
2020-10-05 9:40 ` Marco Barisione
2020-10-05 17:49 ` Andrew Burgess
2020-09-14 9:39 ` [PATCH 2/2] Add a way to preserve redefined GDB commands for later invocation Marco Barisione
2020-09-14 16:18 ` Eli Zaretskii
2020-09-14 16:51 ` Marco Barisione
2020-10-05 10:24 ` Andrew Burgess
2020-10-05 11:44 ` Marco Barisione
2020-10-05 18:11 ` Andrew Burgess [this message]
2020-10-06 7:18 ` Marco Barisione
2020-09-28 7:54 ` [PING] Add a way to invoke redefined (overridden) GDB commands Marco Barisione
2020-10-05 7:42 ` Marco Barisione
2020-10-12 11:50 ` Pedro Alves
2020-10-19 17:41 ` Marco Barisione
2020-10-19 18:05 ` Pedro Alves
2020-10-19 18:47 ` Philippe Waroquiers
2020-10-19 19:28 ` Marco Barisione
2020-10-20 15:06 ` Pedro Alves
2020-10-20 18:19 ` Marco Barisione
2020-10-20 18:32 ` Pedro Alves
2020-10-20 15:15 ` Pedro Alves
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201005181100.GI605036@embecosm.com \
--to=andrew.burgess@embecosm.com \
--cc=gdb-patches@sourceware.org \
--cc=mbarisione@undo.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).