This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH:MI] Use observers for breakpoints
- From: Nick Roberts <nickrob at snap dot net dot nz>
- To: gdb-patches at sourceware dot org
- Cc: ghost at cs dot msu dot su
- Date: Sun, 1 Jun 2008 14:46:04 +1200
- Subject: [PATCH:MI] Use observers for breakpoints
Following Aleksandar Ristovski's patch for catchpoints in GDB/MI, here's a
patch to demonstrate the use of observers for breakpoints. This relates to
earlier patches I've submitted which uses event notification to communicate a
change in state rather than using command output directly. Among other things
this allows the use of CLI commands with MI.
It's not a patch for immediate inclusion as it changes existing behaviour.
However I think it's something we should be aiming towards and would be
suitable for inclusion next time the MI level gets bumped.
Here's some sample output:
b main
&"b main\n"
=breakpoints-changed,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x080486d6",func="main",file="myprog.c",fullname="/home/nickrob/myprog.c",line="140",times="0",original-location="main"}
~"Breakpoint 1 at 0x80486d6: file myprog.c, line 140.\n"
^done
(gdb)
dis 1
&"dis 1\n"
=breakpoints-changed,bkpt={number="1",type="breakpoint",disp="keep",enabled="n",addr="0x080486d6",func="main",file="myprog.c",fullname="/home/nickrob/myprog.c",line="140",times="0",original-location="main"}
^done
(gdb)
cond 1 1==1
&"cond 1 1==1\n"
=breakpoints-changed,bkpt={number="1",type="breakpoint",disp="keep",enabled="n",addr="0x080486d6",func="main",file="myprog.c",fullname="/home/nickrob/myprog.c",line="140",cond="1==1",times="0",original-location="main"}
^done
(gdb)
-break-insert main
=breakpoints-changed,bkpt={number="2",type="breakpoint",disp="keep",enabled="y",addr="0x080486d6",func="main",file="myprog.c",fullname="/home/nickrob/myprog.c",line="140",times="0",original-location="main"}
^done
(gdb)
watch i22
&"watch i22\n"
=breakpoints-changed,bkpt={number="3",type="watchpoint",disp="keep",enabled="y",addr="",what="i22",times="0",original-location="i22"}
~"Watchpoint 3: i22\n"
^done
(gdb)
-break-watch i22
=breakpoints-changed,bkpt={number="4",type="watchpoint",disp="keep",enabled="y",addr="",what="i22",times="0",original-location="i22"}
^done,wpt={number="4",exp="i22"}
(gdb)
ignore 1 4
&"ignore 1 4\n"
=breakpoints-changed,bkpt={number="1",type="breakpoint",disp="keep",enabled="n",addr="0x080486d6",func="main",file="myprog.c",fullname="/home/nickrob/myprog.c",line="140",cond="1==1",times="0",ignore="4",original-location="main"}
~"Will ignore next 4 crossings of breakpoint 1.\n"
^done
(gdb)
--
Nick http://www.inet.net.nz/~nickrob
2008-06-01 Nick Roberts <nickrob@snap.net.nz>
* mi/mi-interp.c (mi_breakpoints_changed): New function.
(mi_interpreter_init): Register mi_breakpoints_changed as
breakpoints_changed observer.
* mi/mi-cmd-break.c (breakpoint_notify, breakpoint_hooks): Delete.
(mi_cmd_break_insert): Don't use deprecated_set_gdb_event_hooks.
* breakpoint.c (condition_command, commands_command)
(commands_from_control_command, mention, delete_breakpoint)
(set_ignore_count, disable_breakpoint, do_enable_breakpoint):
Call observer_notify_breakpoints_changed.
(gdb_breakpoint_query): Rename to...
(breakpoint_query): ...this.
* breakpoint.h: Declare breakpoint_query.
* gdb.h: Delete extern for gdb_breakpoint_query.
2008-06-01 Nick Roberts <nickrob@snap.net.nz>
* observer.texi (GDB Observers): New observer "breakpoints_changed".
Index: breakpoint.c
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.322
diff -p -u -r1.322 breakpoint.c
--- breakpoint.c 28 May 2008 14:04:21 -0000 1.322
+++ breakpoint.c 1 Jun 2008 02:17:21 -0000
@@ -621,6 +621,7 @@ condition_command (char *arg, int from_t
}
}
breakpoints_changed ();
+ observer_notify_breakpoints_changed (b->number);
breakpoint_modify_event (b->number);
return;
}
@@ -660,6 +661,7 @@ commands_command (char *arg, int from_tt
free_command_lines (&b->commands);
b->commands = l;
breakpoints_changed ();
+ observer_notify_breakpoints_changed (b->number);
breakpoint_modify_event (b->number);
return;
}
@@ -706,6 +708,7 @@ commands_from_control_command (char *arg
list after it finishes execution. */
b->commands = copy_command_lines (cmd->body_list[0]);
breakpoints_changed ();
+ observer_notify_breakpoints_changed (b->number);
breakpoint_modify_event (b->number);
return simple_control;
}
@@ -3856,18 +3859,15 @@ do_captured_breakpoint_query (struct ui_
return GDB_RC_NONE;
}
-enum gdb_rc
-gdb_breakpoint_query (struct ui_out *uiout, int bnum, char **error_message)
+void
+breakpoint_query (int bnum)
{
struct captured_breakpoint_query_args args;
args.bnum = bnum;
/* For the moment we don't trust print_one_breakpoint() to not throw
an error. */
- if (catch_exceptions_with_msg (uiout, do_captured_breakpoint_query, &args,
- error_message, RETURN_MASK_ALL) < 0)
- return GDB_RC_FAIL;
- else
- return GDB_RC_OK;
+ catch_exceptions_with_msg (uiout, do_captured_breakpoint_query, &args,
+ NULL, RETURN_MASK_ALL);
}
/* Return non-zero if B is user settable (breakpoints, watchpoints,
@@ -4882,6 +4882,7 @@ mention (struct breakpoint *b)
been done for deprecated_delete_breakpoint_hook and so on. */
if (deprecated_create_breakpoint_hook)
deprecated_create_breakpoint_hook (b);
+ observer_notify_breakpoints_changed (b->number);
breakpoint_create_event (b->number);
if (b->ops != NULL && b->ops->print_mention != NULL)
@@ -7126,6 +7127,7 @@ delete_breakpoint (struct breakpoint *bp
if (deprecated_delete_breakpoint_hook)
deprecated_delete_breakpoint_hook (bpt);
+ observer_notify_breakpoints_changed (b->number);
breakpoint_delete_event (bpt->number);
if (breakpoint_chain == bpt)
@@ -7633,6 +7635,7 @@ set_ignore_count (int bptnum, int count,
count, bptnum);
}
breakpoints_changed ();
+ observer_notify_breakpoints_changed (b->number);
breakpoint_modify_event (b->number);
return;
}
@@ -7783,6 +7786,7 @@ disable_breakpoint (struct breakpoint *b
if (deprecated_modify_breakpoint_hook)
deprecated_modify_breakpoint_hook (bpt);
+ observer_notify_breakpoints_changed (bpt->number);
breakpoint_modify_event (bpt->number);
}
@@ -7908,6 +7912,7 @@ have been allocated for other watchpoint
if (deprecated_modify_breakpoint_hook)
deprecated_modify_breakpoint_hook (bpt);
+ observer_notify_breakpoints_changed (bpt->number);
breakpoint_modify_event (bpt->number);
}
Index: breakpoint.h
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.h,v
retrieving revision 1.72
diff -p -u -r1.72 breakpoint.h
--- breakpoint.h 4 May 2008 19:38:59 -0000 1.72
+++ breakpoint.h 1 Jun 2008 02:17:21 -0000
@@ -865,4 +865,8 @@ void breakpoint_restore_shadows (gdb_byt
extern int breakpoints_always_inserted_mode (void);
+/* Print the specified breakpoint on GDB_STDOUT. (Eventually this
+ function will ``print'' the object on ``output''). */
+void breakpoint_query (int bnum);
+
#endif /* !defined (BREAKPOINT_H) */
Index: gdb.h
===================================================================
RCS file: /cvs/src/src/gdb/gdb.h,v
retrieving revision 1.10
diff -p -u -r1.10 gdb.h
--- gdb.h 1 Feb 2008 16:24:46 -0000 1.10
+++ gdb.h 1 Jun 2008 02:17:21 -0000
@@ -41,12 +41,6 @@ enum gdb_rc {
GDB_RC_OK = 2
};
-
-/* Print the specified breakpoint on GDB_STDOUT. (Eventually this
- function will ``print'' the object on ``output''). */
-enum gdb_rc gdb_breakpoint_query (struct ui_out *uiout, int bnum,
- char **error_message);
-
/* Switch thread and print notification. */
enum gdb_rc gdb_thread_select (struct ui_out *uiout, char *tidstr,
char **error_message);
Index: mi/mi-cmd-break.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmd-break.c,v
retrieving revision 1.19
diff -p -u -r1.19 mi-cmd-break.c
--- mi/mi-cmd-break.c 1 Feb 2008 16:24:46 -0000 1.19
+++ mi/mi-cmd-break.c 1 Jun 2008 02:17:21 -0000
@@ -24,7 +24,6 @@
#include "breakpoint.h"
#include "gdb_string.h"
#include "mi-getopt.h"
-#include "gdb-events.h"
#include "gdb.h"
#include "exceptions.h"
@@ -33,23 +32,6 @@ enum
FROM_TTY = 0
};
-/* Output a single breakpoint. */
-
-static void
-breakpoint_notify (int b)
-{
- gdb_breakpoint_query (uiout, b, NULL);
-}
-
-
-struct gdb_events breakpoint_hooks =
-{
- breakpoint_notify,
- breakpoint_notify,
- breakpoint_notify,
-};
-
-
enum bp_type
{
REG_BP,
@@ -71,7 +53,6 @@ mi_cmd_break_insert (char *command, char
char *condition = NULL;
int pending = 0;
struct gdb_exception e;
- struct gdb_events *old_hooks;
enum opt
{
HARDWARE_OPT, TEMP_OPT /*, REGEXP_OPT */ , CONDITION_OPT,
@@ -131,8 +112,6 @@ mi_cmd_break_insert (char *command, char
error (_("mi_cmd_break_insert: Garbage following <location>"));
address = argv[optind];
- /* Now we have what we need, let's insert the breakpoint! */
- old_hooks = deprecated_set_gdb_event_hooks (&breakpoint_hooks);
/* Make sure we restore hooks even if exception is thrown. */
TRY_CATCH (e, RETURN_MASK_ALL)
{
@@ -164,7 +143,7 @@ mi_cmd_break_insert (char *command, char
_("mi_cmd_break_insert: Bad switch."));
}
}
- deprecated_set_gdb_event_hooks (old_hooks);
+
if (e.reason < 0)
throw_exception (e);
Index: mi/mi-interp.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-interp.c,v
retrieving revision 1.30
diff -p -u -r1.30 mi-interp.c
--- mi/mi-interp.c 3 May 2008 15:10:42 -0000 1.30
+++ mi/mi-interp.c 1 Jun 2008 02:17:22 -0000
@@ -68,6 +68,7 @@ static void mi_remove_notify_hooks (void
static void mi_new_thread (struct thread_info *t);
static void mi_thread_exit (struct thread_info *t);
+static void mi_breakpoints_changed (int bnum);
static void *
mi_interpreter_init (int top_level)
@@ -92,6 +93,7 @@ mi_interpreter_init (int top_level)
{
observer_attach_new_thread (mi_new_thread);
observer_attach_thread_exit (mi_thread_exit);
+ observer_attach_breakpoints_changed (mi_breakpoints_changed);
}
return mi;
@@ -331,6 +333,27 @@ mi_thread_exit (struct thread_info *t)
gdb_flush (mi->event_channel);
}
+static void
+mi_breakpoints_changed (int bnum)
+{
+ struct mi_interp *mi = top_level_interpreter_data ();
+ struct interp *interp_to_use;
+ struct ui_out *old_uiout, *temp_uiout;
+ int version;
+
+ fprintf_unfiltered (mi->event_channel, "breakpoints-changed");
+ interp_to_use = top_level_interpreter ();
+ old_uiout = uiout;
+ temp_uiout = interp_ui_out (interp_to_use);
+ version = mi_version (temp_uiout);
+ temp_uiout = mi_out_new (version);
+ uiout = temp_uiout;
+ breakpoint_query (bnum);
+ mi_out_put (uiout, mi->event_channel);
+ uiout = old_uiout;
+ gdb_flush (mi->event_channel);
+}
+
extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */
void
Index: doc/observer.texi
===================================================================
RCS file: /cvs/src/src/gdb/doc/observer.texi,v
retrieving revision 1.15
diff -p -u -r1.15 observer.texi
--- doc/observer.texi 3 May 2008 15:10:42 -0000 1.15
+++ doc/observer.texi 1 Jun 2008 02:17:22 -0000
@@ -137,3 +137,7 @@ The thread specified by @var{t} has been
The thread specified by @var{t} has exited.
@end deftypefun
+@deftypefun void breakpoints_changed (int @var{bnum})
+The thread specified by @var{t} has exited.
+@end deftypefun
+