From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26892 invoked by alias); 13 Dec 2003 20:11: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 26821 invoked from network); 13 Dec 2003 20:11:18 -0000 Received: from unknown (HELO zenia.home) (12.223.225.216) by sources.redhat.com with SMTP; 13 Dec 2003 20:11:18 -0000 Received: by zenia.home (Postfix, from userid 5433) id 33B83207A2; Sat, 13 Dec 2003 15:08:34 -0500 (EST) To: Daniel Jacobowitz Cc: gdb-patches@sources.redhat.com Subject: Re: RFA: New regression test for breakpoint command freeing References: <20031213060440.GA32084@nevyn.them.org> From: Jim Blandy Date: Sat, 13 Dec 2003 20:11:00 -0000 In-Reply-To: <20031213060440.GA32084@nevyn.them.org> 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/msg00359.txt.bz2 Daniel Jacobowitz writes: > On Sat, Dec 13, 2003 at 12:55:37AM -0500, Jim Blandy wrote: > > + gdb_test_multiple "run" "run program with breakpoint commands" { > > No, please don't; any time that you issue an explicit "run" command in > a testcase is probably a bug. Take a look at gdb_run_cmd: Yes, of course; I should have known this. Sorry. Revised as below, and committed: gdb/testsuite/ChangeLog: 2003-12-13 Jim Blandy * gdb.base/freebpcmd.exp, gdb.base/freebpcmd.c: New test. Index: gdb/testsuite/gdb.base/freebpcmd.exp =================================================================== RCS file: gdb/testsuite/gdb.base/freebpcmd.exp diff -N gdb/testsuite/gdb.base/freebpcmd.exp *** gdb/testsuite/gdb.base/freebpcmd.exp 1 Jan 1970 00:00:00 -0000 --- gdb/testsuite/gdb.base/freebpcmd.exp 13 Dec 2003 20:09:30 -0000 *************** *** 0 **** --- 1,121 ---- + # Copyright 2003 Free Software Foundation, Inc. + + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 2 of the License, or + # (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with this program; if not, write to the Free Software + # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + + # This is a regression test for the following bug, as of 2003-12-12: + # + # Set a breakpoint which will be hit many times. Attach a complex set + # of commands to it, including a "continue" command. Run the program, + # so that the breakpoint is hit, its commands get executed, and the + # program continues and hits the breakpoint again. You will see + # messages like "warning: Invalid control type in command structure.", + # or maybe GDB will crash. + # + # When the breakpoint is hit, bpstat_stop_status copies the + # breakpoint's command tree to the bpstat. bpstat_do_actions then + # calls execute_control_command to run the commands. The 'continue' + # command invokes the following chain of calls: + # + # continue_command + # -> clear_proceed_status + # -> bpstat_clear + # -> free_command_lines + # -> frees the commands we are currently running. + # + # When control does eventually return to execute_control_command, GDB + # continues to walk the tree of freed command nodes, resulting in the + # error messages and / or crashes. + # + # Since this bug depends on storage being reused between the time that + # we continue and the time that we fall back to bpstat_do_actions, the + # reproduction recipe is more delicate than I would like. I welcome + # suggestions for improving this. + + set prms_id 0 + set bug_id 0 + + set testfile "freebpcmd" + set srcfile ${testfile}.c + set srcfile1 ${testfile}1.c + set binfile ${objdir}/${subdir}/${testfile} + + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." + } + + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load ${binfile} + + gdb_test "break [gdb_get_line_number "euphonium"]" "" "set breakpoint" + + # The goal of all this is to make sure that there's plenty of memory + # churn, and different amounts of it each time the inferior stops; + # this seems to make GDB crash more reliably. + set lines {{if (i%2) == 0} + {echo "even "} + {print i} + {else} + {echo "odd "} + {print i} + {end} + {set variable $foo = 0} + {set variable $j = 0} + {while $j < i} + {set variable $foo += $j} + {set variable $j++} + {end} + {print $foo} + {if i != 40} + {c} + {end} + {end}} + + send_gdb "commands\n" + for {set i 0} {$i < [llength $lines]} {incr i} { + gdb_expect { + -re ".*>" { + send_gdb "[lindex $lines $i]\n" + } + -re "$gdb_prompt $" { + set reason "got top-level prompt early" + break + } + timeout { + set reason "timeout" + break + } + } + } + if {$i >= [llength $lines]} { + pass "send breakpoint commands" + } else { + fail "send breakpoint commands ($reason)" + } + + gdb_run_cmd + gdb_test_multiple "" "run program with breakpoint commands" { + -re "warning: Invalid control type in command structure" { + fail "run program with breakpoint commands" + } + -re "$gdb_prompt $" { + pass "run program with breakpoint commands" + } + eof { + fail "run program with breakpoint commands (GDB died)" + } + } Index: gdb/testsuite/gdb.base/freebpcmd.c =================================================================== RCS file: gdb/testsuite/gdb.base/freebpcmd.c diff -N gdb/testsuite/gdb.base/freebpcmd.c *** gdb/testsuite/gdb.base/freebpcmd.c 1 Jan 1970 00:00:00 -0000 --- gdb/testsuite/gdb.base/freebpcmd.c 13 Dec 2003 20:09:30 -0000 *************** *** 0 **** --- 1,15 ---- + int + main (int argc, char **argv) + { + int i; + + #ifdef usestubs + set_debug_traps(); + breakpoint(); + #endif + + for (i = 0; i < 100; i++) + printf (">>> %d\n", i); /* euphonium */ + + return 0; + }