This is the mail archive of the gdb@sourceware.cygnus.com 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]

Re: libGDB architecture


Ovidiu Predescu wrote:
> 
> Hi,
> 
> Sorry for being so late, but only now I had some time to read through the
> libGDB architecture proposal thread.

My turn for being slow :-(

> Andrew, please correct me if I'm wrong here. My understanding of the proposal
> is that we'll have an abstract layer on top of GDB that receives commands
> through an input stream and spits out the GDB internal structures in a given
> format, that could easily be changed to meet one's particular needs. There are
> at least two obvious advantages for such an approach: (1) there is no need to
> change much of the GDB's internals in order to support it and (2) a libGDB
> client could be implemented in any language, since there's no coupling between
> the two layers.

No, yes, kind of.

The proposal is to identify a set of GDB operations and publish them
using a, C based, function-call interface. An interpreter would be
expected to implement bindings to that interface.

Initially, it is expected that some of those C-functions will be mapped
directly onto existing interpreter commands  (gdb_lib_breakpoint_delete
(int n) -> ``"delete %d", bp'').  Then, as GDB's internals are modified
more direct implementations will be possible.

As part of the interface, the idea is to re-define the way GDB creates
its output.  Where previously breakpoint.c:breakpoint_1() used a
sequence of printf's to output a line of breakpoint information:

      printf_filtered ("%-3d ", b->number);
      printf_filtered ("%-14s ", bptypes[(int) b->type].description);
      printf_filtered ("%-4s ", bpdisps[(int) b->disposition]);
      printf_filtered ("%-3c ", bpenables[(int) b->enable]);

it would instead use a sequence like:

      ui_out_field_int (uiout, "number", b->number);
      ui_out_field_string (uiout, "type", bptypes[(int)
b->type].description);
      ui_out_field_string (uiout, "disp", bpdisps[(int)
b->disposition]);
      ui_out_field_fmt (uiout, "enabled", "%c", bpenables[(int)
b->enable]);

to construct the breakpoint result (the next step in the discussion is
hopefully that interface).

As part of the eixsting CLI there would be ui_out* functions that sent
all output straight through to the console (well GDB_STDOUT). Other
clients would implement their own ui_out and construct a breakpoint
description in their own special way

Importantly, the same code would be used when producing output for the
CLI and for some other client.  This means that, at all stages, the code
being changed would continue to be exercised by the existing testsuite.

The alternative would be to provide a new and separate interface into
GDB's internals. Looking at what has happened so far, people (ddd
especially) has been remarkably content with just GDB's CLI.  (Ignoring
the perenial of the output just changed).

I do expect people to gradually implement new modules, not accessible
from the CLI, that really do grub around in GDB's internals.  By
sticking to the interface being developed here, that could would
hopefully be available for all.


> Here are some of my observations of what's going on so far.
> 
> From the the work that Jim Ingham, Tom Tromey, Keith Seitz, Martin Hunt and
> others did inside Cygnus on the gdbtk interface, from my previous experience
> with a Perl prototype and the current Python integration work we're doing here
> and from the work that Martin Baulig is doing on the Guile interface, it looks
> like we need a more tightly coupled interface with GDB. It seems that what we
> really need is the ability to have access to the internal GDB structures and
> functions directly and not through an additional layer, which adds a certain
> amount of burden in how you deal with GDB internals.

How close is close?  I'm aiming at an interface that is efficient and
reliable (hence C-function call) without exposing the nitty gritty
internal GDB details.  Hopefully that gives the interpreter the
performance it needs without commiting GDB to supporting specific
internal details at infinitum :-)

> It also looks like there is a lot of code duplication in all these glue layers.
> Things like getting the backtrace, finding the function name given a pc and
> lots more are copied from various places in GDB in all these clients. This is
> not a good thing since it doesn't promote code reuse. In addition, fixing a bug
> somewhere requires fixes in the other places that copied the code.

Yes. Rationalizing the code is a wishlist item.

Going back to the breakpoint example.  GDB currently contains several
independant blocks of code that it uses to display breakpoint
information: info-breakpoint; set-breakpoint; target-stopped/WFI and
even ``file'' display breakpoint information. There should only be one
mechanism and anything else wanting to display breakpoint information
should use that.

A client of libGDB would only have access to the direct call ``info
breakpoint''.  A person reviewing the breakpoint code would only
consider modifying ``info breakpoint''.  Any other operations (such as
set-breakpoint) would not return any information (other than possibly an
event advising that breakpoint state was changed).

> This happens because GDB's code does not make a clear distinction between the
> parts that do actual computation and the ones that print out the results. I
> think we should try to separate the two parts and have computation functions
> and associated printing functions. Computation functions should just create
> structures or set-up global values that are used later on by the printing
> functions. These would just walk on existing structures and print out their
> content.

Yes.  I suspect you're actually describing what we're trying to do :-) 
Sounds like I botched my description.

> With this approach it's a lot easier to glue on top of GDB clients like gdbtk,
> Guile, Python or whatever else, because all we have to do then is just export
> the functions that we need using SWIG and they automagically appear as native
> functions in the interpreted languages that SWIG supports (Tcl, Guile, Python,
> Perl and even Java).

(SWIG, just love that acronym :-)

> The next thing after this is to figure out a way to have all these languages
> share code and data between them. Imagine that there is a piece of code which
> you need in Guile, but you don't want to rewrite it in Python in order to be
> able to use it. Having the ability to call Guile code from Python and passing
> back and forth data in and from your favorite language would be very nice. The
> idea is to have people scripting GDB in Perl, Guile, Tcl or Python, all at
> once, from the same binary. This would be the true freedom of the user ;-)! But
> this is a completely different story...

:-)

> Does the approach of separating the functionality inside GDB sound reasonable?
> I know that there's a lot more work than what Andrew proposed but I think this
> will help us a lot in the long run.

As a holy grail we have a separate CLI that uses the same interface as
all the other components :-)

As I hinted above, when formumulating an overall plan we considered
creating an entirely new interface (rather than evolving the old one). 
It was felt that by putting the emphasis on evolving the existing code
it would be possible to both leverage (as a verb? :-) the existing
testsuite and consolidate the existing code base.  Creating a new
separate independant interface would have ment the duplication
significant amounts of GDB.

	enjoy,
		Andrew

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