[patch][python] Add breakpoint support.
Pedro Alves
pedro@codesourcery.com
Thu Apr 8 23:40:00 GMT 2010
On Friday 09 April 2010 00:25:47, Joel Brobecker wrote:
> > I'd just like to point out that we already have code in the tree (and
> > for a decade) that dumps tracepoints into a file; the file can be
> > sourced as a cli script afterwards. See breakpoint.c:tracepoint_save_command.
> > Since the tracepoint/breakpoints merge, it is trivial to extend that function
> > to dump breakpoints as well.
>
> I almost did implement things that way, and it's certainly better
> than nothing. Maybe I'm letting best be the enemy of good, but there
> are issues with a pure CLI script approach that a user cannot control.
> For instance, what if one of the breakpoints now fails? A CLI script
> would abort early, leaving some of the breakpoints not restored.
> If some of the breakpoints were in DSOs that only get loaded at runtime,
> should they be created as pending? I can't remember what the default
> is when from_tty is not set... I like the python approach because it
> allows us to provide a more configurable approach than a pure CLI script
> would give us.
Yeah... being a fundamental and frequently asked for feature,
that python bit would ideally be a part of gdb itself, meaning,
we should consider where to put/install python commands that gdb
always auto-loads, etc.
in any case, here's a 10 minute (functinal, but incomplete,
catchpoints not dumped completely) patch, FTR.
--
Pedro Alves
---
gdb/breakpoint.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++---------
gdb/breakpoint.h | 4 +
2 files changed, 115 insertions(+), 21 deletions(-)
Index: src/gdb/breakpoint.c
===================================================================
--- src.orig/gdb/breakpoint.c 2010-04-08 23:27:37.000000000 +0100
+++ src/gdb/breakpoint.c 2010-04-09 00:26:01.000000000 +0100
@@ -5838,6 +5838,12 @@ print_mention_catch_fork (struct breakpo
printf_filtered (_("Catchpoint %d (fork)"), b->number);
}
+static void
+print_create_catch_fork (struct breakpoint *b, struct ui_file *fp)
+{
+ fprintf_unfiltered (fp, "catch fork");
+}
+
/* The breakpoint_ops structure to be used in fork catchpoints. */
static struct breakpoint_ops catch_fork_breakpoint_ops =
@@ -5847,7 +5853,8 @@ static struct breakpoint_ops catch_fork_
breakpoint_hit_catch_fork,
print_it_catch_fork,
print_one_catch_fork,
- print_mention_catch_fork
+ print_mention_catch_fork,
+ print_create_catch_fork
};
/* Implement the "insert" breakpoint_ops method for vfork catchpoints. */
@@ -5919,6 +5926,12 @@ print_mention_catch_vfork (struct breakp
printf_filtered (_("Catchpoint %d (vfork)"), b->number);
}
+static void
+print_create_catch_vfork (struct breakpoint *b, struct ui_file *fp)
+{
+ fprintf_unfiltered (fp, "catch vfork");
+}
+
/* The breakpoint_ops structure to be used in vfork catchpoints. */
static struct breakpoint_ops catch_vfork_breakpoint_ops =
@@ -5928,7 +5941,8 @@ static struct breakpoint_ops catch_vfork
breakpoint_hit_catch_vfork,
print_it_catch_vfork,
print_one_catch_vfork,
- print_mention_catch_vfork
+ print_mention_catch_vfork,
+ print_create_catch_vfork
};
/* Implement the "insert" breakpoint_ops method for syscall
@@ -6167,6 +6181,12 @@ print_mention_catch_syscall (struct brea
b->number);
}
+static void
+print_create_catch_syscall (struct breakpoint *b, struct ui_file *fp)
+{
+ fprintf_unfiltered (fp, "catch vfork");
+}
+
/* The breakpoint_ops structure to be used in syscall catchpoints. */
static struct breakpoint_ops catch_syscall_breakpoint_ops =
@@ -6176,7 +6196,8 @@ static struct breakpoint_ops catch_sysca
breakpoint_hit_catch_syscall,
print_it_catch_syscall,
print_one_catch_syscall,
- print_mention_catch_syscall
+ print_mention_catch_syscall,
+ print_create_catch_syscall
};
/* Returns non-zero if 'b' is a syscall catchpoint. */
@@ -10644,30 +10665,43 @@ get_tracepoint_by_number (char **arg, in
return NULL;
}
-/* save-tracepoints command */
+/* The save-breakpoints command. */
+
static void
-tracepoint_save_command (char *args, int from_tty)
+breakpoint_save (char *args, int from_tty,
+ int (*filter) (const struct breakpoint *))
{
- struct breakpoint *tp;
- int any_tp = 0;
- struct command_line *line;
+ struct breakpoint *bp;
+ int any = 0;
char *pathname;
char tmp[40];
struct cleanup *cleanup;
struct ui_file *fp;
+ int extra_trace_bits = 0;
if (args == 0 || *args == 0)
- error (_("Argument required (file name in which to save tracepoints)"));
+ error (_("Argument required (file name in which to save breakpoints)"));
/* See if we have anything to save. */
- ALL_TRACEPOINTS (tp)
+ ALL_BREAKPOINTS (tp)
{
- any_tp = 1;
+ if (tp->number <= 0)
+ continue;
+
+ /* If we have a filter, only list the breakpoints it accepts. */
+ if (filter && !filter (tp))
+ continue;
+
+ if (is_tracepoint (tp))
+ extra_trace_bits = 1;
+
+ any = 1;
break;
}
- if (!any_tp)
+
+ if (!any)
{
- warning (_("save-tracepoints: no tracepoints to save."));
+ warning (_("No breakpoints to save."));
return;
}
@@ -10675,18 +10709,53 @@ tracepoint_save_command (char *args, int
cleanup = make_cleanup (xfree, pathname);
fp = gdb_fopen (pathname, "w");
if (!fp)
- error (_("Unable to open file '%s' for saving tracepoints (%s)"),
+ error (_("Unable to open file '%s' for saving breakpoints (%s)"),
args, safe_strerror (errno));
make_cleanup_ui_file_delete (fp);
- save_trace_state_variables (fp);
+ if (extra_trace_bits)
+ save_trace_state_variables (fp);
- ALL_TRACEPOINTS (tp)
+ ALL_BREAKPOINTS (tp)
{
+ /* Skip internal and momentary breakpoints. */
+ if (tp->number <= 0)
+ continue;
+
+ /* If we have a filter, only list the breakpoints it accepts. */
+ if (filter && !filter (tp))
+ continue;
+
if (tp->type == bp_fast_tracepoint)
fprintf_unfiltered (fp, "ftrace");
- else
+ else if (tp->type == bp_tracepoint)
fprintf_unfiltered (fp, "trace");
+ if (tp->type == bp_breakpoint && tp->disposition == disp_del)
+ fprintf_unfiltered (fp, "tbreak");
+ else if (tp->type == bp_breakpoint)
+ fprintf_unfiltered (fp, "break");
+ else if (tp->type == bp_hardware_breakpoint && tp->disposition == disp_del)
+ fprintf_unfiltered (fp, "thbreak");
+ else if (tp->type == bp_hardware_breakpoint)
+ fprintf_unfiltered (fp, "hbreak");
+ else if (tp->type == bp_watchpoint)
+ fprintf_unfiltered (fp, "watch");
+ else if (tp->type == bp_hardware_watchpoint)
+ fprintf_unfiltered (fp, "watch");
+ else if (tp->type == bp_read_watchpoint)
+ fprintf_unfiltered (fp, "rwatch");
+ else if (tp->type == bp_access_watchpoint)
+ fprintf_unfiltered (fp, "awatch");
+ else if (tp->type == bp_hardware_breakpoint)
+ fprintf_unfiltered (fp, "hbreak");
+ else if (tp->type == bp_hardware_breakpoint)
+ fprintf_unfiltered (fp, "hbreak");
+ else if (tp->type == bp_catchpoint)
+ (tp->ops->print_create) (tp, fp);
+ else
+ internal_error (__FILE__, __LINE__,
+ _("unhandled breakpoint type %d"),
+ (int) tp->type);
if (tp->addr_string)
fprintf_unfiltered (fp, " %s", tp->addr_string);
@@ -10708,7 +10777,7 @@ tracepoint_save_command (char *args, int
{
volatile struct gdb_exception ex;
- fprintf_unfiltered (fp, " actions\n");
+ fprintf_unfiltered (fp, " commands\n");
ui_out_redirect (uiout, fp);
TRY_CATCH (ex, RETURN_MASK_ERROR)
@@ -10722,15 +10791,31 @@ tracepoint_save_command (char *args, int
fprintf_unfiltered (fp, " end\n");
}
+
+ if (tp->enable_state == bp_disabled)
+ fprintf_unfiltered (fp, "disable %d\n", tp->number);
}
- if (*default_collect)
+ if (extra_trace_bits && *default_collect)
fprintf_unfiltered (fp, "set default-collect %s\n", default_collect);
do_cleanups (cleanup);
if (from_tty)
- printf_filtered (_("Tracepoints saved to file '%s'.\n"), args);
- return;
+ printf_filtered (_("Breakpoints saved to file '%s'.\n"), args);
+}
+
+/* save-breakpoints command */
+static void
+save_breakpoints_command (char *args, int from_tty)
+{
+ breakpoint_save (args, from_tty, NULL);
+}
+
+/* save-tracepoints command */
+static void
+tracepoint_save_command (char *args, int from_tty)
+{
+ breakpoint_save (args, from_tty, is_tracepoint);
}
/* Create a vector of all tracepoints. */
@@ -11232,6 +11317,11 @@ Save current tracepoint definitions as a
Use the 'source' command in another debug session to restore them."));
set_cmd_completer (c, filename_completer);
+ c = add_com ("save-breakpoints", class_breakpoint, save_breakpoints_command, _("\
+Save current breakpoint definitions as a script.\n\
+Use the 'source' command in another debug session to restore them."));
+ set_cmd_completer (c, filename_completer);
+
add_prefix_cmd ("breakpoint", class_maintenance, set_breakpoint_cmd, _("\
Breakpoint specific settings\n\
Configure various breakpoint-specific variables such as\n\
Index: src/gdb/breakpoint.h
===================================================================
--- src.orig/gdb/breakpoint.h 2010-04-09 00:00:42.000000000 +0100
+++ src/gdb/breakpoint.h 2010-04-09 00:07:35.000000000 +0100
@@ -362,6 +362,10 @@ struct breakpoint_ops
/* Display information about this breakpoint after setting it (roughly
speaking; this is called from "mention"). */
void (*print_mention) (struct breakpoint *);
+
+ /* Display information about this breakpoint after setting it (roughly
+ speaking; this is called from "mention"). */
+ void (*print_create) (struct breakpoint *, struct ui_file *fp);
};
enum watchpoint_triggered
More information about the Gdb-patches
mailing list