From: Iain Buclaw <ibuclaw@gdcproject.org>
To: gdb-patches@sourceware.org
Cc: tom@tromey.com, Iain Buclaw <ibuclaw@gdcproject.org>
Subject: [PATCH v2] gdb, d: Fix PR 33200 - Segfault in d_lookup_symbol
Date: Fri, 1 Aug 2025 01:09:46 +0200 [thread overview]
Message-ID: <20250731230946.102908-1-ibuclaw@gdcproject.org> (raw)
In-Reply-To: <1753985679.4lko1qk7ka.astroid@pulse.none>
After some trial and error, I think I've managed to create a minimal
Dwarf test case.
---
If d_lookup_symbol tries to locate a member variable within a class or
struct type with no a name, type->name() is NULL, so the assignment to
std::string classname crashes gdb.
This can happen in some older versions of gdc, where debug info was
generated too eagerly in complex cases involving types referencing each
other recursively.
This patch adds a guard against this case, allowing the caller of
d_lookup_symbol to search other blocks for the right symbol.
---
gdb/d-namespace.c | 4 ++
gdb/testsuite/gdb.dlang/namelessclass.c | 31 ++++++++++
gdb/testsuite/gdb.dlang/namelessclass.exp | 75 +++++++++++++++++++++++
3 files changed, 110 insertions(+)
create mode 100644 gdb/testsuite/gdb.dlang/namelessclass.c
create mode 100644 gdb/testsuite/gdb.dlang/namelessclass.exp
diff --git a/gdb/d-namespace.c b/gdb/d-namespace.c
index b5e046efaa7..cdfa67a051c 100644
--- a/gdb/d-namespace.c
+++ b/gdb/d-namespace.c
@@ -131,6 +131,10 @@ d_lookup_symbol (const struct language_defn *langdef,
return {};
type = check_typedef (lang_this.symbol->type ()->target_type ());
+ /* If type name is NULL, abandon trying to find this symbol. */
+ if (type->name () == nullptr)
+ return {};
+
classname = type->name ();
nested = name;
}
diff --git a/gdb/testsuite/gdb.dlang/namelessclass.c b/gdb/testsuite/gdb.dlang/namelessclass.c
new file mode 100644
index 00000000000..837e33f5764
--- /dev/null
+++ b/gdb/testsuite/gdb.dlang/namelessclass.c
@@ -0,0 +1,31 @@
+/* Copyright 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/>. */
+
+/* DWARF will describe this function as being inside an anonymous class within
+ a D module. */
+
+void
+doit (void *this)
+{
+ asm ("doit_label: .globl doit_label");
+}
+
+int
+main (void)
+{
+ doit (0);
+ return 0;
+}
+
diff --git a/gdb/testsuite/gdb.dlang/namelessclass.exp b/gdb/testsuite/gdb.dlang/namelessclass.exp
new file mode 100644
index 00000000000..3246ae33849
--- /dev/null
+++ b/gdb/testsuite/gdb.dlang/namelessclass.exp
@@ -0,0 +1,75 @@
+# Copyright 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/>.
+
+# Test nameless classes that may be output by the compiler.
+# PR gdb/33200
+
+load_lib "d-support.exp"
+load_lib "dwarf.exp"
+
+# Do not run in environments which do not support D.
+require dwarf2_support allow_d_tests
+
+standard_testfile .c -dw.S
+
+# Make some DWARF for the test.
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+ cu {} {
+ compile_unit {
+ {language @DW_LANG_D}
+ } {
+ declare_labels class_label class_ptr_label
+ set class_size 1
+ set ptr_size 4
+
+ module {
+ {name namelessclass}
+ } {
+ class_label: class_type {
+ {byte_size $class_size sdata}
+ {name ""}
+ }
+ class_ptr_label: pointer_type {
+ {byte_size $ptr_size data1}
+ {type :$class_label}
+ }
+ subprogram {
+ {MACRO_AT_func {"doit"}}
+ {external 1 flag_present}
+ } {
+ formal_parameter {
+ {name "this"}
+ {type :$class_ptr_label}
+ }
+ }
+ }
+ }
+ }
+}
+
+if { [prepare_for_testing "failed to prepare" ${testfile} \
+ [list $srcfile $asm_file] {nodebug}] } {
+ return -1
+}
+
+gdb_test_no_output "set language d"
+
+if {![runto "doit"]} {
+ return -1
+}
+
+# Any output is accepted as valid as long as gdb does not segfault.
+gdb_test "print do_not_segfault" ".*"
--
2.43.0
next prev parent reply other threads:[~2025-07-31 23:11 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-30 11:42 [PATCH] " Iain Buclaw
2025-07-31 16:52 ` Tom Tromey
2025-07-31 18:25 ` Iain Buclaw
2025-07-31 23:09 ` Iain Buclaw [this message]
2025-08-04 17:22 ` [PATCH v2] " Tom Tromey
2025-08-04 17:43 ` Tom Tromey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250731230946.102908-1-ibuclaw@gdcproject.org \
--to=ibuclaw@gdcproject.org \
--cc=gdb-patches@sourceware.org \
--cc=tom@tromey.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox