mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-03 04:12:10 +08:00
ef7a6b977b
After this commit the gcc_compiled global is no longer exported from lib/gdb.exp. In theory we could switch over all uses of gcc_compiled to instead call test_compiler_info directly, however, I have instead added a new proc to gdb.exp: 'is_c_compiler_gcc'. I've then updated the testsuite to call this proc instead of using the global. Having a new proc specifically for this task means that we have a single consistent pattern for detecting gcc. By wrapping this logic within a proc that calls test_compiler_info, rather than using the global, means that test scripts don't need to call get_compiler_info before they read the global, simply calling the new proc does everything in one go. As a result I've been able to remove the get_compiler_info calls from all the test scripts that I've touched in this commit. In some of the tests e.g. gdb.dwarf2/*.exp, the $gcc_compiled flag was being checked at the top of the script to decide if the whole script should be skipped or not. In these cases I've called the new proc directly and removed all uses of gcc_compiled. In other cases, e.g. most of the gdb.base scripts, there were many uses of gcc_compiled. In these cases I set a new global gcc_compiled near the top of the script, and leave the rest of the script unchanged. There should be no changes in what is tested after this commit.
252 lines
7.5 KiB
Plaintext
252 lines
7.5 KiB
Plaintext
# Copyright 2020-2022 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/>.
|
|
|
|
# This test shows the importance of not corrupting the order of line
|
|
# table information. When multiple lines are given for the same
|
|
# address the compiler usually lists these in the order in which we
|
|
# would expect to encounter them. When stepping through nested inline
|
|
# frames the last line given for an address is assumed by GDB to be
|
|
# the most inner frame, and this is what GDB displays.
|
|
#
|
|
# If we corrupt the order of the line table entries then GDB will
|
|
# display the wrong line as being the inner most frame.
|
|
|
|
load_lib dwarf.exp
|
|
|
|
# This test can only be run on targets which support DWARF-2 and use gas.
|
|
if {![dwarf2_support]} {
|
|
return 0
|
|
}
|
|
|
|
# The .c files use __attribute__.
|
|
if ![is_c_compiler_gcc] {
|
|
return 0
|
|
}
|
|
|
|
standard_testfile .c .S
|
|
|
|
set asm_file [standard_output_file $srcfile2]
|
|
Dwarf::assemble $asm_file {
|
|
global srcdir subdir srcfile
|
|
declare_labels lines_label
|
|
|
|
get_func_info main
|
|
|
|
cu {} {
|
|
compile_unit {
|
|
{language @DW_LANG_C}
|
|
{name dw2-is-stmt.c}
|
|
{low_pc 0 addr}
|
|
{stmt_list ${lines_label} DW_FORM_sec_offset}
|
|
} {
|
|
subprogram {
|
|
{external 1 flag}
|
|
{name main}
|
|
{low_pc $main_start addr}
|
|
{high_pc "$main_start + $main_len" addr}
|
|
} {}
|
|
}
|
|
}
|
|
|
|
lines {version 2 default_is_stmt 0} lines_label {
|
|
include_dir "${srcdir}/${subdir}"
|
|
file_name "$srcfile" 1
|
|
|
|
program {
|
|
DW_LNE_set_address main
|
|
line [gdb_get_line_number "main prologue"]
|
|
DW_LNS_negate_stmt
|
|
DW_LNS_copy
|
|
|
|
DW_LNE_set_address line_label_1
|
|
line [gdb_get_line_number "main, set var to 99"]
|
|
DW_LNS_copy
|
|
|
|
DW_LNE_set_address line_label_2
|
|
line [gdb_get_line_number "main, set var to 0"]
|
|
DW_LNS_negate_stmt
|
|
DW_LNS_copy
|
|
|
|
DW_LNE_set_address line_label_3
|
|
DW_LNS_negate_stmt
|
|
DW_LNS_copy
|
|
|
|
DW_LNE_set_address line_label_4
|
|
DW_LNS_negate_stmt
|
|
DW_LNS_copy
|
|
|
|
DW_LNE_set_address line_label_5
|
|
line [gdb_get_line_number "main end"]
|
|
DW_LNS_negate_stmt
|
|
DW_LNS_copy
|
|
|
|
DW_LNE_set_address ${main_end}
|
|
DW_LNE_end_sequence
|
|
}
|
|
}
|
|
}
|
|
|
|
if { [prepare_for_testing "failed to prepare" ${testfile} \
|
|
[list $srcfile $asm_file] {nodebug}] } {
|
|
return -1
|
|
}
|
|
|
|
if ![runto_main] {
|
|
return -1
|
|
}
|
|
|
|
# First, break by address at a location we know is marked as not a
|
|
# statement. GDB should still correctly report the file and line
|
|
# number.
|
|
gdb_breakpoint "*line_label_2"
|
|
gdb_continue_to_breakpoint "*line_label_2"
|
|
|
|
# Now step by instruction. We should skip over the is-stmt location
|
|
# for this line, and land on the next source line.
|
|
gdb_test "step" "/\\* main end \\*/" \
|
|
"step to end from line_label_2"
|
|
|
|
# Restart the test. This time, stop at a location we know is marked
|
|
# as a statement.
|
|
clean_restart ${binfile}
|
|
runto_main
|
|
|
|
gdb_breakpoint "*line_label_3"
|
|
gdb_continue_to_breakpoint "*line_label_3"
|
|
|
|
# Now step by instruction. As you would expect we should leave this
|
|
# line and stop at the next source line.
|
|
gdb_test "step" "/\\* main end \\*/" \
|
|
"step to end from line_label_3"
|
|
|
|
# Restart the test, this time, step through line by line, ensure we
|
|
# only stop at the places where is-stmt is true.
|
|
clean_restart ${binfile}
|
|
runto_main
|
|
|
|
# Get the values of the labels where we expect to stop.
|
|
set ll1 [get_hexadecimal_valueof "&line_label_1" "INVALID"]
|
|
set ll2 [get_hexadecimal_valueof "&line_label_2" "INVALID"]
|
|
set ll3 [get_hexadecimal_valueof "&line_label_3" "INVALID"]
|
|
set ll5 [get_hexadecimal_valueof "&line_label_5" "INVALID"]
|
|
|
|
# The first stop should be at line_label_1
|
|
with_test_prefix "check we're at line_label_1" {
|
|
set pc [get_hexadecimal_valueof "\$pc" "NO-PC"]
|
|
gdb_assert { $ll1 == $pc } "check initial \$pc is line_label_1"
|
|
}
|
|
|
|
# Now step, this should take us to line_label_3 which is the next
|
|
# location marked as is-stmt.
|
|
with_test_prefix "step to line_label_3" {
|
|
gdb_test "step" "/\\* main, set var to 0 \\*/"
|
|
set pc [get_hexadecimal_valueof "\$pc" "NO-PC"]
|
|
gdb_assert { $ll3 == $pc } "check initial \$pc is line_label_3"
|
|
}
|
|
|
|
# A final step should take us to line_label_5.
|
|
with_test_prefix "step to line_label_5" {
|
|
gdb_test "step" "/\\* main end \\*/"
|
|
set pc [get_hexadecimal_valueof "\$pc" "NO-PC"]
|
|
gdb_assert { $ll5 == $pc } "check initial \$pc"
|
|
}
|
|
|
|
# Now restart the test, and place a breakpoint by line number. GDB
|
|
# should select the location that is marked as is-stmt.
|
|
clean_restart ${binfile}
|
|
runto_main
|
|
set linum [gdb_get_line_number "main, set var to 0"]
|
|
gdb_breakpoint "$srcfile:$linum"
|
|
gdb_continue_to_breakpoint "Breakpoint on line, set var to 0"
|
|
set pc [get_hexadecimal_valueof "\$pc" "NO-PC"]
|
|
gdb_assert { $ll3 == $pc } "check initial \$pc"
|
|
|
|
# Restart the test again, this time we will test stepping by
|
|
# instruction.
|
|
clean_restart ${binfile}
|
|
runto_main
|
|
|
|
# We will be at line_label_1 at this point - we already tested this
|
|
# above. Now single instruction step forward until we get to
|
|
# line_label_2. Every instruction before line_label_2 should be
|
|
# attributed to the 'var = 99' line. For most targets there will only
|
|
# be a single instruction between line_label_1 and line_label_2, but
|
|
# we allow for up to 25 (just a random number).
|
|
|
|
with_test_prefix "stepi until line_label_2" {
|
|
set i 0
|
|
set pc [get_hexadecimal_valueof "\$pc" "NO-PC" \
|
|
"get pc before stepi loop at line_label_1"]
|
|
while { $pc < $ll2 } {
|
|
incr i
|
|
with_test_prefix $i {
|
|
set line_changed -1
|
|
gdb_test_multiple "stepi" "stepi until line_label_2" {
|
|
-re "main, set var to 99.*$gdb_prompt" {
|
|
set line_changed 0
|
|
}
|
|
-re "main, set var to 0.*$gdb_prompt " {
|
|
set line_changed 1
|
|
}
|
|
}
|
|
gdb_assert { $line_changed != -1 } \
|
|
"ensure we saw a valid line pattern"
|
|
set pc [get_hexadecimal_valueof "\$pc" "NO-PC" \
|
|
"get pc inside stepi loop from line_label_1"]
|
|
if { $ll2 == $pc } {
|
|
gdb_assert { $line_changed } \
|
|
"line must change at line_label_2"
|
|
} else {
|
|
gdb_assert { !$line_changed } \
|
|
"line should not change until line_label_2"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Now single instruction step forward until GDB reports a new source
|
|
# line, at which point we should be at line_label_5.
|
|
|
|
with_test_prefix "stepi until line_label_5" {
|
|
set i 0
|
|
set pc [get_hexadecimal_valueof "\$pc" "NO-PC" \
|
|
"get pc before stepi loop at line_label_2"]
|
|
while { $pc < $ll5 } {
|
|
incr i
|
|
with_test_prefix $i {
|
|
set line_changed -1
|
|
gdb_test_multiple "stepi" "stepi until line_label_5" {
|
|
-re "main, set var to 0.*$gdb_prompt" {
|
|
set line_changed 0
|
|
}
|
|
-re "main end.*$gdb_prompt " {
|
|
set line_changed 1
|
|
}
|
|
}
|
|
gdb_assert { $line_changed != -1 } \
|
|
"ensure we saw a valid line pattern"
|
|
set pc [get_hexadecimal_valueof "\$pc" "NO-PC" \
|
|
"get pc inside stepi loop from line_label_2"]
|
|
if { $ll5 == $pc } {
|
|
gdb_assert { $line_changed } \
|
|
"line must change at line_label_5"
|
|
} else {
|
|
gdb_assert { !$line_changed } \
|
|
"line should not change until line_label_5"
|
|
}
|
|
}
|
|
}
|
|
}
|