[PATCH v2] Add a way to preserve overridden GDB commands for later invocation

Andrew Burgess andrew.burgess@embecosm.com
Tue Nov 5 10:17:00 GMT 2019


* Marco Barisione <mbarisione@undo.io> [2019-11-01 21:01:18 +0000]:

> On 1 Nov 2019, at 19:18, Tom Tromey <tom@tromey.com> wrote:
> >>>>>> "Marco" == Marco Barisione <mbarisione@undo.io> writes:
> > Could you say what unexpected behavioural changes you would anticipate?
> > I tend to think it would be clearer if all commands were treated
> > identically.
> > 
> > Is there some implementation difficulty doing it?  Or was it just that
> > you didn't think it was useful?
> 
> I was mainly worried about changing the behaviour in ways which could be
> unexpected.  For instance, an instance of gdb.Command may end up living longer
> than expected.
> Another thing is that a command which was written before this patch may not be
> using the original implementation just because it was not possible before, so
> block a further command from accessing it as well.  See the example later in
> the email.
> 
> If you don't think these are problems I'm happy to simplify the code.
> 
> > In this model, if a Python command overrides a built-in command, and
> > then is itself overridden, can the new command still access the
> > underlying built-in command?
> 
> Let's say you override delete. Let's call the first class overriding it
> DeleteCommand1 and the second DeleteCommand2.
> 
> If DeleteCommand1 didn't use preserve_when_overridden then
> DeleteCommand2.invoke_overridden will just call the original delete.
> 
> If DeleteCommand1 was preserved, then DeleteCommand2.invoke_overridden
> will call DeleteCommand1.invoke.  At this point DeleteCommand1 may just do
> whatever it needs on its own, or call its own invoke_overridden method
> which will call the original delete command.
> DeleteCommand2 has not way to invoke the original delete command directly.
> This is partly because I'm not sure how I would expose this in a nice way,
> but mainly because I don't want commands to accidentally skip some
> previous implementation by accident.  For instance, if we had an
> invoke_original method, then DeleteCommand2 could call that and skip
> DeleteCommand1.

I too have sometimes wondered about providing override type
behaviour.

I wonder, instead of having 'invoke_overridden' and/or
'invoke_original', if we could/should look to TCL for inspiration,
specifically it's uplevel command[1].

If we consider your 'delete' example, the builtin delete would be
considered to be at level 0, then we define DeleteCommand1, this would
be level 1, and then comes DeleteCommand2 which would be at level 2.

Inside DeleteCommand1 we can do:

  DeleteCommand1.invoke_uplevel (-1, args)

this would invoke the command one level down the stack, so in this
case the builtin delete.  In DeleteCommand2 we can do:

  DeleteCommand2.invoke_uplevel (-1, args)

again, this invokes the command one level down the stack, so in this
case DeleteCommand1.

However, we could also use:

  DeleteCommand2.invoke_uplevel (0, args)

In this case the level argument 0 indicates we want to directly access
the instance of the command at level 0.

Where I would find this idea really interesting is that we could
easily provide access to this functionality from the command line.
This might be useful in two ways I think, first, if a Python script
has overridden a command and a user wants to quickly bypass that for
some reason they can just do:

  (gdb) uplevel 0 delete args...

in order to get the base version of the command.  Second, with some
extra work we could make the existing hook mechanism redundant, and
possibly provide something more flexible (maybe?), consider:

  define delete
    echo Basically a pre-hook here\n
    uplevel -1 delete $argv
    echo Basically a post-hook here\n
  end

Notice I just invented '$argv' on the fly there - this doesn't exist
currently, but I'm imagining that this would expand to all of the
arguments passed to the newly defined 'delete' command.

Anyway, I don't think all of the ideas mentioned above would need to
be implemented in one go, but I thought it might be worth mentioning
some of the thoughts I'd had in this area.

Thanks,
Andrew

[1] https://www.tcl.tk/man/tcl8.4/TclCmd/uplevel.htm



More information about the Gdb-patches mailing list