From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20726 invoked by alias); 13 Dec 2003 05:59:20 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 20718 invoked from network); 13 Dec 2003 05:59:19 -0000 Received: from unknown (HELO zenia.home) (12.223.225.216) by sources.redhat.com with SMTP; 13 Dec 2003 05:59:19 -0000 Received: by zenia.home (Postfix, from userid 5433) id 9F45720766; Sat, 13 Dec 2003 00:56:39 -0500 (EST) To: gdb-patches@sources.redhat.com Subject: RFA: protect breakpoint commands from being freed From: Jim Blandy Date: Sat, 13 Dec 2003 05:59:00 -0000 Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2003-12/txt/msg00350.txt.bz2 2003-12-02 Jim Blandy * breakpoint.c (bpstat_do_actions): To ensure that clear_proceed_status doesn't free the command tree we're evaluating out from under us, zero the bpstat's pointer to it, and take care of freeing it ourselves. * cli/cli-script.c (make_cleanup_free_command_lines): Make this function externally visible. * cli/cli-script.h (make_cleanup_free_command_lines): New declaration. Index: gdb/breakpoint.c =================================================================== RCS file: /cvs/cvsfiles/devo/gdb/breakpoint.c,v retrieving revision 1.361.2.1 diff -c -r1.361.2.1 breakpoint.c *** gdb/breakpoint.c 22 Oct 2003 00:34:07 -0000 1.361.2.1 --- gdb/breakpoint.c 3 Dec 2003 04:31:28 -0000 *************** *** 1943,1949 **** { bpstat bs; struct cleanup *old_chain; - struct command_line *cmd; /* Avoid endless recursion if a `source' command is contained in bs->commands. */ --- 1943,1948 ---- *************** *** 1968,1974 **** --- 1967,1989 ---- breakpoint_proceeded = 0; for (; bs != NULL; bs = bs->next) { + struct command_line *cmd; + struct cleanup *this_cmd_tree_chain; + + /* Take ownership of the BSP's command tree, if it has one. + + The command tree could legitimately contain commands like + 'step' and 'next', which call clear_proceed_status, which + frees stop_bpstat's command tree. To make sure this doesn't + free the tree we're executing out from under us, we need to + take ownership of the tree ourselves. Since a given bpstat's + commands are only executed once, we don't need to copy it; we + can clear the pointer in the bpstat, and make sure we free + the tree when we're done. */ cmd = bs->commands; + bs->commands = 0; + this_cmd_tree_chain = make_cleanup_free_command_lines (&cmd); + while (cmd != NULL) { execute_control_command (cmd); *************** *** 1978,1991 **** else cmd = cmd->next; } if (breakpoint_proceeded) /* The inferior is proceeded by the command; bomb out now. The bpstat chain has been blown away by wait_for_inferior. But since execution has stopped again, there is a new bpstat to look at, so start over. */ goto top; - else - free_command_lines (&bs->commands); } do_cleanups (old_chain); } --- 1993,2008 ---- else cmd = cmd->next; } + + /* We can free this command tree now. */ + do_cleanups (this_cmd_tree_chain); + if (breakpoint_proceeded) /* The inferior is proceeded by the command; bomb out now. The bpstat chain has been blown away by wait_for_inferior. But since execution has stopped again, there is a new bpstat to look at, so start over. */ goto top; } do_cleanups (old_chain); } Index: gdb/cli/cli-script.c =================================================================== RCS file: /cvs/cvsfiles/devo/gdb/cli/cli-script.c,v retrieving revision 1.16 diff -c -r1.16 cli-script.c *** gdb/cli/cli-script.c 15 Oct 2003 17:30:27 -0000 1.16 --- gdb/cli/cli-script.c 3 Dec 2003 04:31:31 -0000 *************** *** 36,44 **** /* Prototypes for local functions */ - static struct cleanup * - make_cleanup_free_command_lines (struct command_line **arg); - static enum command_control_type recurse_read_control_structure (struct command_line *current_cmd); --- 36,41 ---- *************** *** 1001,1007 **** free_command_lines (arg); } ! static struct cleanup * make_cleanup_free_command_lines (struct command_line **arg) { return make_cleanup (do_free_command_lines_cleanup, arg); --- 998,1004 ---- free_command_lines (arg); } ! struct cleanup * make_cleanup_free_command_lines (struct command_line **arg) { return make_cleanup (do_free_command_lines_cleanup, arg); Index: gdb/cli/cli-script.h =================================================================== RCS file: /cvs/cvsfiles/devo/gdb/cli/cli-script.h,v retrieving revision 1.5 diff -c -r1.5 cli-script.h *** gdb/cli/cli-script.h 16 Apr 2003 21:18:50 -0000 1.5 --- gdb/cli/cli-script.h 3 Dec 2003 04:31:31 -0000 *************** *** 47,52 **** --- 47,54 ---- extern struct command_line * copy_command_lines (struct command_line *cmds); + struct cleanup *make_cleanup_free_command_lines (struct command_line **arg); + /* Exported to gdb/infrun.c */ extern void execute_user_command (struct cmd_list_element *c, char *args);