diff options
author | Hui Zhu <teawater@gmail.com> | 2013-05-21 04:18:55 +0000 |
---|---|---|
committer | Hui Zhu <teawater@gmail.com> | 2013-05-21 04:18:55 +0000 |
commit | c5867ab65ce98cb27943606d66eee564c60a7d23 (patch) | |
tree | 8e623a837ebd3598708ba25a955740c304fb65a9 /gdb/mi | |
parent | 624852650acae72e34a0204d4e3e0a6c809b1625 (diff) | |
download | binutils-c5867ab65ce98cb27943606d66eee564c60a7d23.zip binutils-c5867ab65ce98cb27943606d66eee564c60a7d23.tar.gz binutils-c5867ab65ce98cb27943606d66eee564c60a7d23.tar.bz2 |
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.c | 163 | ||||
-rw-r--r-- | gdb/mi/mi-cmds.c | 2 | ||||
-rw-r--r-- | gdb/mi/mi-cmds.h | 1 |
3 files changed, 144 insertions, 22 deletions
diff --git a/gdb/mi/mi-cmd-break.c b/gdb/mi/mi-cmd-break.c index ebc1e6a..050cf3f 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 c9efa81..124a9dd 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 4b9fb7a..8199d15 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; |