1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
# Copyright 2025 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/>.
# Check that GDB doesn't emit a 'breakpoint-modified' notification for
# dprintf breakpoints when the dprintf commands haven't changed.
#
# GDB use to emit a 'breakpoint-modified' dprintf breakpoints each
# time the dprintf_breakpoint::re_set function was called as this
# would re-cacluate the dprintf command string, even though in most
# cases the calculated string was no different from the previous
# value.
#
# Then GDB got smarter and could recognise that the string had not
# changed, and so would skip the 'breakpoint-modified' notification.
#
# This test stops at a dlopen() call in the inferior and creates a
# dprintf breakpoint. Then we 'next' over the dlopen() which triggers
# a call to the ::re_set() functions. We check that there is no
# 'breakpoint-modified' event emitted for the dprintf breakpoint.
load_lib mi-support.exp
set MIFLAGS "-i=mi"
standard_testfile .c -lib.c
# Build the library.
set libname ${testfile}-lib
set libfile [standard_output_file $libname]
if { [build_executable "build shlib" $libfile $srcfile2 {debug shlib}] == -1} {
return
}
# Build the executable.
set opts [list debug shlib_load additional_flags=-DSHLIB_NAME=\"${libname}\"]
if { [build_executable "build exec" $binfile $srcfile $opts] == -1} {
return
}
# The line number of the dlopen() call.
set bp_line [gdb_get_line_number "Break here" $srcfile]
# Start the inferior.
mi_clean_restart $binfile
mi_runto_main
# Place a breakpoint at the dlopen() line.
mi_create_breakpoint $srcfile:$bp_line "set breakpoint at dlopen call" \
-disp keep -func main -file "\[^\r\n\]+/$srcfile" -line $bp_line
# And run to the breakpoint.
mi_execute_to "exec-continue" "breakpoint-hit" main "" ".*/$srcfile" \
$bp_line { "" "disp=\"keep\"" } "run to breakpoint"
# Cleanup breakpoints.
mi_delete_breakpoints
# Setup a dprintf breakpoint.
mi_gdb_test "-dprintf-insert --function main \"in main\"" \
"\\^done,bkpt={.*}" "dprintf at main"
set bpnum [mi_get_valueof "/d" "\$bpnum" "INVALID" \
"get number for dprintf breakpoint"]
# Use 'next' to step over loading the shared library.
mi_gdb_test "220-exec-next" ".*" "next over dlopen"
# Now wait for the 'stopped' notification. While we wait we should
# see a 'library-loaded' notification for the loading of the shared
# library.
#
# In older versions of GDB we would also see a 'breakpoint-modified'
# notification for the dprintf breakpoint, but newer versions of GDB
# are smart enough to not emit this unnecessary notification.
set bp_re [mi_make_breakpoint -number $bpnum \
-type dprintf -disp keep -enabled y -func main]
set saw_bp_modified false
set saw_lib_load false
set saw_stopped false
gdb_test_multiple "" "wait for 'next' to complete" {
-re "^=library-loaded,id=\[^\r\n\]+\r\n" {
set saw_lib_load true
exp_continue
}
-re "^=breakpoint-modified,$bp_re\r\n" {
set saw_bp_modified true
exp_continue
}
-re "^\\*stopped,reason=\"end-stepping-range\",\[^\r\n\]+\r\n" {
set saw_stopped true
exp_continue
}
-re "^$mi_gdb_prompt$" {
gdb_assert { $saw_lib_load } \
"$gdb_test_name, library was loaded"
gdb_assert { $saw_stopped } \
"$gdb_test_name, saw stopped message"
gdb_assert { !$saw_bp_modified } \
"$gdb_test_name, no breakpoint-modified"
}
-re "^\[^\r\n\]+\r\n" {
exp_continue
}
}
|