3 Copyright (C) 2022-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #include "dwarf2/cooked-index.h"
21 #include "dwarf2/read.h"
22 #include "dwarf2/stringify.h"
23 #include "dwarf2/index-cache.h"
24 #include "cp-support.h"
27 #include "event-top.h"
28 #include "split-name.h"
29 #include "observable.h"
30 #include "run-on-main-thread.h"
32 #include "gdbsupport/gdb-safe-ctype.h"
33 #include "gdbsupport/selftest.h"
35 #include <unordered_set>
36 #include "cli/cli-cmds.h"
38 /* We don't want gdb to exit while it is in the process of writing to
39 the index cache. So, all live cooked index vectors are stored
40 here, and then these are all waited for before exit proceeds. */
41 static std::unordered_set
<cooked_index
*> active_vectors
;
43 /* See cooked-index.h. */
46 to_string (cooked_index_flag flags
)
48 static constexpr cooked_index_flag::string_mapping mapping
[] = {
49 MAP_ENUM_FLAG (IS_MAIN
),
50 MAP_ENUM_FLAG (IS_STATIC
),
51 MAP_ENUM_FLAG (IS_LINKAGE
),
52 MAP_ENUM_FLAG (IS_TYPE_DECLARATION
),
53 MAP_ENUM_FLAG (IS_PARENT_DEFERRED
),
56 return flags
.to_string (mapping
);
59 /* See cooked-index.h. */
62 language_requires_canonicalization (enum language lang
)
64 return (lang
== language_ada
66 || lang
== language_cplus
);
69 /* Return true if a plain "main" could be the main program for this
70 language. Languages that are known to use some other mechanism are
74 language_may_use_plain_main (enum language lang
)
76 /* No need to handle "unknown" here. */
77 return (lang
== language_c
78 || lang
== language_objc
79 || lang
== language_cplus
80 || lang
== language_m2
81 || lang
== language_asm
82 || lang
== language_opencl
83 || lang
== language_minimal
);
86 /* See cooked-index.h. */
89 cooked_index_entry::compare (const char *stra
, const char *strb
,
92 auto munge
= [] (char c
) -> unsigned char
94 /* We want to sort '<' before any other printable character.
95 So, rewrite '<' to something just before ' '. */
98 return TOLOWER ((unsigned char) c
);
103 && (munge (*stra
) == munge (*strb
)))
109 unsigned char c1
= munge (*stra
);
110 unsigned char c2
= munge (*strb
);
115 /* When completing, if STRB ends earlier than STRA, consider them as
116 equal. When comparing, if STRB ends earlier and STRA ends with
117 '<', consider them as equal. */
118 if (mode
== COMPLETE
|| (mode
== MATCH
&& c1
== munge ('<')))
124 return c1
< c2
? -1 : 1;
134 /* Convenience aliases. */
135 const auto mode_compare
= cooked_index_entry::MATCH
;
136 const auto mode_sort
= cooked_index_entry::SORT
;
137 const auto mode_complete
= cooked_index_entry::COMPLETE
;
139 SELF_CHECK (cooked_index_entry::compare ("abcd", "abcd",
141 SELF_CHECK (cooked_index_entry::compare ("abcd", "abcd",
142 mode_complete
) == 0);
144 SELF_CHECK (cooked_index_entry::compare ("abcd", "ABCDE",
146 SELF_CHECK (cooked_index_entry::compare ("ABCDE", "abcd",
148 SELF_CHECK (cooked_index_entry::compare ("abcd", "ABCDE",
150 SELF_CHECK (cooked_index_entry::compare ("ABCDE", "abcd",
151 mode_complete
) == 0);
153 SELF_CHECK (cooked_index_entry::compare ("name", "name<>",
155 SELF_CHECK (cooked_index_entry::compare ("name<>", "name",
157 SELF_CHECK (cooked_index_entry::compare ("name", "name<>",
159 SELF_CHECK (cooked_index_entry::compare ("name<>", "name",
160 mode_complete
) == 0);
162 SELF_CHECK (cooked_index_entry::compare ("name<arg>", "name<arg>",
164 SELF_CHECK (cooked_index_entry::compare ("name<arg>", "name<ag>",
166 SELF_CHECK (cooked_index_entry::compare ("name<arg>", "name<arg>",
167 mode_complete
) == 0);
168 SELF_CHECK (cooked_index_entry::compare ("name<arg>", "name<ag>",
171 SELF_CHECK (cooked_index_entry::compare ("name<arg<more>>",
175 SELF_CHECK (cooked_index_entry::compare ("name", "name<arg<more>>",
177 SELF_CHECK (cooked_index_entry::compare ("name<arg<more>>", "name",
179 SELF_CHECK (cooked_index_entry::compare ("name<arg<more>>", "name<arg<",
181 SELF_CHECK (cooked_index_entry::compare ("name<arg<more>>", "name<arg<",
182 mode_complete
) == 0);
184 SELF_CHECK (cooked_index_entry::compare ("", "abcd", mode_compare
) < 0);
185 SELF_CHECK (cooked_index_entry::compare ("", "abcd", mode_complete
) < 0);
186 SELF_CHECK (cooked_index_entry::compare ("abcd", "", mode_compare
) > 0);
187 SELF_CHECK (cooked_index_entry::compare ("abcd", "", mode_complete
) == 0);
189 SELF_CHECK (cooked_index_entry::compare ("func", "func<type>",
191 SELF_CHECK (cooked_index_entry::compare ("func<type>", "func1",
195 } /* anonymous namespace */
197 #endif /* GDB_SELF_TEST */
199 /* See cooked-index.h. */
202 cooked_index_entry::matches (domain_search_flags kind
) const
204 /* Just reject type declarations. */
205 if ((flags
& IS_TYPE_DECLARATION
) != 0)
208 return tag_matches_domain (tag
, kind
, lang
);
211 /* See cooked-index.h. */
214 cooked_index_entry::full_name (struct obstack
*storage
, bool for_main
) const
216 const char *local_name
= for_main
? name
: canonical
;
218 if ((flags
& IS_LINKAGE
) != 0 || get_parent () == nullptr)
221 const char *sep
= nullptr;
239 get_parent ()->write_scope (storage
, sep
, for_main
);
240 obstack_grow0 (storage
, local_name
, strlen (local_name
));
241 return (const char *) obstack_finish (storage
);
244 /* See cooked-index.h. */
247 cooked_index_entry::write_scope (struct obstack
*storage
,
251 if (get_parent () != nullptr)
252 get_parent ()->write_scope (storage
, sep
, for_main
);
253 const char *local_name
= for_main
? name
: canonical
;
254 obstack_grow (storage
, local_name
, strlen (local_name
));
255 obstack_grow (storage
, sep
, strlen (sep
));
258 /* See cooked-index.h. */
261 cooked_index_shard::add (sect_offset die_offset
, enum dwarf_tag tag
,
262 cooked_index_flag flags
, enum language lang
,
264 cooked_index_entry_ref parent_entry
,
265 dwarf2_per_cu_data
*per_cu
)
267 cooked_index_entry
*result
= create (die_offset
, tag
, flags
, lang
, name
,
268 parent_entry
, per_cu
);
269 m_entries
.push_back (result
);
271 /* An explicitly-tagged main program should always override the
272 implicit "main" discovery. */
273 if ((flags
& IS_MAIN
) != 0)
275 else if ((flags
& IS_PARENT_DEFERRED
) == 0
276 && parent_entry
.resolved
== nullptr
278 && language_may_use_plain_main (lang
)
279 && strcmp (name
, "main") == 0)
285 /* See cooked-index.h. */
287 gdb::unique_xmalloc_ptr
<char>
288 cooked_index_shard::handle_gnat_encoded_entry (cooked_index_entry
*entry
,
291 /* We decode Ada names in a particular way: operators and wide
292 characters are left as-is. This is done to make name matching a
293 bit simpler; and for wide characters, it means the choice of Ada
294 source charset does not affect the indexer directly. */
295 std::string canonical
= ada_decode (entry
->name
, false, false, false);
296 if (canonical
.empty ())
298 std::vector
<std::string_view
> names
= split_name (canonical
.c_str (),
299 split_style::DOT_STYLE
);
300 std::string_view tail
= names
.back ();
303 const cooked_index_entry
*parent
= nullptr;
304 for (const auto &name
: names
)
306 uint32_t hashval
= dwarf5_djb_hash (name
);
307 void **slot
= htab_find_slot_with_hash (gnat_entries
, &name
,
309 /* CUs are processed in order, so we only need to check the most
311 cooked_index_entry
*last
= (cooked_index_entry
*) *slot
;
312 if (last
== nullptr || last
->per_cu
!= entry
->per_cu
)
314 gdb::unique_xmalloc_ptr
<char> new_name
315 = make_unique_xstrndup (name
.data (), name
.length ());
316 last
= create (entry
->die_offset
, DW_TAG_namespace
,
317 0, language_ada
, new_name
.get (), parent
,
319 last
->canonical
= last
->name
;
320 m_names
.push_back (std::move (new_name
));
327 entry
->set_parent (parent
);
328 return make_unique_xstrndup (tail
.data (), tail
.length ());
331 /* See cooked-index.h. */
334 cooked_index_shard::finalize (const parent_map_map
*parent_maps
)
336 auto hash_name_ptr
= [] (const void *p
)
338 const cooked_index_entry
*entry
= (const cooked_index_entry
*) p
;
339 return htab_hash_pointer (entry
->name
);
342 auto eq_name_ptr
= [] (const void *a
, const void *b
) -> int
344 const cooked_index_entry
*ea
= (const cooked_index_entry
*) a
;
345 const cooked_index_entry
*eb
= (const cooked_index_entry
*) b
;
346 return ea
->name
== eb
->name
;
349 /* We can use pointer equality here because names come from
350 .debug_str, which will normally be unique-ified by the linker.
351 Also, duplicates are relatively harmless -- they just mean a bit
352 of extra memory is used. */
353 htab_up
seen_names (htab_create_alloc (10, hash_name_ptr
, eq_name_ptr
,
354 nullptr, xcalloc
, xfree
));
356 auto hash_entry
= [] (const void *e
)
358 const cooked_index_entry
*entry
= (const cooked_index_entry
*) e
;
359 return dwarf5_djb_hash (entry
->canonical
);
362 auto eq_entry
= [] (const void *a
, const void *b
) -> int
364 const cooked_index_entry
*ae
= (const cooked_index_entry
*) a
;
365 const std::string_view
*sv
= (const std::string_view
*) b
;
366 return (strlen (ae
->canonical
) == sv
->length ()
367 && strncasecmp (ae
->canonical
, sv
->data (), sv
->length ()) == 0);
370 htab_up
gnat_entries (htab_create_alloc (10, hash_entry
, eq_entry
,
371 nullptr, xcalloc
, xfree
));
373 for (cooked_index_entry
*entry
: m_entries
)
375 if ((entry
->flags
& IS_PARENT_DEFERRED
) != 0)
377 const cooked_index_entry
*new_parent
378 = parent_maps
->find (entry
->get_deferred_parent ());
379 entry
->resolve_parent (new_parent
);
382 /* Note that this code must be kept in sync with
383 language_requires_canonicalization. */
384 gdb_assert (entry
->canonical
== nullptr);
385 if ((entry
->flags
& IS_LINKAGE
) != 0)
386 entry
->canonical
= entry
->name
;
387 else if (entry
->lang
== language_ada
)
389 gdb::unique_xmalloc_ptr
<char> canon_name
390 = handle_gnat_encoded_entry (entry
, gnat_entries
.get ());
391 if (canon_name
== nullptr)
392 entry
->canonical
= entry
->name
;
395 entry
->canonical
= canon_name
.get ();
396 m_names
.push_back (std::move (canon_name
));
399 else if (entry
->lang
== language_cplus
|| entry
->lang
== language_c
)
401 void **slot
= htab_find_slot (seen_names
.get (), entry
,
403 if (*slot
== nullptr)
405 gdb::unique_xmalloc_ptr
<char> canon_name
406 = (entry
->lang
== language_cplus
407 ? cp_canonicalize_string (entry
->name
)
408 : c_canonicalize_name (entry
->name
));
409 if (canon_name
== nullptr)
410 entry
->canonical
= entry
->name
;
413 entry
->canonical
= canon_name
.get ();
414 m_names
.push_back (std::move (canon_name
));
420 const cooked_index_entry
*other
421 = (const cooked_index_entry
*) *slot
;
422 entry
->canonical
= other
->canonical
;
426 entry
->canonical
= entry
->name
;
429 m_names
.shrink_to_fit ();
430 m_entries
.shrink_to_fit ();
431 std::sort (m_entries
.begin (), m_entries
.end (),
432 [] (const cooked_index_entry
*a
, const cooked_index_entry
*b
)
438 /* See cooked-index.h. */
440 cooked_index_shard::range
441 cooked_index_shard::find (const std::string
&name
, bool completing
) const
443 cooked_index_entry::comparison_mode mode
= (completing
444 ? cooked_index_entry::COMPLETE
445 : cooked_index_entry::MATCH
);
447 auto lower
= std::lower_bound (m_entries
.cbegin (), m_entries
.cend (), name
,
448 [=] (const cooked_index_entry
*entry
,
449 const std::string
&n
)
451 return cooked_index_entry::compare (entry
->canonical
, n
.c_str (), mode
) < 0;
454 auto upper
= std::upper_bound (m_entries
.cbegin (), m_entries
.cend (), name
,
455 [=] (const std::string
&n
,
456 const cooked_index_entry
*entry
)
458 return cooked_index_entry::compare (entry
->canonical
, n
.c_str (), mode
) > 0;
461 return range (lower
, upper
);
464 /* See cooked-index.h. */
467 cooked_index_worker::start ()
469 gdb::thread_pool::g_thread_pool
->post_task ([=] ()
475 catch (const gdb_exception
&exc
)
478 set (cooked_state::CACHE_DONE
);
481 bfd_thread_cleanup ();
485 /* See cooked-index.h. */
488 cooked_index_worker::wait (cooked_state desired_state
, bool allow_quit
)
493 std::unique_lock
<std::mutex
> lock (m_mutex
);
495 /* This may be called from a non-main thread -- this functionality
496 is needed for the index cache -- but in this case we require
497 that the desired state already have been attained. */
498 gdb_assert (is_main_thread () || desired_state
<= m_state
);
500 while (desired_state
> m_state
)
504 std::chrono::milliseconds duration
{ 15 };
505 if (m_cond
.wait_for (lock
, duration
) == std::cv_status::timeout
)
511 done
= m_state
== cooked_state::CACHE_DONE
;
514 /* Without threads, all the work is done immediately on the main
515 thread, and there is never anything to wait for. */
517 #endif /* CXX_STD_THREAD */
519 /* Only the main thread is allowed to report complaints and the
521 if (!is_main_thread ())
528 /* Emit warnings first, maybe they were emitted before an exception
529 (if any) was thrown. */
532 if (m_failed
.has_value ())
534 /* do_reading failed -- report it. */
535 exception_print (gdb_stderr
, *m_failed
);
540 /* Only show a given exception a single time. */
541 std::unordered_set
<gdb_exception
> seen_exceptions
;
542 for (auto &one_result
: m_results
)
544 re_emit_complaints (std::get
<1> (one_result
));
545 for (auto &one_exc
: std::get
<2> (one_result
))
546 if (seen_exceptions
.insert (one_exc
).second
)
547 exception_print (gdb_stderr
, one_exc
);
552 struct objfile
*objfile
= m_per_objfile
->objfile
;
553 dwarf2_per_bfd
*per_bfd
= m_per_objfile
->per_bfd
;
555 = (gdb::checked_static_cast
<cooked_index
*>
556 (per_bfd
->index_table
.get ()));
558 auto_obstack temp_storage
;
559 enum language lang
= language_unknown
;
560 const char *main_name
= table
->get_main_name (&temp_storage
, &lang
);
561 if (main_name
!= nullptr)
562 set_objfile_main_name (objfile
, main_name
, lang
);
564 /* dwarf_read_debug_printf ("Done building psymtabs of %s", */
565 /* objfile_name (objfile)); */
570 /* See cooked-index.h. */
573 cooked_index_worker::set (cooked_state desired_state
)
575 gdb_assert (desired_state
!= cooked_state::INITIAL
);
578 std::lock_guard
<std::mutex
> guard (m_mutex
);
579 gdb_assert (desired_state
> m_state
);
580 m_state
= desired_state
;
581 m_cond
.notify_one ();
583 /* Without threads, all the work is done immediately on the main
584 thread, and there is never anything to do. */
585 #endif /* CXX_STD_THREAD */
588 /* See cooked-index.h. */
591 cooked_index_worker::write_to_cache (const cooked_index
*idx
,
592 deferred_warnings
*warn
) const
596 /* Writing to the index cache may cause a warning to be emitted.
597 See PR symtab/30837. This arranges to capture all such
598 warnings. This is safe because we know the deferred_warnings
599 object isn't in use by any other thread at this point. */
600 scoped_restore_warning_hook
defer (warn
);
601 m_cache_store
.store ();
605 cooked_index::cooked_index (dwarf2_per_objfile
*per_objfile
,
606 std::unique_ptr
<cooked_index_worker
> &&worker
)
607 : m_state (std::move (worker
)),
608 m_per_bfd (per_objfile
->per_bfd
)
610 /* ACTIVE_VECTORS is not locked, and this assert ensures that this
611 will be caught if ever moved to the background. */
612 gdb_assert (is_main_thread ());
613 active_vectors
.insert (this);
617 cooked_index::start_reading ()
623 cooked_index::wait (cooked_state desired_state
, bool allow_quit
)
625 gdb_assert (desired_state
!= cooked_state::INITIAL
);
627 /* If the state object has been deleted, then that means waiting is
629 if (m_state
== nullptr)
632 if (m_state
->wait (desired_state
, allow_quit
))
634 /* Only the main thread can modify this. */
635 gdb_assert (is_main_thread ());
636 m_state
.reset (nullptr);
641 cooked_index::set_contents (vec_type
&&vec
, deferred_warnings
*warn
,
642 const parent_map_map
*parent_maps
)
644 gdb_assert (m_vector
.empty ());
645 m_vector
= std::move (vec
);
647 m_state
->set (cooked_state::MAIN_AVAILABLE
);
649 /* This is run after finalization is done -- but not before. If
650 this task were submitted earlier, it would have to wait for
651 finalization. However, that would take a slot in the global
652 thread pool, and if enough such tasks were submitted at once, it
653 would cause a livelock. */
654 gdb::task_group
finalizers ([=] ()
656 m_state
->set (cooked_state::FINALIZED
);
657 m_state
->write_to_cache (index_for_writing (), warn
);
658 m_state
->set (cooked_state::CACHE_DONE
);
661 for (auto &idx
: m_vector
)
663 auto this_index
= idx
.get ();
664 finalizers
.add_task ([=] () { this_index
->finalize (parent_maps
); });
670 cooked_index::~cooked_index ()
672 /* Wait for index-creation to be done, though this one must also
673 waited for by the per-BFD object to ensure the required data
675 wait (cooked_state::CACHE_DONE
);
677 /* Remove our entry from the global list. See the assert in the
678 constructor to understand this. */
679 gdb_assert (is_main_thread ());
680 active_vectors
.erase (this);
683 /* See cooked-index.h. */
686 cooked_index::lookup (unrelocated_addr addr
)
688 /* Ensure that the address maps are ready. */
689 wait (cooked_state::MAIN_AVAILABLE
, true);
690 for (const auto &index
: m_vector
)
692 dwarf2_per_cu_data
*result
= index
->lookup (addr
);
693 if (result
!= nullptr)
699 /* See cooked-index.h. */
701 std::vector
<const addrmap
*>
702 cooked_index::get_addrmaps ()
704 /* Ensure that the address maps are ready. */
705 wait (cooked_state::MAIN_AVAILABLE
, true);
706 std::vector
<const addrmap
*> result
;
707 for (const auto &index
: m_vector
)
708 result
.push_back (index
->m_addrmap
);
712 /* See cooked-index.h. */
715 cooked_index::find (const std::string
&name
, bool completing
)
717 wait (cooked_state::FINALIZED
, true);
718 std::vector
<cooked_index_shard::range
> result_range
;
719 result_range
.reserve (m_vector
.size ());
720 for (auto &entry
: m_vector
)
721 result_range
.push_back (entry
->find (name
, completing
));
722 return range (std::move (result_range
));
725 /* See cooked-index.h. */
728 cooked_index::get_main_name (struct obstack
*obstack
, enum language
*lang
)
731 const cooked_index_entry
*entry
= get_main ();
732 if (entry
== nullptr)
736 return entry
->full_name (obstack
, true);
739 /* See cooked_index.h. */
741 const cooked_index_entry
*
742 cooked_index::get_main () const
744 const cooked_index_entry
*best_entry
= nullptr;
745 for (const auto &index
: m_vector
)
747 const cooked_index_entry
*entry
= index
->get_main ();
748 /* Choose the first "main" we see. We only do this for names
749 not requiring canonicalization. At this point in the process
750 names might not have been canonicalized. However, currently,
751 languages that require this step also do not use
752 DW_AT_main_subprogram. An assert is appropriate here because
753 this filtering is done in get_main. */
754 if (entry
!= nullptr)
756 if ((entry
->flags
& IS_MAIN
) != 0)
758 if (!language_requires_canonicalization (entry
->lang
))
760 /* There won't be one better than this. */
766 /* This is one that is named "main". Here we don't care
767 if the language requires canonicalization, due to how
768 the entry is detected. Entries like this have worse
769 priority than IS_MAIN entries. */
770 if (best_entry
== nullptr)
779 quick_symbol_functions_up
780 cooked_index::make_quick_functions () const
782 return quick_symbol_functions_up (new cooked_index_functions
);
785 /* See cooked-index.h. */
788 cooked_index::dump (gdbarch
*arch
)
790 auto_obstack temp_storage
;
792 gdb_printf (" entries:\n");
796 for (const cooked_index_entry
*entry
: this->all_entries ())
800 gdb_printf (" [%zu] ((cooked_index_entry *) %p)\n", i
++, entry
);
801 gdb_printf (" name: %s\n", entry
->name
);
802 gdb_printf (" canonical: %s\n", entry
->canonical
);
803 gdb_printf (" qualified: %s\n", entry
->full_name (&temp_storage
, false));
804 gdb_printf (" DWARF tag: %s\n", dwarf_tag_name (entry
->tag
));
805 gdb_printf (" flags: %s\n", to_string (entry
->flags
).c_str ());
806 gdb_printf (" DIE offset: %s\n", sect_offset_str (entry
->die_offset
));
808 if ((entry
->flags
& IS_PARENT_DEFERRED
) != 0)
809 gdb_printf (" parent: deferred (%" PRIx64
")\n",
810 entry
->get_deferred_parent ());
811 else if (entry
->get_parent () != nullptr)
812 gdb_printf (" parent: ((cooked_index_entry *) %p) [%s]\n",
813 entry
->get_parent (), entry
->get_parent ()->name
);
815 gdb_printf (" parent: ((cooked_index_entry *) 0)\n");
820 const cooked_index_entry
*main_entry
= this->get_main ();
821 if (main_entry
!= nullptr)
822 gdb_printf (" main: ((cooked_index_entry *) %p) [%s]\n", main_entry
,
825 gdb_printf (" main: ((cooked_index_entry *) 0)\n");
828 gdb_printf (" address maps:\n");
831 std::vector
<const addrmap
*> addrmaps
= this->get_addrmaps ();
832 for (i
= 0; i
< addrmaps
.size (); ++i
)
834 const addrmap
&addrmap
= *addrmaps
[i
];
836 gdb_printf (" [%zu] ((addrmap *) %p)\n", i
, &addrmap
);
839 addrmap
.foreach ([arch
] (CORE_ADDR start_addr
, const void *obj
)
843 const char *start_addr_str
= paddress (arch
, start_addr
);
847 const dwarf2_per_cu_data
*per_cu
848 = static_cast<const dwarf2_per_cu_data
*> (obj
);
849 gdb_printf (" [%s] ((dwarf2_per_cu_data *) %p)\n",
850 start_addr_str
, per_cu
);
853 gdb_printf (" [%s] ((dwarf2_per_cu_data *) 0)\n",
863 /* Wait for all the index cache entries to be written before gdb
866 wait_for_index_cache (int)
868 gdb_assert (is_main_thread ());
869 for (cooked_index
*item
: active_vectors
)
870 item
->wait_completely ();
873 /* A maint command to wait for the cache. */
876 maintenance_wait_for_index_cache (const char *args
, int from_tty
)
878 wait_for_index_cache (0);
881 void _initialize_cooked_index ();
883 _initialize_cooked_index ()
886 selftests::register_test ("cooked_index_entry::compare", test_compare
);
889 add_cmd ("wait-for-index-cache", class_maintenance
,
890 maintenance_wait_for_index_cache
, _("\
891 Wait until all pending writes to the index cache have completed.\n\
892 Usage: maintenance wait-for-index-cache"),
895 gdb::observers::gdb_exiting
.attach (wait_for_index_cache
, "cooked-index");