| # Copyright 2003-2021 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 3 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, see <http://www.gnu.org/licenses/>. |
| |
| |
| # 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. |
| |
| |
| standard_testfile |
| if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} { |
| return -1 |
| } |
| |
| gdb_test "break ${srcfile}:[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<0 || i > 100} |
| {echo Invalid i value\n} |
| {else} |
| {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} |
| {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 |
| |
| with_timeout_factor 10 { |
| gdb_test_multiple "" "run program with breakpoint commands" { |
| -re "warning: Invalid control type in command structure" { |
| kfail "gdb/1489" "run program with breakpoint commands" |
| } |
| -re "Invalid i value\r\n$gdb_prompt $" { |
| xfail "run program with breakpoint commands (i value not readable)" |
| } |
| -re "$gdb_prompt $" { |
| pass "run program with breakpoint commands" |
| } |
| eof { |
| kfail "gdb/1489" "run program with breakpoint commands (GDB died)" |
| } |
| } |
| } |