From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17728 invoked by alias); 8 Apr 2010 23:40:39 -0000 Received: (qmail 17717 invoked by uid 22791); 8 Apr 2010 23:40:36 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=BAYES_00,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 08 Apr 2010 23:40:24 +0000 Received: (qmail 9085 invoked from network); 8 Apr 2010 23:40:22 -0000 Received: from unknown (HELO orlando.localnet) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 8 Apr 2010 23:40:22 -0000 From: Pedro Alves To: Joel Brobecker Subject: Re: [patch][python] Add breakpoint support. Date: Thu, 08 Apr 2010 23:40:00 -0000 User-Agent: KMail/1.12.2 (Linux/2.6.31-20-generic; KDE/4.3.2; x86_64; ; ) Cc: gdb-patches@sourceware.org, Phil Muldoon , Tom Tromey , Eli Zaretskii References: <4BB0B063.6000600@redhat.com> <201004082321.01822.pedro@codesourcery.com> <20100408232547.GN19194@adacore.com> In-Reply-To: <20100408232547.GN19194@adacore.com> MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-Id: <201004090040.18692.pedro@codesourcery.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-04/txt/msg00213.txt.bz2 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