Index: gdb/mi/mi-cmd-break.c |
diff --git a/gdb/mi/mi-cmd-break.c b/gdb/mi/mi-cmd-break.c |
index 5a64bf1d5559854c7383944770aa6ed59ec1349b..07902bbecb16a908035e844aa9fb3b56f83b69fd 100644 |
--- a/gdb/mi/mi-cmd-break.c |
+++ b/gdb/mi/mi-cmd-break.c |
@@ -1,5 +1,5 @@ |
/* MI Command Set - breakpoint and watchpoint commands. |
- Copyright (C) 2000-2002, 2007-2012 Free Software Foundation, Inc. |
+ Copyright (C) 2000-2013 Free Software Foundation, Inc. |
Contributed by Cygnus Solutions (a Red Hat company). |
This file is part of GDB. |
@@ -23,12 +23,15 @@ |
#include "ui-out.h" |
#include "mi-out.h" |
#include "breakpoint.h" |
-#include "gdb_string.h" |
+#include <string.h> |
#include "mi-getopt.h" |
#include "gdb.h" |
#include "exceptions.h" |
#include "observer.h" |
#include "mi-main.h" |
+#include "mi-cmd-break.h" |
+#include "gdb_obstack.h" |
+#include <ctype.h> |
enum |
{ |
@@ -59,11 +62,111 @@ enum bp_type |
REGEXP_BP |
}; |
-/* Implements the -break-insert command. |
- See the MI manual for the list of possible options. */ |
+/* Arrange for all new breakpoints and catchpoints to be reported to |
+ CURRENT_UIOUT until the cleanup returned by this function is run. |
-void |
-mi_cmd_break_insert (char *command, char **argv, int argc) |
+ Note that MI output will be probably invalid if more than one |
+ breakpoint is created inside one MI command. */ |
+ |
+struct cleanup * |
+setup_breakpoint_reporting (void) |
+{ |
+ struct cleanup *rev_flag; |
+ |
+ if (! mi_breakpoint_observers_installed) |
+ { |
+ observer_attach_breakpoint_created (breakpoint_notify); |
+ mi_breakpoint_observers_installed = 1; |
+ } |
+ |
+ rev_flag = make_cleanup_restore_integer (&mi_can_breakpoint_notify); |
+ mi_can_breakpoint_notify = 1; |
+ |
+ return rev_flag; |
+} |
+ |
+ |
+/* Convert arguments in ARGV to the string in "format",argv,argv... |
+ and return it. */ |
+ |
+static char * |
+mi_argv_to_format (char **argv, int argc) |
+{ |
+ int i; |
+ struct obstack obstack; |
+ char *ret; |
+ |
+ obstack_init (&obstack); |
+ |
+ /* Convert ARGV[OIND + 1] to format string and save to FORMAT. */ |
+ obstack_1grow (&obstack, '\"'); |
+ for (i = 0; i < strlen (argv[0]); i++) |
+ { |
+ switch (argv[0][i]) |
+ { |
+ case '\\': |
+ obstack_grow (&obstack, "\\\\", 2); |
+ break; |
+ case '\a': |
+ obstack_grow (&obstack, "\\a", 2); |
+ break; |
+ case '\b': |
+ obstack_grow (&obstack, "\\b", 2); |
+ break; |
+ case '\f': |
+ obstack_grow (&obstack, "\\f", 2); |
+ break; |
+ case '\n': |
+ obstack_grow (&obstack, "\\n", 2); |
+ break; |
+ case '\r': |
+ obstack_grow (&obstack, "\\r", 2); |
+ break; |
+ case '\t': |
+ obstack_grow (&obstack, "\\t", 2); |
+ break; |
+ case '\v': |
+ obstack_grow (&obstack, "\\v", 2); |
+ break; |
+ case '"': |
+ obstack_grow (&obstack, "\\\"", 2); |
+ break; |
+ default: |
+ if (isprint (argv[0][i])) |
+ obstack_grow (&obstack, argv[0] + i, 1); |
+ else |
+ { |
+ char tmp[5]; |
+ |
+ xsnprintf (tmp, sizeof (tmp), "\\%o", |
+ (unsigned char) argv[0][i]); |
+ obstack_grow (&obstack, tmp, strlen (tmp)); |
+ } |
+ break; |
+ } |
+ } |
+ obstack_1grow (&obstack, '\"'); |
+ |
+ /* Apply other argv to FORMAT. */ |
+ for (i = 1; i < argc; i++) |
+ { |
+ obstack_1grow (&obstack, ','); |
+ obstack_grow (&obstack, argv[i], strlen (argv[i])); |
+ } |
+ obstack_1grow (&obstack, '\0'); |
+ |
+ ret = xstrdup (obstack_finish (&obstack)); |
+ obstack_free (&obstack, NULL); |
+ |
+ return ret; |
+} |
+ |
+/* Insert breakpoint. |
+ If dprintf is true, it will insert dprintf. |
+ If not, it will insert other type breakpoint. */ |
+ |
+static void |
+mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc) |
{ |
char *address = NULL; |
int hardware = 0; |
@@ -74,8 +177,10 @@ mi_cmd_break_insert (char *command, char **argv, int argc) |
int pending = 0; |
int enabled = 1; |
int tracepoint = 0; |
- struct cleanup *back_to; |
+ struct cleanup *back_to = make_cleanup (null_cleanup, NULL); |
enum bptype type_wanted; |
+ struct breakpoint_ops *ops; |
+ char *extra_string = NULL; |
enum opt |
{ |
@@ -137,41 +242,79 @@ mi_cmd_break_insert (char *command, char **argv, int argc) |
} |
if (oind >= argc) |
- error (_("-break-insert: Missing <location>")); |
- if (oind < argc - 1) |
- error (_("-break-insert: Garbage following <location>")); |
+ error (_("-%s-insert: Missing <location>"), |
+ dprintf ? "dprintf" : "break"); |
address = argv[oind]; |
+ if (dprintf) |
+ { |
+ int format_num = oind + 1; |
- /* Now we have what we need, let's insert the breakpoint! */ |
- if (! mi_breakpoint_observers_installed) |
+ if (hardware || tracepoint) |
+ error (_("-dprintf-insert: does not support -h or -a")); |
+ if (format_num >= argc) |
+ error (_("-dprintf-insert: Missing <format>")); |
+ |
+ extra_string = mi_argv_to_format (argv + format_num, argc - format_num); |
+ make_cleanup (xfree, extra_string); |
+ } |
+ else |
{ |
- observer_attach_breakpoint_created (breakpoint_notify); |
- mi_breakpoint_observers_installed = 1; |
+ if (oind < argc - 1) |
+ error (_("-break-insert: Garbage following <location>")); |
} |
- back_to = make_cleanup_restore_integer (&mi_can_breakpoint_notify); |
- mi_can_breakpoint_notify = 1; |
+ /* Now we have what we need, let's insert the breakpoint! */ |
+ setup_breakpoint_reporting (); |
- /* Note that to request a fast tracepoint, the client uses the |
- "hardware" flag, although there's nothing of hardware related to |
- fast tracepoints -- one can implement slow tracepoints with |
- hardware breakpoints, but fast tracepoints are always software. |
- "fast" is a misnomer, actually, "jump" would be more appropriate. |
- A simulator or an emulator could conceivably implement fast |
- regular non-jump based tracepoints. */ |
- type_wanted = (tracepoint |
- ? (hardware ? bp_fast_tracepoint : bp_tracepoint) |
- : (hardware ? bp_hardware_breakpoint : bp_breakpoint)); |
+ if (tracepoint) |
+ { |
+ /* Note that to request a fast tracepoint, the client uses the |
+ "hardware" flag, although there's nothing of hardware related to |
+ fast tracepoints -- one can implement slow tracepoints with |
+ hardware breakpoints, but fast tracepoints are always software. |
+ "fast" is a misnomer, actually, "jump" would be more appropriate. |
+ A simulator or an emulator could conceivably implement fast |
+ regular non-jump based tracepoints. */ |
+ type_wanted = hardware ? bp_fast_tracepoint : bp_tracepoint; |
+ ops = &tracepoint_breakpoint_ops; |
+ } |
+ else if (dprintf) |
+ { |
+ type_wanted = bp_dprintf; |
+ ops = &dprintf_breakpoint_ops; |
+ } |
+ else |
+ { |
+ type_wanted = hardware ? bp_hardware_breakpoint : bp_breakpoint; |
+ ops = &bkpt_breakpoint_ops; |
+ } |
create_breakpoint (get_current_arch (), address, condition, thread, |
- NULL, |
+ extra_string, |
0 /* condition and thread are valid. */, |
temp_p, type_wanted, |
ignore_count, |
pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE, |
- &bkpt_breakpoint_ops, 0, enabled, 0, 0); |
+ ops, 0, enabled, 0, 0); |
do_cleanups (back_to); |
+} |
+ |
+/* Implements the -break-insert command. |
+ See the MI manual for the list of possible options. */ |
+void |
+mi_cmd_break_insert (char *command, char **argv, int argc) |
+{ |
+ mi_cmd_break_insert_1 (0, command, argv, argc); |
+} |
+ |
+/* Implements the -dprintf-insert command. |
+ See the MI manual for the list of possible options. */ |
+ |
+void |
+mi_cmd_dprintf_insert (char *command, char **argv, int argc) |
+{ |
+ mi_cmd_break_insert_1 (1, command, argv, argc); |
} |
enum wp_type |
@@ -198,7 +341,7 @@ mi_cmd_break_passcount (char *command, char **argv, int argc) |
if (t) |
{ |
t->pass_count = p; |
- observer_notify_tracepoint_modified (n); |
+ observer_notify_breakpoint_modified (&t->base); |
} |
else |
{ |