diff options
Diffstat (limited to 'gdb/testsuite/gdb.base')
-rw-r--r-- | gdb/testsuite/gdb.base/frame-view.c | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/frame-view.exp | 46 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/frame-view.py | 41 |
3 files changed, 89 insertions, 4 deletions
diff --git a/gdb/testsuite/gdb.base/frame-view.c b/gdb/testsuite/gdb.base/frame-view.c index 7b1cbd6..e330da0 100644 --- a/gdb/testsuite/gdb.base/frame-view.c +++ b/gdb/testsuite/gdb.base/frame-view.c @@ -28,6 +28,12 @@ struct type_2 int n; }; +__attribute__((used)) static int +called_from_pretty_printer (void) +{ + return 23; +} + static int baz (struct type_1 z1, struct type_2 z2) { diff --git a/gdb/testsuite/gdb.base/frame-view.exp b/gdb/testsuite/gdb.base/frame-view.exp index d2dba14..edae167 100644 --- a/gdb/testsuite/gdb.base/frame-view.exp +++ b/gdb/testsuite/gdb.base/frame-view.exp @@ -22,13 +22,28 @@ if { [build_executable "failed to prepare" \ return } -proc test_select_frame_view {} { +# If WITH_PRETTY_PRINTER is true, load pretty printers for the function +# parameter types, in which we do an inferior call. This is meant to test +# that the frame_info_ptr correctly reinflates frames created using +# "select-frame view". + +proc test_select_frame_view { with_pretty_printer } { clean_restart $::binfile + if { $with_pretty_printer } { + require allow_python_tests + } + if { ![runto_main] } { return } + if { $with_pretty_printer } { + set remote_python_file \ + [gdb_remote_download host "${::srcdir}/${::subdir}/${::testfile}.py"] + gdb_test_no_output "source ${remote_python_file}" "load python file" + } + # Stop thread 2 at a baz. gdb_test "break baz" gdb_test "continue" "Thread 2.*hit Breakpoint $::decimal, baz .*" @@ -60,11 +75,34 @@ proc test_select_frame_view {} { gdb_test "thread 1" "Switching to thread 1 .*" gdb_test_no_output "select-frame view $frame_sp $frame_pc" + if { $with_pretty_printer } { + # When the pretty printer does its infcall, it is done on the currently + # selected thread, thread 1 here. However, other threads are resumed + # at the same time. This causes thread 2 to exit during that infcall, + # leading to this weirdness: + # + # frame^M + # #0 baz (z=[Thread 0x7ffff7cc26c0 (LWP 417519) exited]^M + # hohoho) at /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/frame-view.c:35^M + # 35 return z.n + 2;^M + # + # Avoid that by setting scheduler-locking on. + gdb_test_no_output "set scheduler-locking on" + + set z1_pattern "hahaha" + set z2_pattern "hohoho" + } else { + set z1_pattern "\\.\\.\\." + set z2_pattern "\\.\\.\\." + } + # Verify that the "frame" command does not change the selected frame. # There used to be a bug where the "frame" command would lose the # selection of user-created frames. - gdb_test "frame" "#0 baz \\(z1=.*, z2=.*\\).*" "frame" - gdb_test "frame" "#0 baz \\(z1=.*, z2=.*\\).*" "frame again" + gdb_test "frame" "#0 baz \\(z1=$z1_pattern, z2=$z2_pattern\\).*" "frame" + gdb_test "frame" "#0 baz \\(z1=$z1_pattern, z2=$z2_pattern\\).*" "frame again" } -test_select_frame_view +foreach_with_prefix with_pretty_printer {false true} { + test_select_frame_view $with_pretty_printer +} diff --git a/gdb/testsuite/gdb.base/frame-view.py b/gdb/testsuite/gdb.base/frame-view.py new file mode 100644 index 0000000..6c1b8bc --- /dev/null +++ b/gdb/testsuite/gdb.base/frame-view.py @@ -0,0 +1,41 @@ +# Copyright (C) 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/>. + + +class Printer1: + def to_string(self): + n = gdb.parse_and_eval("called_from_pretty_printer ()") + assert n == 23 + return "hahaha" + + +class Printer2: + def to_string(self): + n = gdb.parse_and_eval("called_from_pretty_printer ()") + assert n == 23 + return "hohoho" + + +def lookup_function(val): + if str(val.type) == "struct type_1": + return Printer1() + + if str(val.type) == "struct type_2": + return Printer2() + + return None + + +gdb.pretty_printers.append(lookup_function) |