forked from Imagelibrary/binutils-gdb
This updates the copyright headers to include 2025. I did this by running gdb/copyright.py and then manually modifying a few files as noted by the script. Approved-By: Eli Zaretskii <eliz@gnu.org>
229 lines
7.2 KiB
Plaintext
229 lines
7.2 KiB
Plaintext
# Copyright (C) 2024-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 the 'maint info inline-frames' and 'maint info blocks'
|
|
# commands.
|
|
|
|
standard_testfile
|
|
|
|
if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \
|
|
{debug nopie}]} {
|
|
return -1
|
|
}
|
|
|
|
if {![runto normal_func]} {
|
|
return 0
|
|
}
|
|
|
|
# Make a pattern to match 'maint info blocks' output. ARGS is the
|
|
# list of function names we expect to see. If the function name
|
|
# starts with 'inline_func' then we expect to see an inline block,
|
|
# otherwise blocks are not expected to be inline.
|
|
proc make_blocks_result { args } {
|
|
set result \
|
|
[list \
|
|
"Blocks at $::hex:" \
|
|
" from objfile: \\\[\\(objfile \\*\\) $::hex\\\] [string_to_regexp $::binfile]" \
|
|
""\
|
|
"\\\[\\(block \\*\\) $::hex\\\] $::hex\\.\\.$::hex" \
|
|
" entry pc: $::hex" \
|
|
" is global block" \
|
|
".*" \
|
|
"\\\[\\(block \\*\\) $::hex\\\] $::hex\\.\\.$::hex" \
|
|
" entry pc: $::hex" \
|
|
" is static block" \
|
|
".*" ]
|
|
|
|
foreach func $args {
|
|
lappend result \
|
|
"\\\[\\(block \\*\\) $::hex\\\] $::hex\\.\\.$::hex" \
|
|
" entry pc: $::hex"
|
|
|
|
if { [string range $func 0 10] eq "inline_func" } {
|
|
lappend result" inline function: $func"
|
|
} else {
|
|
lappend result" function: $func"
|
|
}
|
|
|
|
lappend result ".*"
|
|
}
|
|
|
|
return [multi_line {*}$result]
|
|
}
|
|
|
|
gdb_test "maint info blocks" [make_blocks_result normal_func] \
|
|
"maint info blocks in normal_func only"
|
|
|
|
# Next forward until we find the call to inline_func_a(). The hope is
|
|
# that when we see the 'inline_func_a()' line this will be the start of
|
|
# the inlined function. This might not be the case on all
|
|
# architectures if the compiler needs to perform some preamble.
|
|
gdb_test_multiple "next" "next forward to inline_func_a" {
|
|
-re "^$decimal\\s+inline_func_a \\(\\);\r\n" {
|
|
# Consume the next prompt.
|
|
gdb_expect {
|
|
-re "^$gdb_prompt $" {}
|
|
}
|
|
pass $gdb_test_name
|
|
}
|
|
|
|
-re "^$decimal\\s+\[^\r\n\]+After inline function\[^\r\n\]+\r\n" {
|
|
# We've gone too far!
|
|
fail $gdb_test_name
|
|
}
|
|
|
|
-re "^$decimal\\s+\[^\r\n\]+\r\n" {
|
|
send_gdb "next\n"
|
|
exp_continue
|
|
}
|
|
|
|
-re "^\[^\r\n\]+\r\n" {
|
|
exp_continue
|
|
}
|
|
}
|
|
|
|
gdb_test "maint info blocks" [make_blocks_result normal_func \
|
|
inline_func_a inline_func_b] \
|
|
"maint info blocks when all blocks visible"
|
|
|
|
# View the inline frame information. This should display that we are
|
|
# at the start of inline_func_a() within normal_func().
|
|
gdb_test "maint info inline-frames" \
|
|
[multi_line \
|
|
"^Cached inline state information for thread $decimal\\." \
|
|
"program counter = $hex" \
|
|
"skipped frames = 2" \
|
|
" inline_func_b" \
|
|
" inline_func_a" \
|
|
"> normal_func"] \
|
|
"check inline-frames state when in normal_func"
|
|
|
|
# Step, we should now enter the inlined function.
|
|
gdb_test "step" ".*" \
|
|
"step to enter inline_func"
|
|
|
|
# And the inline-frames information should update.
|
|
gdb_test "maint info inline-frames" \
|
|
[multi_line \
|
|
"^Cached inline state information for thread $decimal\\." \
|
|
"program counter = $hex" \
|
|
"skipped frames = 1" \
|
|
" inline_func_b" \
|
|
"> inline_func_a" \
|
|
" normal_func"] \
|
|
"check inline-frames state when just entered inline_func_a"
|
|
|
|
# Record the current program counter.
|
|
set pc [get_hexadecimal_valueof "\$pc" "UNKNOWN"]
|
|
|
|
# Use the recorded $pc value to check inline frames.
|
|
gdb_test "maint info inline-frames $pc" \
|
|
[multi_line \
|
|
"^program counter = $hex" \
|
|
"skipped frames = 2" \
|
|
" inline_func_b" \
|
|
" inline_func_a" \
|
|
"> normal_func"] \
|
|
"check inline-frames state at recorded \$pc while at the \$pc"
|
|
|
|
# Step again, we should now enter inlined_func_b().
|
|
gdb_test "step" ".*" \
|
|
"step into inline_func_b"
|
|
|
|
gdb_test "maint info inline-frames" \
|
|
[multi_line \
|
|
"^Cached inline state information for thread $decimal\\." \
|
|
"program counter = $hex" \
|
|
"skipped frames = 0" \
|
|
"> inline_func_b" \
|
|
" inline_func_a" \
|
|
" normal_func"] \
|
|
"check inline-frames state when just entered inline_func_b"
|
|
|
|
gdb_test "maint info blocks" [make_blocks_result normal_func \
|
|
inline_func_a inline_func_b] \
|
|
"maint info blocks when all blocks still visible"
|
|
|
|
gdb_test "step" ".*" \
|
|
"step into the body of inline_func_b"
|
|
|
|
# Now we are no longer at the start of the inlined function we should
|
|
# no longer see normal_func() in the inline-frames information.
|
|
gdb_test "maint info inline-frames" \
|
|
[multi_line \
|
|
"^Cached inline state information for thread $decimal\\." \
|
|
"program counter = $hex" \
|
|
"skipped frames = 0" \
|
|
"> inline_func_b"] \
|
|
"check inline-frames state when within inline_func_b"
|
|
|
|
gdb_test "maint info blocks" [make_blocks_result normal_func \
|
|
inline_func_a inline_func_b] \
|
|
"maint info blocks within inline function, all blocks still visible"
|
|
|
|
# Use 'stepi' and check 'maint info inline-frames' still works.
|
|
gdb_test "stepi" ".*" "perform stepi"
|
|
gdb_test "maint info inline-frames" \
|
|
[multi_line \
|
|
"^Inline state information for thread $decimal\\." \
|
|
"program counter = $hex" \
|
|
"skipped frames = 0" \
|
|
"> inline_func_b"] \
|
|
"check inline-frames state when within inline_func_b after stepi"
|
|
|
|
gdb_test "maint info blocks" [make_blocks_result normal_func \
|
|
inline_func_a inline_func_b] \
|
|
"maint info blocks within inline function after stepi, all blocks still visible"
|
|
|
|
# Use the recorded $pc value to check inline frames.
|
|
gdb_test "maint info inline-frames $pc" \
|
|
[multi_line \
|
|
"^program counter = $hex" \
|
|
"skipped frames = 2" \
|
|
" inline_func_b" \
|
|
" inline_func_a" \
|
|
"> normal_func"] \
|
|
"check inline-frames state at recorded \$pc"
|
|
|
|
gdb_test "maint info blocks" [make_blocks_result normal_func \
|
|
inline_func_a inline_func_b] \
|
|
"maint info blocks using stored \$pc, inferior still running"
|
|
|
|
clean_restart $binfile
|
|
|
|
# Use the recorded $pc value to check inline frames when the inferior
|
|
# is not executing.
|
|
gdb_test "maint info inline-frames $pc" \
|
|
[multi_line \
|
|
"^program counter = $hex" \
|
|
"skipped frames = 2" \
|
|
" inline_func_b" \
|
|
" inline_func_a" \
|
|
"> normal_func"] \
|
|
"check inline-frames state at recorded \$pc before execution starts"
|
|
|
|
gdb_test "maint info blocks $pc" [make_blocks_result normal_func \
|
|
inline_func_a inline_func_b] \
|
|
"maint info blocks using stored \$pc, inferior not running"
|
|
|
|
# Trying to read the $pc from the current thread should fail if the
|
|
# inferior is not yet running.
|
|
gdb_test "maint info inline-frames" \
|
|
"^no inferior thread" \
|
|
"check inline-frames state of current thread before execution starts"
|
|
|
|
gdb_test "maint info blocks" "^no inferior thread" \
|
|
"maint info blocks with no \$pc and inferior not running"
|