void rcmd (const char *command, struct ui_file *output) override;
- char *pid_to_exec_file (int pid) override;
+ const char *pid_to_exec_file (int pid) override;
void log_command (const char *cmd) override
{
char *append_resumption (char *p, char *endp,
ptid_t ptid, int step, gdb_signal siggnal);
- int remote_resume_with_vcont (ptid_t ptid, int step,
+ int remote_resume_with_vcont (ptid_t scope_ptid, int step,
gdb_signal siggnal);
thread_info *add_current_inferior_and_thread (const char *wait_status);
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<remote_target *> (target);
+}
+
/* See remote.h. */
bool
is_remote_target (process_stratum_target *target)
{
- remote_target *rt = dynamic_cast<remote_target *> (target);
- return rt != nullptr;
+ return as_remote_target (target) != nullptr;
}
/* Per-program-space data key. */
/* set/show remote NAME-packet {auto,on,off} -- legacy. */
if (legacy)
{
- /* It's not clear who should take ownership of this string, so, for
- now, make it static, and give copies to each of the add_alias_cmd
- calls below. */
- static gdb::unique_xmalloc_ptr<char> legacy_name
+ /* It's not clear who should take ownership of the LEGACY_NAME string
+ created below, so, for now, place the string into a static vector
+ which ensures the strings is released when GDB exits. */
+ static std::vector<gdb::unique_xmalloc_ptr<char>> legacy_names;
+ gdb::unique_xmalloc_ptr<char> legacy_name
= xstrprintf ("%s-packet", name);
add_alias_cmd (legacy_name.get (), cmds.set, class_obscure, 0,
&remote_set_cmdlist);
add_alias_cmd (legacy_name.get (), cmds.show, class_obscure, 0,
&remote_show_cmdlist);
+ legacy_names.emplace_back (std::move (legacy_name));
}
}
target_async (1);
}
- /* If we connected to a live target, do some additional setup. */
- if (target_has_execution ())
+ /* Give the target a chance to look up symbols. */
+ for (inferior *inf : all_inferiors (this))
{
+ /* The inferiors that exist at this point were created from what
+ was found already running on the remote side, so we know they
+ have execution. */
+ gdb_assert (this->has_execution (inf));
+
/* No use without a symbol-file. */
- if (current_program_space->symfile_object_file)
- remote_check_symbols ();
+ if (inf->pspace->symfile_object_file == nullptr)
+ continue;
+
+ /* Need to switch to a specific thread, because remote_check_symbols
+ uses INFERIOR_PTID to set the general thread. */
+ scoped_restore_current_thread restore_thread;
+ thread_info *thread = any_thread_of_inferior (inf);
+ switch_to_thread (thread);
+ this->remote_check_symbols ();
}
/* Possibly the target has been engaged in a trace run started
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;
else
{
int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
- CORE_ADDR sym_addr = BMSYMBOL_VALUE_ADDRESS (sym);
+ CORE_ADDR sym_addr = sym.value_address ();
/* If this is a function address, return the start of code
instead of any data function descriptor. */
thread to be resumed is PTID; STEP and SIGGNAL indicate whether the
resumed thread should be single-stepped and/or signalled. If PTID
equals minus_one_ptid, then all threads are resumed; if PTID
- represents a process, then all threads of the process are resumed;
- the thread to be stepped and/or signalled is given in the global
- INFERIOR_PTID. */
+ represents a process, then all threads of the process are
+ resumed. */
char *
remote_target::append_resumption (char *p, char *endp,
putpkt (buf);
}
-/* Resume the remote inferior by using a "vCont" packet. The thread
- to be resumed is PTID; STEP and SIGGNAL indicate whether the
- resumed thread should be single-stepped and/or signalled. If PTID
- equals minus_one_ptid, then all threads are resumed; the thread to
- be stepped and/or signalled is given in the global INFERIOR_PTID.
- This function returns non-zero iff it resumes the inferior.
+/* Resume the remote inferior by using a "vCont" packet. SCOPE_PTID,
+ STEP, and SIGGNAL have the same meaning as in target_resume. This
+ function returns non-zero iff it resumes the inferior.
This function issues a strict subset of all possible vCont commands
at the moment. */
int
-remote_target::remote_resume_with_vcont (ptid_t ptid, int step,
+remote_target::remote_resume_with_vcont (ptid_t scope_ptid, int step,
enum gdb_signal siggnal)
{
struct remote_state *rs = get_remote_state ();
p += xsnprintf (p, endp - p, "vCont");
- if (ptid == magic_null_ptid)
+ if (scope_ptid == magic_null_ptid)
{
/* MAGIC_NULL_PTID means that we don't have any active threads,
so we don't have any TID numbers the inferior will
a TID. */
append_resumption (p, endp, minus_one_ptid, step, siggnal);
}
- else if (ptid == minus_one_ptid || ptid.is_pid ())
+ else if (scope_ptid == minus_one_ptid || scope_ptid.is_pid ())
{
/* Resume all threads (of all processes, or of a single
process), with preference for INFERIOR_PTID. This assumes
/* Also pass down any pending signaled resumption for other
threads not the current. */
- p = append_pending_thread_resumptions (p, endp, ptid);
+ p = append_pending_thread_resumptions (p, endp, scope_ptid);
/* And continue others without a signal. */
- append_resumption (p, endp, ptid, /*step=*/ 0, GDB_SIGNAL_0);
+ append_resumption (p, endp, scope_ptid, /*step=*/ 0, GDB_SIGNAL_0);
}
else
{
- /* Scheduler locking; resume only PTID. */
- append_resumption (p, endp, ptid, step, siggnal);
+ /* Scheduler locking; resume only SCOPE_PTID. */
+ append_resumption (p, endp, scope_ptid, step, siggnal);
}
gdb_assert (strlen (rs->buf.data ()) < get_remote_packet_size ());
/* Tell the remote machine to resume. */
void
-remote_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal)
+remote_target::resume (ptid_t scope_ptid, int step, enum gdb_signal siggnal)
{
struct remote_state *rs = get_remote_state ();
able to do vCont action coalescing. */
if (target_is_non_stop_p () && ::execution_direction != EXEC_REVERSE)
{
- remote_thread_info *remote_thr;
-
- if (minus_one_ptid == ptid || ptid.is_pid ())
- remote_thr = get_remote_thread_info (this, inferior_ptid);
- else
- remote_thr = get_remote_thread_info (this, ptid);
+ remote_thread_info *remote_thr
+ = get_remote_thread_info (inferior_thread ());
/* We don't expect the core to ask to resume an already resumed (from
its point of view) thread. */
gdb_assert (remote_thr->get_resume_state () == resume_state::NOT_RESUMED);
remote_thr->set_resumed_pending_vcont (step, siggnal);
+
+ /* There's actually nothing that says that the core can't
+ request a wildcard resume in non-stop mode, though. It's
+ just that we know it doesn't currently, so we don't bother
+ with it. */
+ gdb_assert (scope_ptid == inferior_ptid);
return;
}
rs->last_resume_exec_dir = ::execution_direction;
/* Prefer vCont, and fallback to s/c/S/C, which use Hc. */
- if (!remote_resume_with_vcont (ptid, step, siggnal))
- remote_resume_with_hc (ptid, step, siggnal);
+ if (!remote_resume_with_vcont (scope_ptid, step, siggnal))
+ remote_resume_with_hc (scope_ptid, step, siggnal);
/* Update resumed state tracked by the remote target. */
- for (thread_info *tp : all_non_exited_threads (this, ptid))
+ for (thread_info *tp : all_non_exited_threads (this, scope_ptid))
get_remote_thread_info (tp)->set_resumed ();
/* We've just told the target to resume. The remote server will
if (strcmp (buf, "OK") == 0)
break;
if (strlen (buf) == 3 && buf[0] == 'E'
- && isdigit (buf[1]) && isdigit (buf[2]))
+ && isxdigit (buf[1]) && isxdigit (buf[2]))
{
error (_("Protocol error with Rcmd"));
}
warning (_("Target does not support fast tracepoints, "
"downloading %d as regular tracepoint"), b->number);
}
- else if (b->type == bp_static_tracepoint)
+ else if (b->type == bp_static_tracepoint
+ || b->type == bp_static_marker_tracepoint)
{
/* Only test for support at download time; we may not know
target capabilities at definition time. */
can be opened on the remote side to get the symbols for the child
process. Returns NULL if the operation is not supported. */
-char *
+const char *
remote_target::pid_to_exec_file (int pid)
{
static gdb::optional<gdb::char_vector> filename;
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;
- remote->remote_check_symbols ();
+ /* 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.
+
+ 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