* gdb.base/freebpcmd.exp, gdb.base/freebpcmd.c: New test.
authorJim Blandy <jimb@codesourcery.com>
Sat, 13 Dec 2003 20:12:31 +0000 (20:12 +0000)
committerJim Blandy <jimb@codesourcery.com>
Sat, 13 Dec 2003 20:12:31 +0000 (20:12 +0000)
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/freebpcmd.c [new file with mode: 0644]
gdb/testsuite/gdb.base/freebpcmd.exp [new file with mode: 0644]

index 1939f1c..3e7ccdb 100644 (file)
@@ -1,3 +1,7 @@
+2003-12-13  Jim Blandy  <jimb@redhat.com>
+
+       * gdb.base/freebpcmd.exp, gdb.base/freebpcmd.c: New test.
+
 2003-12-12  Kevin Buettner  <kevinb@redhat.com>
 
        * gdb.asm/frv.inc: New file.
diff --git a/gdb/testsuite/gdb.base/freebpcmd.c b/gdb/testsuite/gdb.base/freebpcmd.c
new file mode 100644 (file)
index 0000000..52d9f30
--- /dev/null
@@ -0,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;
+}
diff --git a/gdb/testsuite/gdb.base/freebpcmd.exp b/gdb/testsuite/gdb.base/freebpcmd.exp
new file mode 100644 (file)
index 0000000..f952139
--- /dev/null
@@ -0,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)"
+    }
+}