[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 ())
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.