diff options
author | David Carlton <carlton@bactrian.org> | 2004-01-26 19:11:55 +0000 |
---|---|---|
committer | David Carlton <carlton@bactrian.org> | 2004-01-26 19:11:55 +0000 |
commit | feff3e492f1aff01b62a61e38e20fc7e8fc89946 (patch) | |
tree | 08c456fb63098f7b46e1dfa74746c8ab87a74e8c /gdb/testsuite/lib | |
parent | aa0e88e3d758559942e192f3075a3edc0b2f222d (diff) | |
download | binutils-carlton_dictionary-branch.zip binutils-carlton_dictionary-branch.tar.gz binutils-carlton_dictionary-branch.tar.bz2 |
2004-01-26 David Carlton <carlton@kealia.com>carlton_dictionary-branch
* Merge with mainline; tag is carlton_dictionary-20040126-merge.
Diffstat (limited to 'gdb/testsuite/lib')
-rw-r--r-- | gdb/testsuite/lib/compiler.c | 57 | ||||
-rw-r--r-- | gdb/testsuite/lib/compiler.cc | 48 | ||||
-rw-r--r-- | gdb/testsuite/lib/gdb.exp | 325 | ||||
-rw-r--r-- | gdb/testsuite/lib/mi-support.exp | 125 |
4 files changed, 346 insertions, 209 deletions
diff --git a/gdb/testsuite/lib/compiler.c b/gdb/testsuite/lib/compiler.c index b0f557c..b1f1f5d 100644 --- a/gdb/testsuite/lib/compiler.c +++ b/gdb/testsuite/lib/compiler.c @@ -1,6 +1,6 @@ /* This test file is part of GDB, the GNU debugger. - Copyright 1995, 1997, 1999, 2003 Free Software Foundation, Inc. + Copyright 1995, 1997, 1999, 2003, 2004 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 @@ -19,36 +19,47 @@ Please email any bugs, comments, and/or additions to this file to: bug-gdb@prep.ai.mit.edu */ -/* Often the behavior of any particular test depends upon what compiler was - used to compile the test. As each test is compiled, this file is - preprocessed by the same compiler used to compile that specific test - (different tests might be compiled by different compilers, particularly - if compiled at different times), and used to generate a *.ci (compiler - info) file for that test. +/* Sometimes the behavior of a test depends upon the compiler used to + compile the test program. A test script can call get_compiler_info + to figure out the compiler version and test_compiler_info to test it. - I.E., when callfuncs is compiled, a callfuncs.ci file will be generated, - which can then be sourced by callfuncs.exp to give callfuncs.exp access - to information about the compilation environment. + get_compiler_info runs the preprocessor on this file and then eval's + the result. This sets various symbols for use by test_compiler_info. - TODO: It might be a good idea to add expect code that tests each - definition made with 'set" to see if one already exists, and if so - warn about conflicts if it is being set to something else. */ + TODO: make compiler_info a local variable for get_compiler_info and + test_compiler_info. -/* This needs to be kept in sync with whatis.c and gdb.exp(get_compiler_info). - If this ends up being hairy, we could use a common header file. */ + TODO: all clients should use test_compiler_info and should not + use gcc_compiled, hp_cc_compiler, or hp_aCC_compiler. -#if defined (__STDC__) || defined (_AIX) -set signed_keyword_not_used 0 -#else -set signed_keyword_not_used 1 -#endif + TODO: purge signed_keyword_not_used. */ + +set compiler_info "" #if defined (__GNUC__) -set gcc_compiled __GNUC__ set compiler_info [join {gcc __GNUC__ __GNUC_MINOR__ } -] +set gcc_compiled __GNUC__ #else set gcc_compiled 0 -set compiler_info "" #endif -return 0 +#if defined (__HP_cc) +set compiler_info [join {hpcc __HP_cc} -] +set hp_cc_compiler __HP_cc +#else +set hp_cc_compiler 0 +#endif + +#if defined (__HP_aCC) +set compiler_info [join {hpacc __HP_aCC} -] +set hp_aCC_compiler __HP_aCC +#else +set hp_aCC_compiler 0 +#endif + +/* gdb.base/whatis.exp still uses this */ +#if defined (__STDC__) || defined (_AIX) +set signed_keyword_not_used 0 +#else +set signed_keyword_not_used 1 +#endif diff --git a/gdb/testsuite/lib/compiler.cc b/gdb/testsuite/lib/compiler.cc index 719b62b..0c5eb66 100644 --- a/gdb/testsuite/lib/compiler.cc +++ b/gdb/testsuite/lib/compiler.cc @@ -1,6 +1,6 @@ /* This test file is part of GDB, the GNU debugger. - Copyright 1995, 1999, 2003 Free Software Foundation, Inc. + Copyright 1995, 1999, 2003, 2004 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 @@ -19,39 +19,35 @@ Please email any bugs, comments, and/or additions to this file to: bug-gdb@prep.ai.mit.edu */ -/* Often the behavior of any particular test depends upon what compiler was - used to compile the test. As each test is compiled, this file is - preprocessed by the same compiler used to compile that specific test - (different tests might be compiled by different compilers, particularly - if compiled at different times), and used to generate a *.ci (compiler - info) file for that test. +/* This file is exactly like compiler.c. I could just use compiler.c if + I could be sure that every C++ compiler accepted extensions of ".c". */ - I.E., when callfuncs is compiled, a callfuncs.ci file will be generated, - which can then be sourced by callfuncs.exp to give callfuncs.exp access - to information about the compilation environment. - - TODO: It might be a good idea to add expect code that tests each - definition made with 'set" to see if one already exists, and if so - warn about conflicts if it is being set to something else. */ +set compiler_info "" -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 6)) -set supports_template_debugging 1 +#if defined (__GNUC__) +set compiler_info [join {gcc __GNUC__ __GNUC_MINOR__ } -] +set gcc_compiled __GNUC__ #else -set supports_template_debugging 0 +set gcc_compiled 0 #endif -#if defined(__cplusplus) -set supports_template_debugging 1 +#if defined (__HP_cc) +set compiler_info [join {hpcc __HP_cc} -] +set hp_cc_compiler __HP_cc #else -set supports_template_debugging 0 +set hp_cc_compiler 0 #endif -#if defined (__GNUC__) -set gcc_compiled __GNUC__ -set compiler_info [join {gcc __GNUC__ __GNUC_MINOR__ } -] +#if defined (__HP_aCC) +set compiler_info [join {hpacc __HP_aCC} -] +set hp_aCC_compiler __HP_aCC #else -set gcc_compiled 0 -set compiler_info "" +set hp_aCC_compiler 0 #endif -return 0 +/* gdb.base/whatis.exp still uses this */ +#if defined (__STDC__) || defined (_AIX) +set signed_keyword_not_used 0 +#else +set signed_keyword_not_used 1 +#endif diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 136f68c..9670c34 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -1,5 +1,5 @@ # Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -# 2002, 2003 +# 2002, 2003, 2004 # Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify @@ -1094,86 +1094,114 @@ proc skip_hp_tests {} { return $skip_hp } -global compiler_info -set compiler_info unknown +set compiler_info "unknown" +set gcc_compiled 0 +set hp_cc_compiler 0 +set hp_aCC_compiler 0 +set signed_keyword_not_used 0 + +# Figure out what compiler I am using. +# +# BINFILE is a "compiler information" output file. This implementation +# does not use BINFILE. +# +# ARGS can be empty or "C++". If empty, "C" is assumed. +# +# There are several ways to do this, with various problems. +# +# [ gdb_compile -E $ifile -o $binfile.ci ] +# source $binfile.ci +# +# Single Unix Spec v3 says that "-E -o ..." together are not +# specified. And in fact, the native compiler on hp-ux 11 (among +# others) does not work with "-E -o ...". Most targets used to do +# this, and it mostly worked, because it works with gcc. +# +# [ catch "exec $compiler -E $ifile > $binfile.ci" exec_output ] +# source $binfile.ci +# +# This avoids the problem with -E and -o together. This almost works +# if the build machine is the same as the host machine, which is +# usually true of the targets which are not gcc. But this code does +# not figure which compiler to call, and it always ends up using the C +# compiler. Not good for setting hp_aCC_compiler. Targets +# hppa*-*-hpux* and mips*-*-irix* used to do this. +# +# [ gdb_compile -E $ifile > $binfile.ci ] +# source $binfile.ci +# +# dejagnu target_compile says that it supports output redirection, +# but the code is completely different from the normal path and I +# don't want to sweep the mines from that path. So I didn't even try +# this. +# +# set cppout [ gdb_compile $ifile "" preprocess $args quiet ] +# eval $cppout +# +# I actually do this for all targets now. gdb_compile runs the right +# compiler, and TCL captures the output, and I eval the output. +# +# Unfortunately, expect logs the output of the command as it goes by, +# and dejagnu helpfully prints a second copy of it right afterwards. +# So I turn off expect logging for a moment. +# +# [ gdb_compile $ifile $ciexe_file executable $args ] +# [ remote_exec $ciexe_file ] +# [ source $ci_file.out ] +# +# I could give up on -E and just do this. +# I didn't get desperate enough to try this. +# +# -- chastain 2004-01-06 proc get_compiler_info {binfile args} { - # Create and source the file that provides information about the compiler - # used to compile the test case. - # Compiler_type can be null or c++. If null we assume c. + # For compiler.c and compiler.cc global srcdir - global subdir - # These two come from compiler.c. - global signed_keyword_not_used - global gcc_compiled + + # I am going to play with the log to keep noise out. + global outdir + global tool + + # These come from compiler.c or compiler.cc global compiler_info + global gcc_compiled + global hp_cc_compiler + global hp_aCC_compiler + global signed_keyword_not_used - if {![istarget "hppa*-*-hpux*"] && ![istarget "mips*-*-irix*"]} { - if { [llength $args] > 0 } { - if {$args == "c++"} { - if { [gdb_compile "${srcdir}/lib/compiler.cc" "${binfile}.ci" preprocess {}] != "" } { - perror "Couldn't make ${binfile}.ci file" - return 1; - } - } - } else { - if { [gdb_compile "${srcdir}/lib/compiler.c" "${binfile}.ci" preprocess {}] != "" } { - perror "Couldn't make ${binfile}.ci file" - return 1; - } - } - } else { - if { [llength $args] > 0 } { - if {$args == "c++"} { - if { [eval gdb_preprocess \ - [list "${srcdir}/lib/compiler.cc" "${binfile}.ci"] \ - $args] != "" } { - perror "Couldn't make ${binfile}.ci file" - return 1; - } - } - } elseif { $args != "f77" } { - if { [eval gdb_preprocess \ - [list "${srcdir}/lib/compiler.c" "${binfile}.ci"] \ - $args] != "" } { - perror "Couldn't make ${binfile}.ci file" - return 1; - } - } + # Choose which file to preprocess. + set ifile "${srcdir}/lib/compiler.c" + if { [llength $args] > 0 && [lindex $args 0] == "c++" } { + set ifile "${srcdir}/lib/compiler.cc" } - - uplevel \#0 { set gcc_compiled 0 } - if { [llength $args] == 0 || $args != "f77" } { - source ${binfile}.ci + # Run $ifile through the right preprocessor. + # Toggle gdb.log to keep the compiler output out of the log. + log_file + set cppout [ gdb_compile "${ifile}" "" preprocess [list "$args" quiet] ] + log_file -a "$outdir/$tool.log" + + # Source the output. + foreach cppline [ split "$cppout" "\n" ] { + if { ! [ regexp "^#" "$cppline" ] } { + if { ! [ regexp "^\[\n\r\t \]*$" "$cppline" ] } { + verbose "get_compiler_info: $cppline" 2 + eval "$cppline" + } + } } + verbose -log "get_compiler_info: $compiler_info" # Most compilers will evaluate comparisons and other boolean # operations to 0 or 1. uplevel \#0 { set true 1 } uplevel \#0 { set false 0 } - uplevel \#0 { set hp_cc_compiler 0 } - uplevel \#0 { set hp_aCC_compiler 0 } - uplevel \#0 { set hp_f77_compiler 0 } - uplevel \#0 { set hp_f90_compiler 0 } - if { !$gcc_compiled && [istarget "hppa*-*-hpux*"] } { - # Check for the HP compilers - set compiler [lindex [split [get_compiler $args] " "] 0] - catch "exec what $compiler" output - if [regexp ".*HP aC\\+\\+.*" $output] { - uplevel \#0 { set hp_aCC_compiler 1 } - # Use of aCC results in boolean results being displayed as - # "true" or "false" - uplevel \#0 { set true true } - uplevel \#0 { set false false } - } elseif [regexp ".*HP C Compiler.*" $output] { - uplevel \#0 { set hp_cc_compiler 1 } - } elseif [regexp ".*HP-UX f77.*" $output] { - uplevel \#0 { set hp_f77_compiler 1 } - } elseif [regexp ".*HP-UX f90.*" $output] { - uplevel \#0 { set hp_f90_compiler 1 } - } + # Use of aCC results in boolean results being displayed as + # "true" or "false" + if { $hp_aCC_compiler } { + uplevel \#0 { set true true } + uplevel \#0 { set false false } } return 0; @@ -1184,85 +1212,6 @@ proc test_compiler_info { compiler } { return [string match $compiler $compiler_info] } -proc get_compiler {args} { - global CC CC_FOR_TARGET CXX CXX_FOR_TARGET F77_FOR_TARGET - - if { [llength $args] == 0 - || ([llength $args] == 1 && [lindex $args 0] == "") } { - set which_compiler "c" - } else { - if { $args =="c++" } { - set which_compiler "c++" - } elseif { $args =="f77" } { - set which_compiler "f77" - } else { - perror "Unknown compiler type supplied to gdb_preprocess" - return "" - } - } - - if [info exists CC_FOR_TARGET] { - if {$which_compiler == "c"} { - set compiler $CC_FOR_TARGET - } - } - - if [info exists CXX_FOR_TARGET] { - if {$which_compiler == "c++"} { - set compiler $CXX_FOR_TARGET - } - } - - if [info exists F77_FOR_TARGET] { - if {$which_compiler == "f77"} { - set compiler $F77_FOR_TARGET - } - } - - if { ![info exists compiler] } { - if { $which_compiler == "c" } { - if {[info exists CC]} { - set compiler $CC - } - } - if { $which_compiler == "c++" } { - if {[info exists CXX]} { - set compiler $CXX - } - } - if {![info exists compiler]} { - set compiler [board_info [target_info name] compiler]; - if { $compiler == "" } { - perror "get_compiler: No compiler found" - return "" - } - } - } - - return $compiler -} - -proc gdb_preprocess {source dest args} { - set compiler [get_compiler "$args"] - if { $compiler == "" } { - return 1 - } - - set cmdline "$compiler -E $source > $dest" - - verbose "Invoking $compiler -E $source > $dest" - verbose -log "Executing on local host: $cmdline" 2 - set status [catch "exec ${cmdline}" exec_output] - - set result [prune_warnings $exec_output] - regsub "\[\r\n\]*$" "$result" "" result; - regsub "^\[\r\n\]*" "$result" "" result; - if { $result != "" } { - clone_output "gdb compile failed, $result" - } - return $result; -} - set gdb_wrapper_initialized 0 proc gdb_wrapper_init { args } { @@ -1918,3 +1867,87 @@ proc gdb_skip_bogus_test { msg } { return 0; } + +# Note: the procedure gdb_gnu_strip_debug will produce an executable called +# ${binfile}.dbglnk, which is just like the executable ($binfile) but without +# the debuginfo. Instead $binfile has a .gnu_debuglink section which contains +# the name of a idebuginfo only file. This file will be stored in the +# gdb.base/.debug subdirectory. + +# Functions for separate debug info testing + +# starting with an executable: +# foo --> original executable + +# at the end of the process we have: +# foo.stripped --> foo w/o debug info +# .debug/foo.debug --> foo's debug info +# foo --> like foo, but with a new .gnu_debuglink section pointing to foo.debug. + +# Return the name of the file in which we should stor EXEC's separated +# debug info. EXEC contains the full path. +proc separate_debug_filename { exec } { + + # In a .debug subdirectory off the same directory where the testcase + # executable is going to be. Something like: + # <your-path>/gdb/testsuite/gdb.base/.debug/blah.debug. + # This is the default location where gdb expects to findi + # the debug info file. + + set exec_dir [file dirname $exec] + set exec_file [file tail $exec] + set debug_dir [file join $exec_dir ".debug"] + set debug_file [file join $debug_dir "${exec_file}.debug"] + + return $debug_file +} + + +proc gdb_gnu_strip_debug { dest } { + + set debug_file [separate_debug_filename $dest] + set strip_to_file_program strip + set objcopy_program objcopy + + # Make sure the directory that will hold the separated debug + # info actually exists. + set debug_dir [file dirname $debug_file] + if {! [file isdirectory $debug_dir]} { + file mkdir $debug_dir + } + + set debug_link [file tail $debug_file] + set stripped_file "${dest}.stripped" + + # Get rid of the debug info, and store result in stripped_file + # something like gdb/testsuite/gdb.base/blah.stripped. + set result [catch "exec $strip_to_file_program --strip-debug ${dest} -o ${stripped_file}" output] + verbose "result is $result" + verbose "output is $output" + if {$result == 1} { + return 1 + } + + # Get rid of everything but the debug info, and store result in debug_file + # This will be in the .debug subdirectory, see above. + set result [catch "exec $strip_to_file_program --only-keep-debug ${dest} -o ${debug_file}" output] + verbose "result is $result" + verbose "output is $output" + if {$result == 1} { + return 1 + } + + # Link the two previous output files together, adding the .gnu_debuglink + # section to the stripped_file, containing a pointer to the debug_file, + # save the new file in dest. + # This will be the regular executable filename, in the usual location. + set result [catch "exec $objcopy_program --add-gnu-debuglink=${debug_file} ${stripped_file} ${dest}" output] + verbose "result is $result" + verbose "output is $output" + if {$result == 1} { + return 1 + } + + return 0 +} + diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp index 4239a37..29a4f76 100644 --- a/gdb/testsuite/lib/mi-support.exp +++ b/gdb/testsuite/lib/mi-support.exp @@ -1,4 +1,4 @@ -# Copyright 1999, 2000, 2002 Free Software Foundation, Inc. +# Copyright 1999, 2000, 2002, 2003, 2004 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 @@ -281,35 +281,94 @@ proc mi_gdb_reinitialize_dir { subdir } { } } +# Send GDB the "target" command. +# FIXME: Some of these patterns are not appropriate for MI. Based on +# config/monitor.exp:gdb_target_command. +proc mi_gdb_target_cmd { targetname serialport } { + global mi_gdb_prompt + + for {set i 1} {$i <= 3} {incr i} { + send_gdb "47-target-select $targetname $serialport\n" + gdb_expect 60 { + -re "47\\^connected.*$mi_gdb_prompt$" { + verbose "Set target to $targetname"; + return 0; + } + -re "Couldn't establish connection to remote.*$mi_gdb_prompt$" { + verbose "Connection failed"; + } + -re "Remote MIPS debugging.*$mi_gdb_prompt$" { + verbose "Set target to $targetname"; + return 0; + } + -re "Remote debugging using .*$serialport.*$mi_gdb_prompt$" { + verbose "Set target to $targetname"; + return 0; + } + -re "Remote target $targetname connected to.*$mi_gdb_prompt$" { + verbose "Set target to $targetname"; + return 0; + } + -re "Connected to.*$mi_gdb_prompt$" { + verbose "Set target to $targetname"; + return 0; + } + -re "Ending remote.*$mi_gdb_prompt$" { } + -re "Connection refused.*$mi_gdb_prompt$" { + verbose "Connection refused by remote target. Pausing, and trying again." + sleep 5 + continue + } + -re "Timeout reading from remote system.*$mi_gdb_prompt$" { + verbose "Got timeout error from gdb."; + } + timeout { + send_gdb ""; + break + } + } + } + return 1 +} + # -# load a file into the debugger. +# load a file into the debugger (file command only). # return a -1 if anything goes wrong. # -proc mi_gdb_load { arg } { +proc mi_gdb_file_cmd { arg } { global verbose global loadpath global loadfile global GDB global mi_gdb_prompt global last_mi_gdb_file + global last_mi_remote_file upvar timeout timeout if { $arg == "" } { set arg $last_mi_gdb_file; + } else { + set last_mi_gdb_file $arg + if { [ info exists last_mi_remote_file ] } { + unset last_mi_remote_file + } } - set last_mi_gdb_file $arg; - - # ``gdb_unload'' + if [is_remote host] { + set arg [remote_download host $arg]; + if { $arg == "" } { + error "download failed" + return -1; + } + } - # ``gdb_file_cmd'' # FIXME: Several of these patterns are only acceptable for console # output. Queries are an error for mi. send_gdb "105-file-exec-and-symbols $arg\n" gdb_expect 120 { -re "Reading symbols from.*done.*$mi_gdb_prompt$" { verbose "\t\tLoaded $arg into the $GDB" - # All OK + return 0 } -re "has no symbol-table.*$mi_gdb_prompt$" { perror "$arg wasn't compiled with \"-g\"" @@ -338,14 +397,15 @@ proc mi_gdb_load { arg } { return -1 } -re "105-file-exec-and-symbols .*\r\n105\\\^done\r\n$mi_gdb_prompt$" { - # We are just giving the prompt back for now - # All OK - } + # We (MI) are just giving the prompt back for now, instead of giving + # some acknowledgement. + return 0 + } timeout { perror "couldn't load $arg into $GDB (timed out)." return -1 } - eof { + eof { # This is an attempt to detect a core dump, but seems not to # work. Perhaps we need to match .* followed by eof, in which # gdb_expect does not seem to have a way to do that. @@ -353,9 +413,46 @@ proc mi_gdb_load { arg } { return -1 } } - +} + +# +# load a file into the debugger. +# return a -1 if anything goes wrong. +# +proc mi_gdb_load { arg } { + global verbose + global loadpath + global loadfile + global GDB + global mi_gdb_prompt + upvar timeout timeout + + # ``gdb_unload'' + if { $arg != "" } { + mi_gdb_file_cmd $arg + } + # ``load'' - if { [info procs send_target_sid] != "" } { + if { [info procs gdbserver_gdb_load] != "" } { + global last_mi_gdb_file + global last_mi_remote_file + + if { ! [info exists last_mi_remote_file] } { + if [is_remote target] { + set last_mi_remote_file [remote_download target $arg] + } else { + set last_mi_remote_file $last_mi_gdb_file + } + } + + set res [gdbserver_gdb_load $last_mi_remote_file] + set protocol [lindex $res 0] + set gdbport [lindex $res 1] + + if { [mi_gdb_target_cmd $protocol $gdbport] != 0 } { + return -1 + } + } elseif { [info procs send_target_sid] != "" } { # For SID, things get complex send_target_sid gdb_expect 60 { |