From: Tom de Vries Date: Wed, 28 May 2025 20:17:19 +0000 (+0200) Subject: [gdb/symtab] Note errors in process_skeletonless_type_units X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=11cb20e27b50419ffadb65706d716f9019f03516;p=thirdparty%2Fbinutils-gdb.git [gdb/symtab] Note errors in process_skeletonless_type_units With a hello world a.out, and using the compiler flags from target board dwarf5-fission-debug-types: ... $ gcc -gdwarf-5 -fdebug-types-section -gsplit-dwarf ~/data/hello.c ... I run into: ... $ gdb -q -batch a.out terminate called after throwing an instance of 'gdb_exception_error' ... What happens is that an error is thrown due to invalid dwarf, but the error is not caught, causing gdb to terminate. In a way, this is a duplicate of PR32861, in the sense that we no longer run into this after: - applying the proposed patch (work around compiler bug), or - using gcc 9 or newer (compiler bug fixed). But in this case, the failure mode is worse than in PR32861. Fix this by catching the error in cooked_index_worker_debug_info::process_skeletonless_type_units. With the patch, we get instead: ... $ gdb -q -batch a.out Offset from DW_FORM_GNU_str_index or DW_FORM_strx pointing outside of \ .debug_str.dwo section in CU at offset 0x0 [in module a.out] ... While we're at it, absorb the common use of cooked_index_worker_result::note_error: ... try { ... } catch (gdb_exception &exc) { (...).note_error (std::move (exc)); } ... into the method and rename it to catch_error, resulting in more compact code for the fix: ... (...).catch_error ([&] () { ... }); ... While we're at it, also use it in cooked_index_worker_debug_info::process_units which looks like it needs the same fix. Tested on x86_64-linux. PR symtab/32979 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32979 --- diff --git a/gdb/dwarf2/cooked-index-worker.h b/gdb/dwarf2/cooked-index-worker.h index df5c31d572d..c68620578cc 100644 --- a/gdb/dwarf2/cooked-index-worker.h +++ b/gdb/dwarf2/cooked-index-worker.h @@ -107,11 +107,20 @@ public: return &m_parent_map; } - /* Add an exception to the list of exceptions caught while reading. - These are passed forward and printed by the main thread. */ - void note_error (gdb_exception &&except) + /* Catch exceptions from calling F (), and add them to the list of caught + exceptions. These are passed forward and printed by the main thread. */ + template + void + catch_error (F &&f) { - m_exceptions.push_back (std::move (except)); + try + { + f (); + } + catch (gdb_exception &ex) + { + m_exceptions.push_back (std::move (ex)); + } } /* Called when the thread using this object is done with its work. diff --git a/gdb/dwarf2/read-debug-names.c b/gdb/dwarf2/read-debug-names.c index 11de9862882..e5f604a8eb6 100644 --- a/gdb/dwarf2/read-debug-names.c +++ b/gdb/dwarf2/read-debug-names.c @@ -416,15 +416,11 @@ cooked_index_worker_debug_names::do_reading () { complaint_interceptor complaint_handler; - try + /* Arbitrarily put all exceptions into the first result. */ + m_map.indices[0].catch_error ([&] () { m_map.scan_all_names (); - } - catch (gdb_exception &exc) - { - /* Arbitrarily put all exceptions into the first result. */ - m_map.indices[0].note_error (std::move (exc)); - } + }); bool first = true; for (auto &iter : m_map.indices) diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 273d594adfe..b178dacbe3d 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -3425,7 +3425,10 @@ cooked_index_worker_debug_info::process_type_units abbrev_table.get (), nullptr, false, language_minimal); if (!reader.is_dummy ()) - process_type_unit (&reader, storage); + storage->catch_error ([&] () + { + process_type_unit (&reader, storage); + }); } } @@ -3467,7 +3470,10 @@ cooked_index_worker_debug_info::process_skeletonless_type_units if (per_objfile->per_bfd->dwp_file == nullptr) for (const dwo_file_up &file : per_objfile->per_bfd->dwo_files) for (const dwo_unit_up &unit : file->tus) - process_skeletonless_type_unit (unit.get (), per_objfile, storage); + storage->catch_error ([&] () + { + process_skeletonless_type_unit (unit.get (), per_objfile, storage); + }); } void @@ -3486,14 +3492,10 @@ cooked_index_worker_debug_info::process_units (size_t task_number, { dwarf2_per_cu *per_cu = inner->get (); - try + thread_storage.catch_error ([&] () { process_unit (per_cu, m_per_objfile, &thread_storage); - } - catch (gdb_exception &except) - { - thread_storage.note_error (std::move (except)); - } + }); } thread_storage.done_reading (complaint_handler.release ());