set_thread_exited (tp, 1);
inf->thread_list = NULL;
+ inf->thread_map.clear();
}
}
{
thread_info *tp = new thread_info (inf, ptid);
+ /* Add to thread_list linked list. */
if (inf->thread_list == NULL)
inf->thread_list = tp;
else
last->next = tp;
}
+ /* Add to ptid -> thread map. A non-exited thread with this ptid should not
+ exist yet. */
+ gdb_assert (inf->thread_map.find (ptid) == inf->thread_map.end ());
+ inf->thread_map[ptid] = tp;
+
return tp;
}
if (!tp)
return;
- set_thread_exited (tp, silent);
+ /* Remove from ptid -> thread map in any case, as it contains only non-exited
+ threads. */
+ if (tp->state != THREAD_EXITED)
+ {
+ /* If the thread is not exited yet, it is in the thread map, remove it. */
+ size_t nr_deleted = thr->inf->thread_map.erase (thr->ptid);
+
+ gdb_assert (nr_deleted == 1);
+
+ set_thread_exited (tp, silent);
+ }
+ else
+ {
+ /* If the thread is already marked as existed, it is not in the thread
+ map (but a more recent thread with the same ptid could be). */
+
+ /* Sanity check. */
+ for (const auto &item : thr->inf->thread_map)
+ gdb_assert (thr != item.second);
+ }
+
if (!tp->deletable ())
{
inf->pid = new_ptid.pid ();
tp = find_thread_ptid (inf, old_ptid);
+ gdb_assert (tp != nullptr);
+
+ /* Update entry in ptid -> thread map. */
+ int num_erased = inf->thread_map.erase (old_ptid);
+ gdb_assert (num_erased == 1);
+
tp->ptid = new_ptid;
+ inf->thread_map[new_ptid] = tp;
gdb::observers::thread_ptid_changed.notify (old_ptid, new_ptid);
}