1# Copyright 2014-2020 Free Software Foundation, Inc.
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
15
16# Test that GDB isn't silent if it fails to remove a breakpoint from
17# the main program, independently of whether the program was loaded
18# with "file PROGRAM" or directly from the command line with "gdb
19# PROGRAM".
20
21standard_testfile
22
23if {[build_executable "failed to prepare" $testfile $srcfile debug]} {
24    return -1
25}
26
27# Run the test proper.  INITIAL_LOAD determines whether the program is
28# initially loaded by the "file" command or by passing it to GDB on
29# the command line.
30proc test_remove_bp { initial_load } {
31    with_test_prefix "$initial_load" {
32	global srcdir subdir binfile
33	global gdb_prompt hex
34	global GDBFLAGS
35
36	gdb_exit
37
38	set saved_gdbflags $GDBFLAGS
39
40	# See "used to behave differently" further below.
41	if { $initial_load == "file" } {
42	    gdb_start
43	    gdb_file_cmd $binfile
44	} else {
45	    global last_loaded_file
46
47	    # gdb_file_cmd sets this.  This is what gdb_reload
48	    # implementations use as binary.
49	    set last_loaded_file $binfile
50
51	    set GDBFLAGS "$GDBFLAGS $binfile"
52	    gdb_start
53	}
54	gdb_reinitialize_dir $srcdir/$subdir
55	gdb_reload
56	set GDBFLAGS $saved_gdbflags
57
58	if ![runto start] {
59	    fail "can't run to start"
60	    return
61	}
62
63	delete_breakpoints
64
65	# So we can easily control when are breakpoints removed.
66	gdb_test_no_output "set breakpoint always-inserted on"
67
68	set bp_addr ""
69
70	set test "break foo"
71	gdb_test_multiple $test $test {
72	    -re "Breakpoint .* at ($hex).*$gdb_prompt $" {
73		set bp_addr $expect_out(1,string)
74		pass $test
75	    }
76	}
77
78	if {$bp_addr == ""} {
79	    unsupported "can't extract foo's address"
80	    return
81	}
82
83	gdb_test "info break" "y.*$hex.*in foo at.*" \
84	    "breakpoint is set"
85
86	# Now unmap the page where the breakpoint is set.  Trying to
87	# remove the memory breakpoint afterwards should fail, and GDB
88	# should warn the user about it.
89	set pagesize [get_integer_valueof "pg_size" 0]
90	set align_addr [expr $bp_addr - $bp_addr % $pagesize]
91	set munmap [get_integer_valueof "(int) munmap ($align_addr, $pagesize)" -1]
92
93	if {$munmap != 0} {
94	    unsupported "can't munmap foo's page"
95	    return
96	}
97
98	gdb_test "delete \$bpnum" \
99	    "warning: Error removing breakpoint .*" \
100	    "failure to remove breakpoint warns"
101    }
102}
103
104foreach initial_load { "cmdline" "file" } {
105    test_remove_bp $initial_load
106}
107