RFC: MI output during program execution

Nick Roberts
2005-08-08T05:20:17Z

Although Emacs will increasingly use GDB/MI to interact with GDB, the GUD
buffer will always require the use of CLI commands. These are executed via
"-interpreter-exec console" that Jim Ingham/Apple contributed. In general
this isn't a problem, but CLI commands which start the inferior e.g run, next,
finish etc do not tell Emacs when the inferior is executing (do not output
^running) and in some cases generate inappropriate output such as the current
source line as CLI output. I would like to change the output of these
commands to that of their MI counterparts. I think that Apple have added a
separate interpreter (console-quoted) for this kind of thing. The patch below
reflects my more modest resources and limited knowledge and seems to do the
kind of thing that Emacs needs. It doesn't change direct use of MI commands,
just the behaviour of a subset of CLI commands invoked the the MI interpreter:

-exec-next
^running
(gdb)
*stopped,reason="end-stepping-range",thread-id="0",frame={addr="0x080484ef",func="main",args=[{name="argc",value="1"},{name="argv",value="0xbffff794"}],file="myprog.c",fullname="/home/nick/myprog.c",line="46"}
(gdb)

-interpreter-exec console next
^running
(gdb)
*stopped,reason="end-stepping-range",thread-id="0",frame={addr="0x0804851f",func="main",args=[{name="argc",value="1"},{name="argv",value="0xbffff794"}],file="myprog.c",fullname="/home/nick/myprog.c",line="47"}
^done
(gdb)

Note that the latter generates an extra ^done as the MI command
-interpreter-exec completes. I'm not asking for approval at this stage, but
any feedback would be most welcome.

Nick

*** mi/mi-interp.c.~1.15.~ 2005-08-01 10:45:28.000000000 +1200
--- mi/mi-interp.c 2005-08-08 11:10:08.000000000 +1200
***************
*** 33,38 ****
--- 33,40 ----
#include "mi-out.h"
#include "mi-console.h"

+ #include "cli/cli-decode.h"
+
struct mi_interp
{
/* MI's output channels */
*************** mi_cmd_interpreter_exec (char *command,
*** 239,250 ****
and then set it back to 0 when we are done. */
sync_execution = 1;
{
! struct gdb_exception e = interp_exec (interp_to_use, argv[i]);
! if (e.reason < 0)
{
! mi_error_message = xstrdup (e.message);
! result = MI_CMD_ERROR;
! break;
}
}
xfree (buff);
--- 241,288 ----
and then set it back to 0 when we are done. */
sync_execution = 1;
{
! struct gdb_exception e;
! int flag = 0;
!
! if (strcmp (argv[0], "console") == 0)
! /* Stick with MI for commands which run the inferior. */
! {
! struct cmd_list_element *c;
! extern struct cmd_list_element *cmdlist;
! char *token, *cp;
!
! flag = 1;
! cp = xstrdup (argv[i]);
! c = lookup_cmd (&cp, cmdlist, "", 0, 0);
! if (strcmp (c->name, "run") == 0)
! mi_cmd_exec_run (cp, 0);
! else if (strcmp (c->name, "next") == 0)
! mi_cmd_exec_next (cp, 0);
! else if (strcmp (c->name, "nexti") == 0)
! mi_cmd_exec_next_instruction (cp, 0);
! else if (strcmp (c->name, "step") == 0)
! mi_cmd_exec_step (cp, 0);
! else if (strcmp (c->name, "stepi") == 0)
! mi_cmd_exec_step_instruction (cp, 0);
! else if (strcmp (c->name, "finish") == 0)
! mi_cmd_exec_finish (cp, 0);
! else if (strcmp (c->name, "until") == 0)
! mi_cmd_exec_until (cp, 0);
! else if (strcmp (c->name, "return") == 0)
! mi_cmd_exec_return (cp, 0);
! else
! flag = 0;
! }
!
! if (!flag)
{
! e = interp_exec (interp_to_use, argv[i]);
! if (e.reason < 0)
! {
! mi_error_message = xstrdup (e.message);
! result = MI_CMD_ERROR;
! break;
! }
}
}
xfree (buff);