This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [PATCH] -data-list-changed-registers (Take 2)
[Including Changelog and no duplication this time]
> Actually this isn't quite right:
>
> (gdb)
> -break-insert main
> ^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x080484d9",func="main",file="myprog.c",line="55",times="0"}
> (gdb)
> -data-list-changed-registers
> &"No registers.\n"
> ^error,msg="No registers."
> (gdb)
> -exec-run
> ^running
> (gdb)
> *stopped,changed-registers=[],reason="breakpoint-hit",bkptno="1",thread-id="0",frame={addr="0x080484d9",func="main",args=[{name="argc",value="1"},{name="argv",value="0xbffff794"}],file="myprog.c",fullname="/home/nick/myprog.c",line="55"}
> (gdb)
> -data-list-changed-registers
> ^done,changed-registers=["1","3","4","5","6","7","8","9","10","11","12","13","24","26","40","41"]
> (gdb)
>
>
> I think the changed-registers=[] after *stopped occurs because an exception
> is raised in register_changed_p in the _first_ call to
> mi_cmd_data_list_changed_registers and control doesn't return to to call
> do_cleanups (cleanup).
Well it turms out that throw_exception calls do_cleanups, but clearly the
above output isn't acceptable. With CLI everything is output immediately.
With MI it's stored in memory to be output later. This can mixed with the
output of the next MI command and break the syntax, as above.
This patch addresses this problem and is not as lightweight as my earlier
patches. If its not the right fix then its pretty damn close.
Nick
2005-06-11 Nick Roberts <nickrob@snap.net.nz>
* ui-file.h: Add extern declarations.
* ui-file.c (mem_init_stream_buffer, mem_free_stream_contents):
New functions.
* mi/mi-main.c (mi_cmd_data_list_changed_registers)
(mi_cmd_data_list_register_values): Cleanup pending MI output
when there is an exception.
(register_changed_p, get_register): Use get_selected_frame.
*** /home/nick/src/gdb/ui-file.h.~1.4.~ 2003-06-11 02:37:04.000000000 +1200
--- /home/nick/src/gdb/ui-file.h 2005-06-11 14:16:15.000000000 +1200
***************
*** 83,88 ****
--- 83,93 ----
extern long ui_file_read (struct ui_file *file, char *buf, long length_buf);
+ struct mem_file;
+ extern void mem_init_stream_buffer (struct mem_file *stream);
+
+ extern void mem_free_stream_contents (void *ptr);
+
/* Create/open a memory based file. Can be used as a scratch buffer
for collecting output. */
extern struct ui_file *mem_fileopen (void);
*** /home/nick/src/gdb/ui-file.c.~1.11.~ 2005-02-13 00:36:15.000000000 +1300
--- /home/nick/src/gdb/ui-file.c 2005-06-11 14:36:23.000000000 +1200
***************
*** 403,408 ****
--- 403,432 ----
stream->length_buffer = new_length;
}
}
+
+ void
+ mem_init_stream_buffer (struct mem_file *stream)
+ {
+ stream->sizeof_buffer = 0;
+ stream->length_buffer = 0;
+ stream->buffer = xmalloc (stream->sizeof_buffer);
+ }
+
+ void
+ mem_free_stream_contents (void *ptr)
+ {
+ struct mem_file **stream_ptr = ptr;
+ if (stream_ptr == NULL)
+ internal_error (__FILE__, __LINE__,
+ _("free_stream_contents: NULL pointer"));
+ if (*stream_ptr != NULL)
+ {
+ (*stream_ptr)->sizeof_buffer = 0;
+ (*stream_ptr)->length_buffer = 0;
+ (*stream_ptr)->buffer = xrealloc ((*stream_ptr)->buffer, 0);
+ }
+ }
+
/* ``struct ui_file'' implementation that maps directly onto
<stdio.h>'s FILE. */
*** /home/nick/src/gdb/mi/mi-main.c.~1.78.~ 2005-05-27 12:27:29.000000000 +1200
--- /home/nick/src/gdb/mi/mi-main.c 2005-06-11 17:25:03.000000000 +1200
***************
*** 319,325 ****
{
int regnum, numregs, changed;
int i;
! struct cleanup *cleanup;
/* Note that the test for a valid register must include checking the
REGISTER_NAME because NUM_REGS may be allocated for the union of
--- 319,327 ----
{
int regnum, numregs, changed;
int i;
! struct cleanup *stream_cleanup, *cleanup;
! mi_out_data *data = ui_out_data (uiout);
! struct mem_file *stream = ui_file_data (data->buffer);
/* Note that the test for a valid register must include checking the
REGISTER_NAME because NUM_REGS may be allocated for the union of
***************
*** 329,334 ****
--- 331,338 ----
numregs = NUM_REGS + NUM_PSEUDO_REGS;
+ mem_init_stream_buffer (stream);
+ stream_cleanup = make_cleanup (mem_free_stream_contents, &stream);
cleanup = make_cleanup_ui_out_list_begin_end (uiout, "changed-registers");
if (argc == 0) /* No args, just do all the regs */
***************
*** 380,385 ****
--- 384,390 ----
}
}
do_cleanups (cleanup);
+ discard_cleanups (stream_cleanup);
return MI_CMD_DONE;
}
***************
*** 388,394 ****
{
gdb_byte raw_buffer[MAX_REGISTER_SIZE];
! if (! frame_register_read (deprecated_selected_frame, regnum, raw_buffer))
return -1;
if (memcmp (&old_regs[DEPRECATED_REGISTER_BYTE (regnum)], raw_buffer,
--- 393,399 ----
{
gdb_byte raw_buffer[MAX_REGISTER_SIZE];
! if (! frame_register_read (get_selected_frame (NULL), regnum, raw_buffer))
return -1;
if (memcmp (&old_regs[DEPRECATED_REGISTER_BYTE (regnum)], raw_buffer,
***************
*** 415,422 ****
{
int regnum, numregs, format, result;
int i;
! struct cleanup *list_cleanup, *tuple_cleanup;
!
/* Note that the test for a valid register must include checking the
REGISTER_NAME because NUM_REGS may be allocated for the union of
the register sets within a family of related processors. In this
--- 420,429 ----
{
int regnum, numregs, format, result;
int i;
! struct cleanup *stream_cleanup, *list_cleanup, *tuple_cleanup;
! mi_out_data *data = ui_out_data (uiout);
! struct mem_file *stream = ui_file_data (data->buffer);
!
/* Note that the test for a valid register must include checking the
REGISTER_NAME because NUM_REGS may be allocated for the union of
the register sets within a family of related processors. In this
***************
*** 433,444 ****
format = (int) argv[0][0];
! if (!target_has_registers)
! {
! mi_error_message = xstrprintf ("mi_cmd_data_list_register_values: No registers.");
! return MI_CMD_ERROR;
! }
!
list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-values");
if (argc == 1) /* No args, beside the format: do all the regs */
--- 440,447 ----
format = (int) argv[0][0];
! mem_init_stream_buffer (stream);
! stream_cleanup = make_cleanup (mem_free_stream_contents, &stream);
list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-values");
if (argc == 1) /* No args, beside the format: do all the regs */
***************
*** 490,495 ****
--- 493,499 ----
}
}
do_cleanups (list_cleanup);
+ discard_cleanups (stream_cleanup);
return MI_CMD_DONE;
}
***************
*** 509,515 ****
if (format == 'N')
format = 0;
! frame_register (deprecated_selected_frame, regnum, &optim, &lval, &addr,
&realnum, buffer);
if (optim)
--- 513,519 ----
if (format == 'N')
format = 0;
! frame_register (get_selected_frame (NULL), regnum, &optim, &lval, &addr,
&realnum, buffer);
if (optim)