1 # Copyright 2015-2024 Free Software Foundation, Inc.
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.
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.
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/>.
18 # This test is Linux-only.
19 if {![istarget *-*-linux*]} {
20 untested "coredump-filter.exp"
24 if { [prepare_for_testing "failed to prepare" $testfile $srcfile debug] } {
28 if { ![runto_main] } {
32 gdb_breakpoint [gdb_get_line_number "break-here"]
33 gdb_continue_to_breakpoint "break-here" ".* break-here .*"
35 proc do_save_core { filter_flag core dump_excluded } {
36 verbose -log "writing $filter_flag to /proc/<inferior pid>/coredump_filter"
38 gdb_test "p set_coredump_filter ($filter_flag)" " = 0"
40 # Enable dumping of excluded mappings (i.e. VM_DONTDUMP).
41 if { $dump_excluded == 1 } {
42 gdb_test_no_output "set dump-excluded-mappings on"
45 # Generate a corefile.
46 gdb_gcore_cmd "$core" "save corefile"
48 # Restore original status.
49 if { $dump_excluded == 1 } {
50 gdb_test_no_output "set dump-excluded-mappings off"
54 proc do_load_and_test_core { core var working_var working_value dump_excluded } {
55 global hex decimal coredump_var_addr
57 set core_loaded [gdb_core_cmd "$core" "load core"]
58 if { $core_loaded == -1 } {
63 # Access the memory the addresses point to.
64 if { $dump_excluded == 0 } {
65 gdb_test "print/x *(char *) $coredump_var_addr($var)" "\(\\\$$decimal = <error: \)?Cannot access memory at address $hex\(>\)?" \
66 "printing $var when core is loaded (should not work)"
67 gdb_test "print/x *(char *) $coredump_var_addr($working_var)" " = $working_value.*" \
68 "print/x *$working_var ( = $working_value)"
70 # Check if VM_DONTDUMP mappings are present in the core file.
71 gdb_test "print/x *(char *) $coredump_var_addr($var)" " = $working_value.*" \
72 "print/x *$var ( = $working_value)"
76 # We do not do file-backed mappings in the test program, but it is
77 # important to test this anyway. One way of performing the test is to
78 # load GDB with a corefile but without a binary, and then ask for the
79 # disassemble of a function (i.e., the binary's .text section). GDB
80 # should fail in this case. However, it must succeed if the binary is
81 # provided along with the corefile. This is what we test here.
83 # A further complication is that Linux NT_FILE notes are now read from
84 # the corefile. This note allows GDB to find the binary for file
85 # backed mappings even though the binary wasn't loaded by GDB in the
86 # conventional manner. In order to see the expected failure for this
87 # case, we rename the binary in order to perform this test.
89 proc test_disasm { core address should_fail } {
90 global testfile hex binfile
92 # Restart GDB without loading the binary.
93 with_test_prefix "no binary" {
97 set hide_binfile [standard_output_file "${testfile}.hide"]
98 if { $should_fail == 1 } {
99 remote_exec host "mv -f $binfile $hide_binfile"
102 set core_loaded [gdb_core_cmd "$core" "load core"]
103 if { $core_loaded == -1 } {
108 if { $should_fail == 1 } {
109 remote_exec host "mv -f $hide_binfile $binfile"
110 gdb_test "x/i \$pc" "=> $hex:\tCannot access memory at address $hex" \
111 "disassemble function with corefile and without a binary"
113 gdb_test "x/i \$pc" "=> $hex:\t\[^C\].*" \
114 "disassemble function with corefile and without a binary"
118 with_test_prefix "with binary" {
119 clean_restart $testfile
121 set core_loaded [gdb_core_cmd "$core" "load core"]
122 if { $core_loaded == -1 } {
127 gdb_test "disassemble $address" "Dump of assembler code for function.*" \
128 "disassemble function with corefile and with a binary"
132 set non_private_anon_core [standard_output_file non-private-anon.gcore]
133 set non_shared_anon_core [standard_output_file non-shared-anon.gcore]
134 # A corefile without {private,shared} {anonymous,file-backed} pages
135 set non_private_shared_anon_file_core [standard_output_file non-private-shared-anon-file.gcore]
136 set dont_dump_core [standard_output_file dont-dump.gcore]
137 set dump_excluded_core [standard_output_file dump-excluded.gcore]
139 # We will generate a few corefiles.
141 # This list is composed by sub-lists, and their elements are (in
145 # - hexadecimal value to be put in the /proc/PID/coredump_filter file
146 # - name of the variable that contains the name of the corefile to be
147 # generated (including the initial $).
148 # - name of the variable in the C source code that points to the
149 # memory mapping that will NOT be present in the corefile.
150 # - name of a variable in the C source code that points to a memory
151 # mapping that WILL be present in the corefile
152 # - corresponding value expected for the above variable
153 # - whether to include mappings marked as VM_DONTDUMP in the
154 # corefile (1) or not (0).
156 # This list refers to the corefiles generated by MAP_ANONYMOUS in the
159 set all_anon_corefiles { { "non-Private-Anonymous" "0x7e" \
160 $non_private_anon_core \
162 "shared_anon" "0x22" "0" }
163 { "non-Shared-Anonymous" "0x7d" \
164 $non_shared_anon_core "shared_anon" \
165 "private_anon" "0x11" "0" }
166 { "DoNotDump" "0x33" \
167 $dont_dump_core "dont_dump" \
168 "shared_anon" "0x22" "0" }
169 { "DoNotDump-DumpExcluded" "0x33" \
170 $dump_excluded_core "dont_dump" \
171 "shared_anon" "0x55" "1" } }
173 # If corefile loading is not supported, we do not even try to run the
175 set core_supported [gdb_gcore_cmd "$non_private_anon_core" "save a corefile"]
176 if { !$core_supported } {
177 untested "corefile generation is not supported"
181 gdb_test_multiple "info inferiors" "getting inferior pid" {
182 -re "process $decimal.*\r\n$gdb_prompt $" {
184 -re "Remote target.*$gdb_prompt $" {
185 # If the target does not provide PID information (like usermode QEMU),
186 # just bail out as the rest of the test may rely on it, giving spurious
192 # Get the main function's address.
194 gdb_test_multiple "print/x &main" "getting main's address" {
195 -re "$decimal = \($hex\)\r\n$gdb_prompt $" {
196 set main_addr $expect_out(1,string)
200 # Obtain the address of each variable that will be checked on each
202 unset -nocomplain coredump_var_addr
203 foreach item $all_anon_corefiles {
204 foreach name [list [lindex $item 3] [lindex $item 4]] {
205 set test "print/x $name"
206 gdb_test_multiple $test $test {
207 -re " = \($hex\)\r\n$gdb_prompt $" {
208 set coredump_var_addr($name) $expect_out(1,string)
214 # Generate corefiles for the "anon" case.
215 foreach item $all_anon_corefiles {
216 with_test_prefix "saving corefile for [lindex $item 0]" {
217 do_save_core [lindex $item 1] [subst [lindex $item 2]] [lindex $item 6]
221 with_test_prefix "saving corefile for non-Private-Shared-Anon-File" {
222 do_save_core "0x60" $non_private_shared_anon_file_core "0"
225 clean_restart $testfile
227 foreach item $all_anon_corefiles {
228 with_test_prefix "loading and testing corefile for [lindex $item 0]" {
229 do_load_and_test_core [subst [lindex $item 2]] [lindex $item 3] \
230 [lindex $item 4] [lindex $item 5] [lindex $item 6]
233 with_test_prefix "disassembling function main for [lindex $item 0]" {
234 test_disasm [subst [lindex $item 2]] $main_addr 0
238 with_test_prefix "loading and testing corefile for non-Private-Shared-Anon-File" {
239 test_disasm $non_private_shared_anon_file_core $main_addr 0
242 with_test_prefix "loading and testing corefile for non-Private-Shared-Anon-File with renamed binary" {
243 test_disasm $non_private_shared_anon_file_core $main_addr 1