aboutsummaryrefslogtreecommitdiff
path: root/gdb/mi
diff options
context:
space:
mode:
authorYao Qi <yao@codesourcery.com>2012-10-17 00:53:24 +0000
committerYao Qi <yao@codesourcery.com>2012-10-17 00:53:24 +0000
commit8de0566d7a01e024fa43e7e1bde309c718856695 (patch)
tree15e8946c06a60231b27f2ba37926c8ce64b01dfe /gdb/mi
parentb1fecbf125225e49517549d561fe5f480ee5055f (diff)
downloadgdb-8de0566d7a01e024fa43e7e1bde309c718856695.zip
gdb-8de0566d7a01e024fa43e7e1bde309c718856695.tar.gz
gdb-8de0566d7a01e024fa43e7e1bde309c718856695.tar.bz2
gdb:
* breakpoint.c (invalidate_bp_value_on_memory_change): Add one more parameter 'inferior'. * corefile.c (write_memory_with_notification): Caller update. * mi/mi-cmd-var.c: Include "mi-main.h". (mi_cmd_var_assign): Set mi_suppress_notification.data_write_memory to 1 and restore it later. * mi/mi-cmds.c (mi_cmd mi_cmds): Update for "data-write-memory" and "data-write-memory-bytes. * mi/mi-interp.c: Include objfiles.h. (mi_interpreter_init): Call observer_attach_memory_changed. (mi_memory_changed): New. * mi/mi-main.h (struct mi_suppress_notification) <memory>: New field. * NEWS: Mention new MI notification "memory-changed". gdb/doc: * observer.texi (GDB Observers): Update observer 'memory_changed'. * gdb.texinfo (GDB/MI Async Records): Document for "memory-changed" notification. gdb/testsuite: * gdb.mi/mi-memory-changed.exp: New.
Diffstat (limited to 'gdb/mi')
-rw-r--r--gdb/mi/mi-cmd-var.c10
-rw-r--r--gdb/mi/mi-cmds.c6
-rw-r--r--gdb/mi/mi-interp.c45
-rw-r--r--gdb/mi/mi-main.h2
4 files changed, 61 insertions, 2 deletions
diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
index 5d7081f..dc47bc1 100644
--- a/gdb/mi/mi-cmd-var.c
+++ b/gdb/mi/mi-cmd-var.c
@@ -21,6 +21,7 @@
#include "defs.h"
#include "mi-cmds.h"
+#include "mi-main.h"
#include "ui-out.h"
#include "mi-out.h"
#include "varobj.h"
@@ -616,6 +617,7 @@ mi_cmd_var_assign (char *command, char **argv, int argc)
struct ui_out *uiout = current_uiout;
struct varobj *var;
char *expression, *val;
+ struct cleanup *cleanup;
if (argc != 2)
error (_("-var-assign: Usage: NAME EXPRESSION."));
@@ -628,6 +630,12 @@ mi_cmd_var_assign (char *command, char **argv, int argc)
expression = xstrdup (argv[1]);
+ /* MI command '-var-assign' may write memory, so suppress memory
+ changed notification if it does. */
+ cleanup
+ = make_cleanup_restore_integer (&mi_suppress_notification.memory);
+ mi_suppress_notification.memory = 1;
+
if (!varobj_set_value (var, expression))
error (_("-var-assign: Could not assign "
"expression to variable object"));
@@ -635,6 +643,8 @@ mi_cmd_var_assign (char *command, char **argv, int argc)
val = varobj_get_value (var);
ui_out_field_string (uiout, "value", val);
xfree (val);
+
+ do_cleanups (cleanup);
}
/* Type used for parameters passing to mi_cmd_var_update_iter. */
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index 2ed1905..572625f 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -75,8 +75,10 @@ static struct mi_cmd mi_cmds[] =
DEF_MI_CMD_MI ("data-list-register-values", mi_cmd_data_list_register_values),
DEF_MI_CMD_MI ("data-read-memory", mi_cmd_data_read_memory),
DEF_MI_CMD_MI ("data-read-memory-bytes", mi_cmd_data_read_memory_bytes),
- DEF_MI_CMD_MI ("data-write-memory", mi_cmd_data_write_memory),
- DEF_MI_CMD_MI ("data-write-memory-bytes", mi_cmd_data_write_memory_bytes),
+ DEF_MI_CMD_MI_1 ("data-write-memory", mi_cmd_data_write_memory,
+ &mi_suppress_notification.memory),
+ DEF_MI_CMD_MI_1 ("data-write-memory-bytes", mi_cmd_data_write_memory_bytes,
+ &mi_suppress_notification.memory),
DEF_MI_CMD_MI ("data-write-register-values",
mi_cmd_data_write_register_values),
DEF_MI_CMD_MI ("enable-timings", mi_cmd_enable_timings),
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index d383958..d3c3d81 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -35,6 +35,7 @@
#include "gdbthread.h"
#include "solist.h"
#include "gdb.h"
+#include "objfiles.h"
/* These are the interpreter setup, etc. functions for the MI
interpreter. */
@@ -76,6 +77,8 @@ static void mi_breakpoint_created (struct breakpoint *b);
static void mi_breakpoint_deleted (struct breakpoint *b);
static void mi_breakpoint_modified (struct breakpoint *b);
static void mi_command_param_changed (const char *param, const char *value);
+static void mi_memory_changed (struct inferior *inf, CORE_ADDR memaddr,
+ ssize_t len, const bfd_byte *myaddr);
static int report_initial_inferior (struct inferior *inf, void *closure);
@@ -138,6 +141,7 @@ mi_interpreter_init (struct interp *interp, int top_level)
observer_attach_breakpoint_deleted (mi_breakpoint_deleted);
observer_attach_breakpoint_modified (mi_breakpoint_modified);
observer_attach_command_param_changed (mi_command_param_changed);
+ observer_attach_memory_changed (mi_memory_changed);
/* The initial inferior is created before this function is
called, so we need to report it explicitly. Use iteration in
@@ -840,6 +844,47 @@ mi_command_param_changed (const char *param, const char *value)
gdb_flush (mi->event_channel);
}
+/* Emit notification about the target memory change. */
+
+static void
+mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
+ ssize_t len, const bfd_byte *myaddr)
+{
+ struct mi_interp *mi = top_level_interpreter_data ();
+ struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
+ struct obj_section *sec;
+
+ if (mi_suppress_notification.memory)
+ return;
+
+ target_terminal_ours ();
+
+ fprintf_unfiltered (mi->event_channel,
+ "memory-changed");
+
+ ui_out_redirect (mi_uiout, mi->event_channel);
+
+ ui_out_field_fmt (mi_uiout, "thread-group", "i%d", inferior->num);
+ ui_out_field_core_addr (mi_uiout, "addr", target_gdbarch, memaddr);
+ ui_out_field_fmt (mi_uiout, "len", "0x%zx", len);
+
+ /* Append 'type=code' into notification if MEMADDR falls in the range of
+ sections contain code. */
+ sec = find_pc_section (memaddr);
+ if (sec != NULL && sec->objfile != NULL)
+ {
+ flagword flags = bfd_get_section_flags (sec->objfile->obfd,
+ sec->the_bfd_section);
+
+ if (flags & SEC_CODE)
+ ui_out_field_string (mi_uiout, "type", "code");
+ }
+
+ ui_out_redirect (mi_uiout, NULL);
+
+ gdb_flush (mi->event_channel);
+}
+
static int
report_initial_inferior (struct inferior *inf, void *closure)
{
diff --git a/gdb/mi/mi-main.h b/gdb/mi/mi-main.h
index aad7eeb..a815fbe 100644
--- a/gdb/mi/mi-main.h
+++ b/gdb/mi/mi-main.h
@@ -41,6 +41,8 @@ struct mi_suppress_notification
int cmd_param_changed;
/* Traceframe changed notification suppressed? */
int traceframe;
+ /* Memory changed notification suppressed? */
+ int memory;
};
extern struct mi_suppress_notification mi_suppress_notification;