diff --git a/gdb/remote.c b/gdb/remote.c index 6914947c172..fde6df3f84d 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -1016,13 +1016,20 @@ struct stop_reply : public notif_event int core; }; +/* Return TARGET as a remote_target if it is one, else nullptr. */ + +static remote_target * +as_remote_target (process_stratum_target *target) +{ + return dynamic_cast (target); +} + /* See remote.h. */ bool is_remote_target (process_stratum_target *target) { - remote_target *rt = dynamic_cast (target); - return rt != nullptr; + return as_remote_target (target) != nullptr; } /* Per-program-space data key. */ @@ -5116,13 +5123,10 @@ remote_target::remote_check_symbols () char *tmp; int end; - /* The remote side has no concept of inferiors that aren't running - yet, it only knows about running processes. If we're connected - but our current inferior is not running, we should not invite the - remote target to request symbol lookups related to its - (unrelated) current process. */ - if (!target_has_execution ()) - return; + /* It doesn't make sense to send a qSymbol packet for an inferior that + doesn't have execution, because the remote side doesn't know about + inferiors without execution. */ + gdb_assert (target_has_execution ()); if (packet_support (PACKET_qSymbol) == PACKET_DISABLE) return; @@ -14575,28 +14579,55 @@ show_remote_cmd (const char *args, int from_tty) static void remote_new_objfile (struct objfile *objfile) { - remote_target *remote = get_current_remote_target (); + /* The objfile change happened in that program space. */ + program_space *pspace = current_program_space; - /* First, check whether the current inferior's process target is a remote - target. */ - if (remote == nullptr) - return; + /* The affected program space is possibly shared by multiple inferiors. + Consider sending a qSymbol packet for each of the inferiors using that + program space. */ + for (inferior *inf : all_inferiors ()) + { + if (inf->pspace != pspace) + continue; - /* When we are attaching or handling a fork child and the shared library - subsystem reads the list of loaded libraries, we receive new objfile - events in between each found library. The libraries are read in an - undefined order, so if we gave the remote side a chance to look up - symbols between each objfile, we might give it an inconsistent picture - of the inferior. It could appear that a library A appears loaded but - a library B does not, even though library A requires library B. That - would present a state that couldn't normally exist in the inferior. - - So, skip these events, we'll give the remote a chance to look up symbols - once all the loaded libraries and their symbols are known to GDB. */ - if (current_inferior ()->in_initial_library_scan) - return; + /* Check whether the inferior's process target is a remote target. */ + remote_target *remote = as_remote_target (inf->process_target ()); + if (remote == nullptr) + continue; + + /* When we are attaching or handling a fork child and the shared library + subsystem reads the list of loaded libraries, we receive new objfile + events in between each found library. The libraries are read in an + undefined order, so if we gave the remote side a chance to look up + symbols between each objfile, we might give it an inconsistent picture + of the inferior. It could appear that a library A appears loaded but + a library B does not, even though library A requires library B. That + would present a state that couldn't normally exist in the inferior. + + So, skip these events, we'll give the remote a chance to look up + symbols once all the loaded libraries and their symbols are known to + GDB. */ + if (inf->in_initial_library_scan) + continue; + + if (!remote->has_execution (inf)) + continue; + + /* Need to switch to a specific thread, because remote_check_symbols will + set the general thread using INFERIOR_PTID. - remote->remote_check_symbols (); + It's possible to have inferiors with no thread here, because we are + called very early in the connection process, while the inferior is + being set up, before threads are added. Just skip it, start_remote_1 + also calls remote_check_symbols when it's done setting things up. */ + thread_info *thread = any_thread_of_inferior (inf); + if (thread != nullptr) + { + scoped_restore_current_thread restore_thread; + switch_to_thread (thread); + remote->remote_check_symbols (); + } + } } /* Pull all the tracepoints defined on the target and create local