aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.rust
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2017-07-06 06:44:38 -0600
committerTom Tromey <tom@tromey.com>2017-11-17 14:34:14 -0700
commit71a3c36949407eafea744bf00334c4e0c136f927 (patch)
tree2449b4419ef190f549e5bd0f4bbc1c210b67076f /gdb/testsuite/gdb.rust
parent7468702dcb37013edbbbc62e247e23c4b2632379 (diff)
downloadgdb-71a3c36949407eafea744bf00334c4e0c136f927.zip
gdb-71a3c36949407eafea744bf00334c4e0c136f927.tar.gz
gdb-71a3c36949407eafea744bf00334c4e0c136f927.tar.bz2
Handle dereferencing Rust trait objects
In Rust, virtual tables work a bit differently than they do in C++. In C++, as you know, they are connected to a particular class hierarchy. Rust, instead, can generate a virtual table for potentially any type -- in fact, one such virtual table for each trait (a trait is similar to an abstract class or to a Java interface) that a type implements. Objects that are referenced via a trait can't currently be inspected by gdb. This patch implements the Rust equivalent of "set print object". gdb relies heavily on the C++ ABI to decode virtual tables; primarily to make "set print object" work; but also "info vtbl". However, Rust does not currently have a specified ABI, so this approach seems unwise to emulate. Instead, I've changed the Rust compiler to emit some DWARF that describes trait objects (previously their internal structure was opaque), vtables (currently just a size -- but I hope to expand this in the future), and the concrete type for which a vtable was emitted. The concrete type is expressed as a DW_AT_containing_type on the vtable's type. This is a small extension to DWARF. This patch adds a new entry to quick_symbol_functions to return the symtab that holds a data address. Previously there was no way in gdb to look up a full (only minimal) non-text symbol by address. The psymbol implementation of this method works by lazily filling in a map that is added to the objfile. This avoids slowing down psymbol reading for a feature that is likely to not be used too frequently. I did not update .gdb_index. My thinking here is that the DWARF 5 indices will obsolete .gdb_index soon-ish, meaning that adding a new feature to them is probably wasted work. If necessary I can update the DWARF 5 index code when it lands in gdb. Regression tested on x86-64 Fedora 25. 2017-11-17 Tom Tromey <tom@tromey.com> * symtab.h (struct symbol) <is_rust_vtable>: New member. (struct rust_vtable_symbol): New. (find_symbol_at_address): Declare. * symtab.c (find_symbol_at_address): New function. * symfile.h (struct quick_symbol_functions) <find_compunit_symtab_by_address>: New member. * symfile-debug.c (debug_qf_find_compunit_symtab_by_address): New function. (debug_sym_quick_functions): Link to debug_qf_find_compunit_symtab_by_address. * rust-lang.c (rust_get_trait_object_pointer): New function. (rust_evaluate_subexp) <case UNOP_IND>: New case. Call rust_get_trait_object_pointer. * psymtab.c (psym_relocate): Clear psymbol_map. (psym_fill_psymbol_map, psym_find_compunit_symtab_by_address): New functions. (psym_functions): Link to psym_find_compunit_symtab_by_address. * objfiles.h (struct objfile) <psymbol_map>: New member. * dwarf2read.c (dwarf2_gdb_index_functions): Update. (process_die) <DW_TAG_variable>: New case. Call read_variable. (rust_containing_type, read_variable): New functions. 2017-11-17 Tom Tromey <tom@tromey.com> * gdb.rust/traits.rs: New file. * gdb.rust/traits.exp: New file.
Diffstat (limited to 'gdb/testsuite/gdb.rust')
-rw-r--r--gdb/testsuite/gdb.rust/traits.exp47
-rw-r--r--gdb/testsuite/gdb.rust/traits.rs37
2 files changed, 84 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.rust/traits.exp b/gdb/testsuite/gdb.rust/traits.exp
new file mode 100644
index 0000000..26686ef
--- /dev/null
+++ b/gdb/testsuite/gdb.rust/traits.exp
@@ -0,0 +1,47 @@
+# Copyright (C) 2017 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/>.
+
+# Test trait object printing.
+
+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
+}
+
+set readelf_program [gdb_find_readelf]
+set result [catch "exec $readelf_program --debug-dump=info $binfile" output]
+if {$result != 0} {
+ untested "could not read ${binfile} with readelf"
+ return
+}
+
+if {![regexp DW_AT_containing_type $output]} {
+ untested "Rust compiler did not emit DW_AT_containing_type"
+ return
+}
+
+set line [gdb_get_line_number "set breakpoint here"]
+if {![runto ${srcfile}:$line]} {
+ untested "could not run to breakpoint"
+ return -1
+}
+
+gdb_test "print *td" " = 23.5"
+gdb_test "print *tu" " = 23"
diff --git a/gdb/testsuite/gdb.rust/traits.rs b/gdb/testsuite/gdb.rust/traits.rs
new file mode 100644
index 0000000..98f841b
--- /dev/null
+++ b/gdb/testsuite/gdb.rust/traits.rs
@@ -0,0 +1,37 @@
+// Copyright (C) 2017 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/>.
+
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+
+pub trait T {
+}
+
+impl T for f64 {
+}
+
+impl T for u8 {
+}
+
+pub fn main() {
+ let d = 23.5f64;
+ let u = 23u8;
+
+ let td = &d as &T;
+ let tu = &u as &T;
+
+ println!(""); // set breakpoint here
+}