1# Copyright 2003, 2007, 2008, 2009, 2010, 2011 2# Free Software Foundation, Inc. 3 4# This program is free software; you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation; either version 3 of the License, or 7# (at your option) any later version. 8# 9# This program is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 18# This is a regression test for the following bug, as of 2003-12-12: 19# 20# Set a breakpoint which will be hit many times. Attach a complex set 21# of commands to it, including a "continue" command. Run the program, 22# so that the breakpoint is hit, its commands get executed, and the 23# program continues and hits the breakpoint again. You will see 24# messages like "warning: Invalid control type in command structure.", 25# or maybe GDB will crash. 26# 27# When the breakpoint is hit, bpstat_stop_status copies the 28# breakpoint's command tree to the bpstat. bpstat_do_actions then 29# calls execute_control_command to run the commands. The 'continue' 30# command invokes the following chain of calls: 31# 32# continue_command 33# -> clear_proceed_status 34# -> bpstat_clear 35# -> free_command_lines 36# -> frees the commands we are currently running. 37# 38# When control does eventually return to execute_control_command, GDB 39# continues to walk the tree of freed command nodes, resulting in the 40# error messages and / or crashes. 41# 42# Since this bug depends on storage being reused between the time that 43# we continue and the time that we fall back to bpstat_do_actions, the 44# reproduction recipe is more delicate than I would like. I welcome 45# suggestions for improving this. 46 47 48set testfile "freebpcmd" 49set srcfile ${testfile}.c 50set binfile ${objdir}/${subdir}/${testfile} 51 52if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { 53 untested freebpcmd.exp 54 return -1 55} 56 57gdb_exit 58gdb_start 59gdb_reinitialize_dir $srcdir/$subdir 60gdb_load ${binfile} 61 62gdb_test "break ${srcfile}:[gdb_get_line_number "euphonium"]" ".*" \ 63 "set breakpoint" 64 65# The goal of all this is to make sure that there's plenty of memory 66# churn, and different amounts of it each time the inferior stops; 67# this seems to make GDB crash more reliably. 68set lines {{if (i%2) == 0} 69 {echo "even "} 70 {print i} 71 {else} 72 {echo "odd "} 73 {print i} 74 {end} 75 {set variable $foo = 0} 76 {set variable $j = 0} 77 {while $j < i} 78 {set variable $foo += $j} 79 {set variable $j++} 80 {end} 81 {print $foo} 82 {if i != 40} 83 {c} 84 {end} 85 {end}} 86 87send_gdb "commands\n" 88for {set i 0} {$i < [llength $lines]} {incr i} { 89 gdb_expect { 90 -re ".*>" { 91 send_gdb "[lindex $lines $i]\n" 92 } 93 -re "$gdb_prompt $" { 94 set reason "got top-level prompt early" 95 break 96 } 97 timeout { 98 set reason "timeout" 99 break 100 } 101 } 102} 103if {$i >= [llength $lines]} { 104 pass "send breakpoint commands" 105} else { 106 fail "send breakpoint commands ($reason)" 107} 108 109gdb_run_cmd 110 111set prev_timeout $timeout 112set timeout 120 113 114gdb_test_multiple "" "run program with breakpoint commands" { 115 -re "warning: Invalid control type in command structure" { 116 kfail "gdb/1489" "run program with breakpoint commands" 117 } 118 -re "$gdb_prompt $" { 119 pass "run program with breakpoint commands" 120 } 121 eof { 122 kfail "gdb/1489" "run program with breakpoint commands (GDB died)" 123 } 124} 125 126set timeout $prev_timeout 127