[PATCH] read_file_scope - avoid eventual crash when the file or directory name is null.

Dominic Clifton
2025-10-09T17:35:40Z

* without this, launching the debugger results in the following error:

```
terminate called after throwing an instance of 'std::logic_error' what():
basic_string: construction from null is not valid
```

find_file_and_directory - return empty strings instead of null pointers.

---
gdb/dwarf2/read.c | 29 +++++++++++++++++++++--------
1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 955893c5f0c..287ce7b518c 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -5942,10 +5942,18 @@ find_file_and_directory (struct die_info *die,
struct dwarf2_cu *cu)
if (cu->per_cu->fnd != nullptr)
return *cu->per_cu->fnd;

+ // Ensure that nullptrs become empty strings
+ const char *name = dwarf2_string_attr(die, DW_AT_name, cu);
+ const char *comp_dir = dwarf2_string_attr(die, DW_AT_comp_dir, cu);
+
+ if (!name)
+ name = "";
+ if (!comp_dir)
+ comp_dir = "";
+
/* Find the filename. Do not use dwarf2_name here, since the filename
is not a source language identifier. */
- file_and_directory res (dwarf2_string_attr (die, DW_AT_name, cu),
- dwarf2_string_attr (die, DW_AT_comp_dir, cu));
+ file_and_directory res(name, comp_dir);

if (res.get_comp_dir () == nullptr
&& cu->producer_is_gcc_lt_4_3 ()
@@ -6083,28 +6091,33 @@ read_file_scope (struct die_info *die, struct
dwarf2_cu *cu)

file_and_directory &fnd = find_file_and_directory (die, cu);

+ // ensure fnd.get_name() and fnd.get_comp_dir() are never null, which
they sometimes are
+ const char *fname = fnd.get_name() ? fnd.get_name() : "";
+ const char *compdir = fnd.get_comp_dir() ? fnd.get_comp_dir() : "";
+
/* GAS supports generating dwarf-5 info starting version 2.35. Versions
2.35-2.37 generate an incorrect CU name attribute: it's relative,
implicitly prefixing it with the compilation dir. Work around this by
prefixing it with the source dir instead. */
- if (cu->header.version == 5 && !IS_ABSOLUTE_PATH (fnd.get_name ())
+ if (cu->header.version == 5 && !IS_ABSOLUTE_PATH (fname)
&& cu->producer_is_gas_lt_2_38 ())
{
attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
if (attr != nullptr && attr->form_is_unsigned ())
{
sect_offset line_offset = (sect_offset) attr->as_unsigned ();
- line_header_up lh = dwarf_decode_line_header (line_offset, cu,
- fnd.get_comp_dir
());
+ line_header_up lh = dwarf_decode_line_header (line_offset, cu,
compdir);
if (lh->version == 5 && lh->include_dir_at (1) != nullptr)
{
- std::string dir = lh->include_dir_at (1);
- fnd.set_comp_dir (std::move (dir));
+ const char* dir_ptr = lh->include_dir_at (1);
+ std::string dir = dir_ptr ? dir_ptr : compdir;
+
+ fnd.set_comp_dir (std::move (dir));
}
}
}

- cu->start_compunit_symtab (fnd.get_name (), fnd.intern_comp_dir
(objfile),
+ cu->start_compunit_symtab (fname, fnd.intern_comp_dir (objfile),
lowpc);

gdb_assert (per_objfile->sym_cu == nullptr);
--
2.48.1