Re: GDB/MI revisited

Andrew Cagney
2003-02-26T16:21:16Z

> Andrew Cagney writes:
>
> > Can you post a transcript of a typical EMACS <-> GDB session?
>
> It would depend on the user, of course, but typically GDB commands would be
> passed to gdb by two means: explicitly through the GUD buffer or through a
> lisp function. The latter could be invoked through the minibuffer, a key sequence
> or through the toolbar.
>
> I'm exploring two approaches:
>
> 1) Running gdb normally and accessing GDB/MI using "interpreter mi mi-command".

I would recommend this aproach.

Provides a path to a more incremental migration aproach. MI can be
exploited where it provides the greatest benefit.

It also avoids an immediate rewrite of things like the conosle and
target I/O code.

> 2) Running gdb with GDB/MI (-interp=mi) and accessing CLI using
> "-interpreter-exec console cli-command".

I'd recommend this aproach in new development.

> In both cases, the source file display is only updated if commands
> are issued through a lisp function. This is because in the first case the lisp
> function is bound to an mi command indirectly e.g
>
> (gud-def gud-run "interpreter mi -exec-run" nil "Run the program.")
>
> and in the second case it is bound to one directly e.g
>
> (gud-def gud-run "-exec-run" nil "Run the program.")

You could even continue to use "run".

> and these output the out of bound record `*stopped' which emacs can parse for
> the program location.

To clarify one point.

GDB's biggest concern here isn't with run, et.al. Rather it is with
the IDEs relying on specific CLI output. For instance, to obtain the
information needed to display a breakpoint, a non MI IDE would issue a
command such as:

> (top-gdb) info break
> Num Type Disp Enb Address What
> 1 breakpoint keep y 0x018abe1c in internal_error at /home/scratch/GDB/sr
> c/gdb/utils.c:800
> 2 breakpoint keep y 0x0180a04c in info_command at /home/scratch/GDB/src/
> gdb/cli/cli-cmds.c:202
> silent
> return

or even:

> info break
>
> yypost-prompt
>
> yybreakpoints-headers
>
> yyfield 0
> Num
> yyfield 1
> Type
> yyfield 2
> Disp
> yyfield 3
> Enb
> yyfield 4
> Address
> yyfield 5
> What
>
> yybreakpoints-table
>
> yyrecord
>
> yyfield 0
> 1
> yyfield 1
> breakpoint
>
> yypre-prompt-for-continue
> ---Type <return> to continue, or q <return> to quit---
> yyprompt-for-continue

(I think its funny here that it came back with the prompt - how does an
IDE live with this? :-)
And then use custom pattern matching to extract the needed information.

If GDB finds it necessary to modify the breakpoint output (add an extra
field, ...) it will likely break the GUIs that are dependant on it.
This is bad since it inhibits GDB's ability to evolve it's user
interface(1).

On the other hand, if an MI command is used vis:

> (top-gdb) interpreter-exec mi -break-list
> ^done,BreakpointTable={nr_rows="2",nr_cols="6",hdr=[{width="3",alignment="-1",col_name="number",colhdr="Num"},{width="14",alignment="-1",col_name="type",colhdr="Type"},{width="4",alignment="-1",col_name="disp",colhdr="Disp"},{width="3",alignment="-1",col_name="enabled",colhdr="Enb"},{width="10",alignment="-1",col_name="addr",colhdr="Address"},{width="40",alignment="2",col_name="what",colhdr="What"}],body=[bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x018abe1c",func="internal_error",file="/home/scratch/GDB/src/gdb/utils.c",line="800",times="0"},bkpt={number="2",type="breakpoint",disp="keep",enabled="y",addr="0x0180a04c",func="info_command",file="/home/scratch/GDB/src/gdb/cli/cli-cmds.c",line="202",times="0",script={"silent","return"}}]}
> (gdb)
> (top-gdb)

While unreadable to the naked eye it is easily parsable by software.
Further, since the gdb.mi/* testsuite is testing this behavior the
likelyhood of unintentional breakage is lessened (of course the MI
interface will evolve, but the evolution can be managed).

> Conversely, in both cases, GDB commands entered through the GUD buffer do not
> currently generate `*stopped' and source display is not updated.
>
> QUESTION: Is it possible to modify GDB so that it does generate `*stopped' in
> these cases?
>
> The first case would require that a cli command generates out of bound
> records. This would require a change in behaviour in gdb so need its own flag
> e.g gdb -emacs
>
> The second case would require that "-interpreter-exec console cli-command"
> generates out of bound records. This could be its defined behaviour as it
> probably would be appropriate to others.

You mean something like:

-interpreter-exec console break foo
~Breakpoint 1 created.
=breakpoint-create,breakpoint={nr=5,location=foo,file=bar.c,line=47}

That is the second change sitting on the interpreters branch. I don't
think it is immediatly necessary though as the imediate objective is to
just address the problem of level two annotations littered through out
things like the breakpoint code.

Andrew

(1) It is unfortunate that while some people are very quick to complain
about various aspects of GDB's CLI, they are very slow when it comes to
contributing to the hard and dirty work of breaking dependencies such as
this that hinder both GDB's and the IDE's long term development.