[binutils-gdb] Avoid crash in dwarf2/read.c:determine_prefix
Tom Tromey via Gdb-cvs <[email protected]>
| Newsgroups | gmane.comp.gdb.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=60f1332264439b1605ad8b12382d4d472b8d7900 commit 60f1332264439b1605ad8b12382d4d472b8d7900 Author: Tom Tromey <[email protected]> Date: Tue Apr 21 14:03:39 2026 -0600 Avoid crash in dwarf2/read.c:determine_prefix I found a gdb crash when using some changes to gnat-llvm to have it emit unqualified names in the DWARF. The crash happens because determine_prefix does this: return dwarf2_full_name (nullptr, parent, cu); However, dwarf2_full_name can return NULL, causing a crash in the caller. The particular DWARF causing this is pretty strange -- it is a function nested inside another nameless function. This may be a bug in gnat-llvm, something I plan to investigate. Meanwhile, gdb shouldn't crash. This patch changes determine_prefix to avoid possible crashes here, by following its contract and not returning NULL. I'm not sure if it's worthwhile to write a test case for this. Approved-By: Simon Marchi <[email protected]> Diff: --- gdb/dwarf2/read.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 1288c076aba..7b5e1b65554 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -16637,23 +16637,28 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu) } return ""; case DW_TAG_subprogram: - /* Nested subroutines in Fortran get a prefix with the name - of the parent's subroutine. Entry points are prefixed by the - parent's namespace. */ - if (cu->lang () == language_fortran) - { - if ((die->tag == DW_TAG_subprogram) - && (dwarf2_name (parent, cu) != NULL)) - return dwarf2_name (parent, cu); - else if (die->tag == DW_TAG_entry_point) - return determine_prefix (parent, cu); - } - else if (cu->lang () == language_ada - && (die->tag == DW_TAG_subprogram - || die->tag == DW_TAG_inlined_subroutine - || die->tag == DW_TAG_lexical_block)) - return dwarf2_full_name (nullptr, parent, cu); - return ""; + { + const char *name = nullptr; + /* Nested subroutines in Fortran get a prefix with the name + of the parent's subroutine. Entry points are prefixed by the + parent's namespace. */ + if (cu->lang () == language_fortran) + { + if ((die->tag == DW_TAG_subprogram) + && (dwarf2_name (parent, cu) != NULL)) + name = dwarf2_name (parent, cu); + else if (die->tag == DW_TAG_entry_point) + name = determine_prefix (parent, cu); + } + else if (cu->lang () == language_ada + && (die->tag == DW_TAG_subprogram + || die->tag == DW_TAG_inlined_subroutine + || die->tag == DW_TAG_lexical_block)) + name = dwarf2_full_name (nullptr, parent, cu); + if (name == nullptr) + name = ""; + return name; + } case DW_TAG_enumeration_type: parent_type = read_type_die (parent, cu); if (parent_type->is_declared_class ())