1# Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2004 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 2 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, write to the Free Software 16# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 18# Please email any bugs, comments, and/or additions to this file to: 19# bug-gdb@prep.ai.mit.edu 20 21# This file is based on corefile.exp which was written by Fred 22# Fish. (fnf@cygnus.com) 23 24if $tracelevel then { 25 strace $tracelevel 26} 27 28set prms_id 0 29set bug_id 0 30 31# Are we on a target board? As of 2004-02-12, GDB didn't have a 32# mechanism that would let it efficiently access a remote corefile. 33 34if ![isnative] then { 35 untested "Remote system" 36 return 37} 38 39# Can the system run this test (in particular support sparse 40# corefiles)? On systems that lack sparse corefile support this test 41# consumes too many resources - gigabytes worth of disk space and and 42# I/O bandwith. 43 44if { [istarget "*-*-*bsd*"] 45 || [istarget "*-*-hpux*"] 46 || [istarget "*-*-solaris*"] 47 || [istarget "*-*-cygwin*"] } { 48 untested "Kernel lacks sparse corefile support (PR gdb/1551)" 49 return 50} 51 52# This testcase causes too much stress (in terms of memory usage) 53# on certain systems... 54if { [istarget "*-*-*irix*"] } { 55 untested "Testcase too stressful for this system" 56 return 57} 58 59set testfile "bigcore" 60set srcfile ${testfile}.c 61set binfile ${objdir}/${subdir}/${testfile} 62set corefile ${objdir}/${subdir}/${testfile}.corefile 63 64if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { 65 gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." 66} 67 68# Run GDB on the bigcore program up-to where it will dump core. 69 70gdb_exit 71gdb_start 72gdb_reinitialize_dir $srcdir/$subdir 73gdb_load ${binfile} 74gdb_test "set print sevenbit-strings" "" \ 75 "set print sevenbit-strings; ${testfile}" 76gdb_test "set width 0" "" \ 77 "set width 0; ${testfile}" 78if { ![runto_main] } then { 79 gdb_suppress_tests; 80} 81set print_core_line [gdb_get_line_number "Dump core"] 82gdb_test "tbreak $print_core_line" 83gdb_test continue ".*print_string.*" 84gdb_test next ".*0 = 0.*" 85 86# Traverse part of bigcore's linked list of memory chunks (forward or 87# backward), saving each chunk's address. 88 89proc extract_heap { dir } { 90 global gdb_prompt 91 global expect_out 92 set heap "" 93 set test "extract ${dir} heap" 94 set lim 0 95 gdb_test_multiple "print heap.${dir}" "$test" { 96 -re " = \\(struct list \\*\\) 0x0.*$gdb_prompt $" { 97 pass "$test" 98 } 99 -re " = \\(struct list \\*\\) (0x\[0-9a-f\]*).*$gdb_prompt $" { 100 set heap [concat $heap $expect_out(1,string)] 101 if { $lim >= 50 } { 102 pass "$test (stop at $lim)" 103 } else { 104 incr lim 105 send_gdb "print \$.${dir}\n" 106 exp_continue 107 } 108 } 109 -re ".*$gdb_prompt $" { 110 fail "$test (entry $lim)" 111 } 112 timeout { 113 fail "$test (timeout)" 114 } 115 } 116 return $heap; 117} 118set next_heap [extract_heap next] 119set prev_heap [extract_heap prev] 120 121# Now create a core dump 122 123# Rename the core file to "TESTFILE.corefile" rather than just "core", 124# to avoid problems with sys admin types that like to regularly prune 125# all files named "core" from the system. 126 127# Some systems append "core" to the name of the program; others append 128# the name of the program to "core"; still others (like Linux, as of 129# May 2003) create cores named "core.PID". 130 131# Save the process ID. Some systems dump the core into core.PID. 132set test "grab pid" 133gdb_test_multiple "info program" $test { 134 -re "child process (\[0-9\]+).*$gdb_prompt $" { 135 set inferior_pid $expect_out(1,string) 136 pass $test 137 } 138 -re "$gdb_prompt $" { 139 set inferior_pid unknown 140 pass $test 141 } 142} 143 144# Dump core using SIGABRT 145set oldtimeout $timeout 146set timeout 600 147gdb_test "signal SIGABRT" "Program terminated with signal SIGABRT, .*" 148 149# Find the corefile 150set file "" 151foreach pat [list core.${inferior_pid} ${testfile}.core core] { 152 set names [glob -nocomplain $pat] 153 if {[llength $names] == 1} { 154 set file [lindex $names 0] 155 remote_exec build "mv $file $corefile" 156 break 157 } 158} 159 160if { $file == "" } { 161 untested "Can't generate a core file" 162 return 0 163} 164 165# Check that the corefile is plausibly large enough. We're trying to 166# detect the case where the operating system has truncated the file 167# just before signed wraparound. TCL, unfortunately, has a similar 168# problem - so use catch. It can handle the "bad" size but not 169# necessarily the "good" one. And we must use GDB for the comparison, 170# similarly. 171 172if {[catch {file size $corefile} core_size] == 0} { 173 set core_ok 0 174 gdb_test_multiple "print bytes_allocated < $core_size" "check core size" { 175 -re " = 1\r\n$gdb_prompt $" { 176 pass "check core size" 177 set core_ok 1 178 } 179 } 180} { 181 # Probably failed due to the TCL build having problems with very 182 # large values. Since GDB uses a 64-bit off_t (when possible) it 183 # shouldn't have this problem. Assume that things are going to 184 # work. Without this assumption the test is skiped on systems 185 # (such as i386 GNU/Linux with patched kernel) which do pass. 186 pass "check core size" 187 set core_ok 1 188} 189if {! $core_ok} { 190 untested "check core size (system does not support large corefiles)" 191 return 0 192} 193 194# Now load up that core file 195 196set test "load corefile" 197gdb_test_multiple "core $corefile" "$test" { 198 -re "A program is being debugged already. Kill it. .y or n. " { 199 send_gdb "y\n" 200 exp_continue 201 } 202 -re "Core was generated by.*$gdb_prompt $" { 203 pass "$test" 204 } 205} 206 207# Finally, re-traverse bigcore's linked list, checking each chunk's 208# address against the executable. Don't use gdb_test_multiple as want 209# only one pass/fail. Don't use exp_continue as the regular 210# expression involving $heap needs to be re-evaluated for each new 211# response. 212 213proc check_heap { dir heap } { 214 global gdb_prompt 215 set test "check ${dir} heap" 216 set ok 1 217 set lim 0 218 send_gdb "print heap.${dir}\n" 219 while { $ok } { 220 gdb_expect { 221 -re " = \\(struct list \\*\\) [lindex $heap $lim].*$gdb_prompt $" { 222 if { $lim >= [llength $heap] } { 223 pass "$test" 224 set ok 0 225 } else { 226 incr lim 227 send_gdb "print \$.${dir}\n" 228 } 229 } 230 -re ".*$gdb_prompt $" { 231 fail "$test (address [lindex $heap $lim])" 232 set ok 0 233 } 234 timeout { 235 fail "$test (timeout)" 236 set ok 0 237 } 238 } 239 } 240} 241 242check_heap next $next_heap 243check_heap prev $prev_heap 244