From 33590be3ac8403a9a74742c3c9d7461606a85ba5 Mon Sep 17 00:00:00 2001 From: Keith Seitz Date: Fri, 31 Mar 2023 11:59:44 -0700 Subject: [PATCH] Backport "Fix crash in inside_main_func" Resolves: rhbz#2183595 --- _gdb.spec.Patch.include | 4 + _gdb.spec.patch.include | 1 + _patch_order | 1 + gdb-rhbz2183595-rustc-inside_main.patch | 136 ++++++++++++++++++++++++ gdb.spec | 6 +- 5 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 gdb-rhbz2183595-rustc-inside_main.patch diff --git a/_gdb.spec.Patch.include b/_gdb.spec.Patch.include index c51abfc..a5806be 100644 --- a/_gdb.spec.Patch.include +++ b/_gdb.spec.Patch.include @@ -232,3 +232,7 @@ Patch054: gdb-rhbz1553104-s390x-arch12-test.patch # [aarch64] Backport fix from Luis Machado for RH BZ 2177655. Patch055: gdb-rhbz2177655-aarch64-pauth-valid-regcache.patch +# Backport "Fix crash in inside_main_func" +# (Tom Tromey, RHBZ 2183595) +Patch056: gdb-rhbz2183595-rustc-inside_main.patch + diff --git a/_gdb.spec.patch.include b/_gdb.spec.patch.include index b72c412..46efc44 100644 --- a/_gdb.spec.patch.include +++ b/_gdb.spec.patch.include @@ -53,3 +53,4 @@ %patch -p1 -P053 %patch -p1 -P054 %patch -p1 -P055 +%patch -p1 -P056 diff --git a/_patch_order b/_patch_order index 8108523..1c80644 100644 --- a/_patch_order +++ b/_patch_order @@ -53,3 +53,4 @@ gdb-linux_perf-bundle.patch gdb-libexec-add-index.patch gdb-rhbz1553104-s390x-arch12-test.patch gdb-rhbz2177655-aarch64-pauth-valid-regcache.patch +gdb-rhbz2183595-rustc-inside_main.patch diff --git a/gdb-rhbz2183595-rustc-inside_main.patch b/gdb-rhbz2183595-rustc-inside_main.patch new file mode 100644 index 0000000..16a77b6 --- /dev/null +++ b/gdb-rhbz2183595-rustc-inside_main.patch @@ -0,0 +1,136 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Tom Tromey +Date: Fri, 24 Feb 2023 10:40:16 -0700 +Subject: gdb-rhbz2183595-rustc-inside_main.patch + +;; Backport "Fix crash in inside_main_func" +;; (Tom Tromey, RHBZ 2183595) + +gdb 13.1 crashes while running the rust compiler's debugger tests. +The crash has a number of causes. + +First, the rust compiler still uses the C++-like _Z mangling, but with +its own twist -- some hex digits added to the end of a symbol. So, +while gdb finds the correct name of "main": + +(top-gdb) p name +$13 = 0x292e0c0 "rustc_gdb_1031745::main" + +It isn't found in the minsyms, because C++ demangling yields: + +[99] t 0x90c0 _ZN17rustc_gdb_10317454main17h5b5be7fe16a97225E section .text rustc_gdb_1031745::main::h5b5be7fe16a97225 zko06yobckx336v + +This could perhaps be fixed. I also filed a new PR to suggest +preferring the linkage name of the main program. + +Next, the rust compiler emits both a DW_TAG_subprogram and a +DW_TAG_namespace for "main". This happens because the file is named +"main.rs" -- i.e., the bug is specific to the source file name. The +crash also seems to require the nested function inside of 'main', at +least for me. The namespace always is generated, but perhaps this +changes the ordering in the DWARF. + +When inside_main_func looks up the main symbol, it finds the namespace +symbol rather than the function. (I filed a bug about fixing gdb's +symbol tables -- long overdue.) + +Meanwhile, as I think it's important to fix this crash sooner rather +than later, this patch changes inside_main_func to check that the +symbol that is found is LOC_BLOCK. This perhaps should have been done +in the first place, anyway. + +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30158 + +diff --git a/gdb/frame.c b/gdb/frame.c +--- a/gdb/frame.c ++++ b/gdb/frame.c +@@ -2453,6 +2453,14 @@ inside_main_func (frame_info_ptr this_frame) + if (bs.symbol == nullptr) + return false; + ++ /* We might have found some unrelated symbol. For example, the ++ Rust compiler can emit both a subprogram and a namespace with ++ the same name in the same scope; and due to how gdb's symbol ++ tables currently work, we can't request the one we'd ++ prefer. */ ++ if (bs.symbol->aclass () != LOC_BLOCK) ++ return false; ++ + const struct block *block = bs.symbol->value_block (); + gdb_assert (block != nullptr); + sym_addr = block->start (); +diff --git a/gdb/testsuite/gdb.rust/main-crash.exp b/gdb/testsuite/gdb.rust/main-crash.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.rust/main-crash.exp +@@ -0,0 +1,35 @@ ++# Copyright (C) 2023 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 . ++ ++# Regression test for a crash in inside_main_func. ++ ++load_lib rust-support.exp ++require allow_rust_tests ++ ++standard_testfile main.rs ++if {[prepare_for_testing "failed to prepare" $testfile $srcfile \ ++ {debug rust}]} { ++ return -1 ++} ++ ++set line [gdb_get_line_number "BREAK"] ++# The bug was that this would crash. ++if {![runto ${srcfile}:$line]} { ++ untested "could not run to breakpoint" ++ return -1 ++} ++ ++# Test that gdb is alive. ++gdb_test "print 23" " = 23" +diff --git a/gdb/testsuite/gdb.rust/main.rs b/gdb/testsuite/gdb.rust/main.rs +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.rust/main.rs +@@ -0,0 +1,30 @@ ++// Copyright (C) 2016-2023 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)] ++ ++fn global_fn(x: u8) { ++ // BREAK ++} ++ ++fn main() { ++ fn nested(y: u8) { ++ global_fn(y) ++ } ++ ++ nested(23); ++} diff --git a/gdb.spec b/gdb.spec index 486d41b..886616c 100644 --- a/gdb.spec +++ b/gdb.spec @@ -57,7 +57,7 @@ Version: 13.1 # The release always contains a leading reserved number, start it at 1. # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing. -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and LGPLv3+ and BSD and Public Domain and GFDL # Do not provide URL for snapshots as the file lasts there only for 2 days. @@ -1249,6 +1249,10 @@ fi %endif %changelog +* Fri Mar 31 2023 Keith Seitz - 13.1-4 +- Backport "Fix crash in inside_main_func" + (Tom Tromey, RHBZ 2183595) + * Thu Mar 30 2023 Alexandra Hájková - 12.1-3 - Update gdb-6.6-buildid-locate.patch to fix RHBZ 2181221.