diff options
Diffstat (limited to 'gdb/dwarf2')
-rw-r--r-- | gdb/dwarf2/read.c | 74 | ||||
-rw-r--r-- | gdb/dwarf2/read.h | 2 |
2 files changed, 46 insertions, 30 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index b36694e..0fccce8 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -1684,15 +1684,18 @@ public: explicit dwarf2_queue_guard (dwarf2_per_objfile *per_objfile) : m_per_objfile (per_objfile) { + gdb_assert (!m_per_objfile->per_bfd->queue.has_value ()); + + m_per_objfile->per_bfd->queue.emplace (); } /* Free any entries remaining on the queue. There should only be entries left if we hit an error while processing the dwarf. */ ~dwarf2_queue_guard () { - /* Ensure that no memory is allocated by the queue. */ - std::queue<dwarf2_queue_item> empty; - std::swap (m_per_objfile->per_bfd->queue, empty); + gdb_assert (m_per_objfile->per_bfd->queue.has_value ()); + + m_per_objfile->per_bfd->queue.reset (); } DISABLE_COPY_AND_ASSIGN (dwarf2_queue_guard); @@ -1861,6 +1864,8 @@ dwarf2_per_bfd::~dwarf2_per_bfd () void dwarf2_per_objfile::remove_all_cus () { + gdb_assert (!this->per_bfd->queue.has_value ()); + for (auto pair : m_dwarf2_cus) delete pair.second; @@ -2542,30 +2547,32 @@ dw2_do_instantiate_symtab (dwarf2_per_cu_data *per_cu, if (per_cu->type_unit_group_p ()) return; - /* The destructor of dwarf2_queue_guard frees any entries left on - the queue. After this point we're guaranteed to leave this function - with the dwarf queue empty. */ - dwarf2_queue_guard q_guard (per_objfile); - - if (!per_objfile->symtab_set_p (per_cu)) - { - queue_comp_unit (per_cu, per_objfile, language_minimal); - dwarf2_cu *cu = load_cu (per_cu, per_objfile, skip_partial); + { + /* The destructor of dwarf2_queue_guard frees any entries left on + the queue. After this point we're guaranteed to leave this function + with the dwarf queue empty. */ + dwarf2_queue_guard q_guard (per_objfile); - /* If we just loaded a CU from a DWO, and we're working with an index - that may badly handle TUs, load all the TUs in that DWO as well. - http://sourceware.org/bugzilla/show_bug.cgi?id=15021 */ - if (!per_cu->is_debug_types - && cu != NULL - && cu->dwo_unit != NULL - && per_objfile->per_bfd->index_table != NULL - && per_objfile->per_bfd->index_table->version <= 7 - /* DWP files aren't supported yet. */ - && get_dwp_file (per_objfile) == NULL) - queue_and_load_all_dwo_tus (cu); - } + if (!per_objfile->symtab_set_p (per_cu)) + { + queue_comp_unit (per_cu, per_objfile, language_minimal); + dwarf2_cu *cu = load_cu (per_cu, per_objfile, skip_partial); + + /* If we just loaded a CU from a DWO, and we're working with an index + that may badly handle TUs, load all the TUs in that DWO as well. + http://sourceware.org/bugzilla/show_bug.cgi?id=15021 */ + if (!per_cu->is_debug_types + && cu != NULL + && cu->dwo_unit != NULL + && per_objfile->per_bfd->index_table != NULL + && per_objfile->per_bfd->index_table->version <= 7 + /* DWP files aren't supported yet. */ + && get_dwp_file (per_objfile) == NULL) + queue_and_load_all_dwo_tus (cu); + } - process_queue (per_objfile); + process_queue (per_objfile); + } /* Age the cache, releasing compilation units that have not been used recently. */ @@ -9180,7 +9187,9 @@ queue_comp_unit (dwarf2_per_cu_data *per_cu, enum language pretend_language) { per_cu->queued = 1; - per_cu->per_bfd->queue.emplace (per_cu, per_objfile, pretend_language); + + gdb_assert (per_objfile->per_bfd->queue.has_value ()); + per_cu->per_bfd->queue->emplace (per_cu, per_objfile, pretend_language); } /* If PER_CU is not yet expanded of queued for expansion, add it to the queue. @@ -9275,9 +9284,9 @@ process_queue (dwarf2_per_objfile *per_objfile) /* The queue starts out with one item, but following a DIE reference may load a new CU, adding it to the end of the queue. */ - while (!per_objfile->per_bfd->queue.empty ()) + while (!per_objfile->per_bfd->queue->empty ()) { - dwarf2_queue_item &item = per_objfile->per_bfd->queue.front (); + dwarf2_queue_item &item = per_objfile->per_bfd->queue->front (); dwarf2_per_cu_data *per_cu = item.per_cu; if (!per_objfile->symtab_set_p (per_cu)) @@ -9323,7 +9332,7 @@ process_queue (dwarf2_per_objfile *per_objfile) } per_cu->queued = 0; - per_objfile->per_bfd->queue.pop (); + per_objfile->per_bfd->queue->pop (); } dwarf_read_debug_printf ("Done expanding symtabs of %s.", @@ -25122,6 +25131,13 @@ dwarf2_per_objfile::age_comp_units () { dwarf_read_debug_printf_v ("running"); + /* This is not expected to be called in the middle of CU expansion. There is + an invariant that if a CU is in the CUs-to-expand queue, its DIEs are + loaded in memory. Calling age_comp_units while the queue is in use could + make us free the DIEs for a CU that is in the queue and therefore break + that invariant. */ + gdb_assert (!this->per_bfd->queue.has_value ()); + /* Start by clearing all marks. */ for (auto pair : m_dwarf2_cus) pair.second->mark = false; diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index d2bae5a..c7f6a11 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -250,7 +250,7 @@ public: abstract_to_concrete; /* CUs that are queued to be read. */ - std::queue<dwarf2_queue_item> queue; + gdb::optional<std::queue<dwarf2_queue_item>> queue; /* We keep a separate reference to the partial symtabs, in case we are sharing them between objfiles. This is only set after |