From 887e71588b295a4d4f4bd7480b1a8c8507dfddb8 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 14 May 2021 19:54:35 -0600 Subject: [PATCH] Fix Python pretty-printing bug in Rust An upstream Rust bug notes notes that the Python pretty-printing feature is broken for values that appear as members of certain types in Rust. The bug here is that some of the Rust value-printing code calls value_print_inner, a method on rust_language. This bypasses the common code that calls into Python. I'm checking this in. gdb/ChangeLog 2021-05-14 Tom Tromey * rust-lang.c (rust_language::val_print_struct) (rust_language::print_enum): Use common_val_print, not value_print_inner. gdb/testsuite/ChangeLog 2021-05-14 Tom Tromey * gdb.rust/pp.exp: New file. * gdb.rust/pp.py: New file. * gdb.rust/pp.rs: New file. --- gdb/ChangeLog | 6 +++++ gdb/rust-lang.c | 6 +++-- gdb/testsuite/ChangeLog | 6 +++++ gdb/testsuite/gdb.rust/pp.exp | 42 ++++++++++++++++++++++++++++++ gdb/testsuite/gdb.rust/pp.py | 49 +++++++++++++++++++++++++++++++++++ gdb/testsuite/gdb.rust/pp.rs | 26 +++++++++++++++++++ 6 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 gdb/testsuite/gdb.rust/pp.exp create mode 100644 gdb/testsuite/gdb.rust/pp.py create mode 100644 gdb/testsuite/gdb.rust/pp.rs diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d44b06d9559..8e1e00250b8 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2021-05-14 Tom Tromey + + * rust-lang.c (rust_language::val_print_struct) + (rust_language::print_enum): Use common_val_print, not + value_print_inner. + 2021-05-14 Tankut Baris Aktemur * python/py-inferior.c (infpy_get_connection_num): New function. diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c index 8c4d209b07a..3b15bb22a27 100644 --- a/gdb/rust-lang.c +++ b/gdb/rust-lang.c @@ -386,7 +386,8 @@ rust_language::val_print_struct fputs_filtered (": ", stream); } - value_print_inner (value_field (val, i), stream, recurse + 1, &opts); + common_val_print (value_field (val, i), stream, recurse + 1, &opts, + this); } if (options->prettyformat) @@ -464,7 +465,8 @@ rust_language::print_enum (struct value *val, struct ui_file *stream, styled_string (variable_name_style.style (), TYPE_FIELD_NAME (variant_type, j))); - value_print_inner (value_field (val, j), stream, recurse + 1, &opts); + common_val_print (value_field (val, j), stream, recurse + 1, &opts, + this); } if (is_tuple) diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index c723a9a0a8e..c7e7152eee0 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2021-05-14 Tom Tromey + + * gdb.rust/pp.exp: New file. + * gdb.rust/pp.py: New file. + * gdb.rust/pp.rs: New file. + 2021-05-14 Bernd Edlinger * gdb.base/index-cache.exp: Cleanup $cache_dir/*.gdb-index and diff --git a/gdb/testsuite/gdb.rust/pp.exp b/gdb/testsuite/gdb.rust/pp.exp new file mode 100644 index 00000000000..abe2168af69 --- /dev/null +++ b/gdb/testsuite/gdb.rust/pp.exp @@ -0,0 +1,42 @@ +# Copyright (C) 2021 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 . + +# Test expression parsing and evaluation that requires Rust compiler. + +load_lib gdb-python.exp +load_lib rust-support.exp +if {[skip_rust_tests]} { + continue +} + +standard_testfile .rs +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug rust}]} { + return -1 +} + +if { [skip_python_tests] } { continue } + +set remote_python_file [gdb_remote_download host \ + ${srcdir}/${subdir}/${testfile}.py] +gdb_test_no_output "source ${remote_python_file}" "load python file" + +set line [gdb_get_line_number "set breakpoint here"] +if {![runto ${srcfile}:$line]} { + untested "could not run to breakpoint" + return -1 +} + +gdb_test "print outer" " = pp::Outer \\(x\\(5\\)\\)" +gdb_test "print outer.0" " = x\\(5\\)" diff --git a/gdb/testsuite/gdb.rust/pp.py b/gdb/testsuite/gdb.rust/pp.py new file mode 100644 index 00000000000..57c8cc3fbf3 --- /dev/null +++ b/gdb/testsuite/gdb.rust/pp.py @@ -0,0 +1,49 @@ +# Copyright (C) 2021 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 . + +# This file is part of the GDB testsuite. It tests python pretty +# printers. + +import re +import gdb + + +# Printer for Inner. +class inner_print(object): + def __init__(self, val): + self.val = val + + def to_string(self): + return "x(" + str(self.val["x"]) + ")" + + +def lookup_function(val): + "Look-up and return a pretty-printer that can print val." + + # Get the type. + type = val.type + + # Get the type name. + typename = type.tag + + if typename == None: + return None + + if typename == "pp::Inner": + return inner_print(val) + return None + + +gdb.pretty_printers.append(lookup_function) diff --git a/gdb/testsuite/gdb.rust/pp.rs b/gdb/testsuite/gdb.rust/pp.rs new file mode 100644 index 00000000000..23e85afeba8 --- /dev/null +++ b/gdb/testsuite/gdb.rust/pp.rs @@ -0,0 +1,26 @@ +// Copyright (C) 2021 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 . + +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unused_assignments)] + +struct Inner{ x : u8 } +struct Outer(Inner); + +fn main () { + let outer = Outer(Inner{x: 5}); + println!("{}", outer.0.x); // set breakpoint here +} -- 2.30.2