summaryrefslogtreecommitdiff
path: root/gdb/mi
diff options
context:
space:
mode:
authorHui Zhu <teawater@gmail.com>2013-05-21 04:18:54 +0000
committerHui Zhu <teawater@gmail.com>2013-05-21 04:18:54 +0000
commit2f2a2015c740d447fee472e08471aa28d416b551 (patch)
treec8cc2e36f348f4993a7a80803f569fa128c6aa27 /gdb/mi
parentc91374499747d84609217f6815ffa6e637dedba3 (diff)
downloadgdb-2f2a2015c740d447fee472e08471aa28d416b551.tar.gz
2013-05-21 Hui Zhu <hui@codesourcery.com>
* breakpoint.c (dprintf_breakpoint_ops): Remove its static. * breakpoint.h (dprintf_breakpoint_ops): Add extern. * mi/mi-cmd-break.c (ctype.h): New include. (gdb_obstack.h): New include. (mi_argv_to_format, mi_cmd_break_insert_1): New. (mi_cmd_break_insert): Call mi_cmd_break_insert_1. (mi_cmd_dprintf_insert): New. * mi/mi-cmds.c (mi_cmds): Add "dprintf-insert". * mi/mi-cmds.h (mi_cmd_dprintf_insert): New extern. 2013-05-21 Hui Zhu <hui@codesourcery.com> * gdb.texinfo (GDB/MI Breakpoint Commands): Describe the "-dprintf-insert" command. 2013-05-21 Hui Zhu <hui@codesourcery.com> * gdb.mi/Makefile.in (PROGS): Add "mi-dprintf". * gdb.mi/mi-dprintf.exp, gdb.mi/mi-dprintf.c: New.
Diffstat (limited to 'gdb/mi')
-rw-r--r--gdb/mi/mi-cmd-break.c163
-rw-r--r--gdb/mi/mi-cmds.c2
-rw-r--r--gdb/mi/mi-cmds.h1
3 files changed, 144 insertions, 22 deletions
diff --git a/gdb/mi/mi-cmd-break.c b/gdb/mi/mi-cmd-break.c
index ebc1e6a61e3..050cf3f3c02 100644
--- a/gdb/mi/mi-cmd-break.c
+++ b/gdb/mi/mi-cmd-break.c
@@ -30,6 +30,8 @@
#include "observer.h"
#include "mi-main.h"
#include "mi-cmd-break.h"
+#include "gdb_obstack.h"
+#include <ctype.h>
enum
{
@@ -84,11 +86,83 @@ setup_breakpoint_reporting (void)
}
-/* Implements the -break-insert command.
- See the MI manual for the list of possible options. */
+/* Convert arguments in ARGV to the string in "format",argv,argv...
+ and return it. */
-void
-mi_cmd_break_insert (char *command, char **argv, int argc)
+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;
+ default:
+ if (isprint (argv[0][i]))
+ obstack_grow (&obstack, argv[0] + i, 1);
+ else
+ {
+ char tmp[5];
+
+ sprintf (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;
@@ -99,9 +173,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
{
@@ -163,35 +238,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;
+
+ 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
+ {
+ if (oind < argc - 1)
+ error (_("-break-insert: Garbage following <location>"));
+ }
/* Now we have what we need, let's insert the breakpoint! */
- back_to = 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));
- ops = tracepoint ? &tracepoint_breakpoint_ops : &bkpt_breakpoint_ops;
+ setup_breakpoint_reporting ();
+
+ 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,
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
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index c9efa815af0..124a9dd8249 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -61,6 +61,8 @@ static struct mi_cmd mi_cmds[] =
DEF_MI_CMD_CLI ("break-info", "info break", 1),
DEF_MI_CMD_MI_1 ("break-insert", mi_cmd_break_insert,
&mi_suppress_notification.breakpoint),
+ DEF_MI_CMD_MI_1 ("dprintf-insert", mi_cmd_dprintf_insert,
+ &mi_suppress_notification.breakpoint),
DEF_MI_CMD_CLI ("break-list", "info break", 0),
DEF_MI_CMD_MI_1 ("break-passcount", mi_cmd_break_passcount,
&mi_suppress_notification.breakpoint),
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index 4b9fb7ade6c..8199d15ad2c 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -39,6 +39,7 @@ typedef void (mi_cmd_argv_ftype) (char *command, char **argv, int argc);
extern mi_cmd_argv_ftype mi_cmd_ada_task_info;
extern mi_cmd_argv_ftype mi_cmd_add_inferior;
extern mi_cmd_argv_ftype mi_cmd_break_insert;
+extern mi_cmd_argv_ftype mi_cmd_dprintf_insert;
extern mi_cmd_argv_ftype mi_cmd_break_commands;
extern mi_cmd_argv_ftype mi_cmd_break_passcount;
extern mi_cmd_argv_ftype mi_cmd_break_watch;