#include "bfd.h"
#include "symfile.h"
#include "target.h"
+#include "process-stratum-target.h"
/*#include "terminal.h" */
#include "gdbcmd.h"
#include "objfiles.h"
remote_doc
};
-class remote_target : public target_ops
+class remote_target : public process_stratum_target
{
public:
- remote_target ()
- {
- to_stratum = process_stratum;
- }
+ remote_target () = default;
~remote_target () override;
const target_info &info () const override
CORE_ADDR load_module_addr,
CORE_ADDR offset) override;
- bool has_all_memory () override { return default_child_has_all_memory (); }
- bool has_memory () override { return default_child_has_memory (); }
- bool has_stack () override { return default_child_has_stack (); }
- bool has_registers () override { return default_child_has_registers (); }
- bool has_execution (ptid_t ptid) override { return default_child_has_execution (ptid); }
-
bool can_execute_reverse () override;
std::vector<mem_region> memory_map () override;
static void remote_async_inferior_event_handler (gdb_client_data);
-static int remote_read_description_p (struct target_ops *target);
+static bool remote_read_description_p (struct target_ops *target);
static void remote_console_output (char *msg);
show_memory_packet_size (&memory_write_packet_config);
}
+/* Show the number of hardware watchpoints that can be used. */
+
+static void
+show_hardware_watchpoint_limit (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c,
+ const char *value)
+{
+ fprintf_filtered (file, _("The maximum number of target hardware "
+ "watchpoints is %s.\n"), value);
+}
+
+/* Show the length limit (in bytes) for hardware watchpoints. */
+
+static void
+show_hardware_watchpoint_length_limit (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c,
+ const char *value)
+{
+ fprintf_filtered (file, _("The maximum length (in bytes) of a target "
+ "hardware watchpoint is %s.\n"), value);
+}
+
+/* Show the number of hardware breakpoints that can be used. */
+
+static void
+show_hardware_breakpoint_limit (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c,
+ const char *value)
+{
+ fprintf_filtered (file, _("The maximum number of target hardware "
+ "breakpoints is %s.\n"), value);
+}
+
long
remote_target::get_memory_write_packet_size ()
{
if (!in_thread_list (currthread))
{
struct inferior *inf = NULL;
- int pid = ptid_get_pid (currthread);
+ int pid = currthread.pid ();
- if (ptid_is_pid (inferior_ptid)
- && pid == ptid_get_pid (inferior_ptid))
+ if (inferior_ptid.is_pid ()
+ && pid == inferior_ptid.pid ())
{
/* inferior_ptid has no thread member yet. This can happen
with the vAttach -> remote_wait,"TAAthread:" path if the
stub doesn't support qC. This is the first stop reported
after an attach, so this is the main thread. Update the
ptid in the thread list. */
- if (in_thread_list (pid_to_ptid (pid)))
+ if (in_thread_list (ptid_t (pid)))
thread_change_ptid (inferior_ptid, currthread);
else
{
return;
}
- if (ptid_equal (magic_null_ptid, inferior_ptid))
+ if (magic_null_ptid == inferior_ptid)
{
/* inferior_ptid is not set yet. This can happen with the
vRun -> remote_wait,"TAAthread:" path if the stub
extended-remote which already was debugging an inferior, we
may not know about it yet. Add it before adding its child
thread, so notifications are emitted in a sensible order. */
- if (find_inferior_pid (ptid_get_pid (currthread)) == NULL)
+ if (find_inferior_pid (currthread.pid ()) == NULL)
{
struct remote_state *rs = get_remote_state ();
int fake_pid_p = !remote_multi_process_p (rs);
inf = remote_add_inferior (fake_pid_p,
- ptid_get_pid (currthread), -1, 1);
+ currthread.pid (), -1, 1);
}
/* This is really a new thread. Add it. */
char *buf = rs->buf;
char *endbuf = rs->buf + get_remote_packet_size ();
- if (ptid_equal (state, ptid))
+ if (state == ptid)
return;
*buf++ = 'H';
*buf++ = gen ? 'g' : 'c';
- if (ptid_equal (ptid, magic_null_ptid))
+ if (ptid == magic_null_ptid)
xsnprintf (buf, endbuf - buf, "0");
- else if (ptid_equal (ptid, any_thread_ptid))
+ else if (ptid == any_thread_ptid)
xsnprintf (buf, endbuf - buf, "0");
- else if (ptid_equal (ptid, minus_one_ptid))
+ else if (ptid == minus_one_ptid)
xsnprintf (buf, endbuf - buf, "-1");
else
write_ptid (buf, endbuf, ptid);
/* We only need to change the remote current thread if it's pointing
at some other process. */
- if (ptid_get_pid (rs->general_thread) != ptid_get_pid (inferior_ptid))
+ if (rs->general_thread.pid () != inferior_ptid.pid ())
set_general_thread (inferior_ptid);
}
static int
remote_thread_always_alive (ptid_t ptid)
{
- if (ptid_equal (ptid, magic_null_ptid))
+ if (ptid == magic_null_ptid)
/* The main thread is always alive. */
return 1;
- if (ptid_get_pid (ptid) != 0 && ptid_get_lwp (ptid) == 0)
+ if (ptid.pid () != 0 && ptid.lwp () == 0)
/* The main thread is always alive. This can happen after a
vAttach, if the remote side doesn't support
multi-threading. */
if (remote_multi_process_p (rs))
{
- pid = ptid_get_pid (ptid);
+ pid = ptid.pid ();
if (pid < 0)
buf += xsnprintf (buf, endbuf - buf, "p-%x.", -pid);
else
buf += xsnprintf (buf, endbuf - buf, "p%x.", pid);
}
- tid = ptid_get_lwp (ptid);
+ tid = ptid.lwp ();
if (tid < 0)
buf += xsnprintf (buf, endbuf - buf, "-%x", -tid);
else
pp = unpack_varlen_hex (p + 1, &tid);
if (obuf)
*obuf = pp;
- return ptid_build (pid, tid, 0);
+ return ptid_t (pid, tid, 0);
}
/* No multi-process. Just a tid. */
what's in inferior_ptid, unless it's null at this point. If so,
then since there's no way to know the pid of the reported
threads, use the magic number. */
- if (ptid_equal (inferior_ptid, null_ptid))
- pid = ptid_get_pid (magic_null_ptid);
+ if (inferior_ptid == null_ptid)
+ pid = magic_null_ptid.pid ();
else
- pid = ptid_get_pid (inferior_ptid);
+ pid = inferior_ptid.pid ();
if (obuf)
*obuf = pp;
- return ptid_build (pid, tid, 0);
+ return ptid_t (pid, tid, 0);
}
static int
|| remote_get_threads_with_qthreadinfo (&context)
|| remote_get_threads_with_ql (&context))
{
- struct thread_info *tp, *tmp;
-
got_list = 1;
if (context.items.empty ()
/* CONTEXT now holds the current thread list on the remote
target end. Delete GDB-side threads no longer found on the
target. */
- ALL_THREADS_SAFE (tp, tmp)
+ for (thread_info *tp : all_threads_safe ())
{
if (!context.contains_thread (tp->ptid))
{
remote_target::extra_thread_info (thread_info *tp)
{
struct remote_state *rs = get_remote_state ();
- int result;
int set;
threadref id;
struct gdb_ext_thread_info threadinfo;
- static char display_buf[100]; /* arbitrary... */
- int n = 0; /* position in display_buf */
if (rs->remote_desc == 0) /* paranoia */
internal_error (__FILE__, __LINE__,
_("remote_threads_extra_info"));
- if (ptid_equal (tp->ptid, magic_null_ptid)
- || (ptid_get_pid (tp->ptid) != 0 && ptid_get_lwp (tp->ptid) == 0))
+ if (tp->ptid == magic_null_ptid
+ || (tp->ptid.pid () != 0 && tp->ptid.lwp () == 0))
/* This is the main thread which was added by GDB. The remote
server doesn't know about it. */
return NULL;
+ std::string &extra = get_remote_thread_info (tp)->extra;
+
+ /* If already have cached info, use it. */
+ if (!extra.empty ())
+ return extra.c_str ();
+
if (packet_support (PACKET_qXfer_threads) == PACKET_ENABLE)
{
- if (tp->priv != NULL)
- {
- const std::string &extra = get_remote_thread_info (tp)->extra;
- return !extra.empty () ? extra.c_str () : NULL;
- }
- else
- return NULL;
+ /* If we're using qXfer:threads:read, then the extra info is
+ included in the XML. So if we didn't have anything cached,
+ it's because there's really no extra info. */
+ return NULL;
}
if (rs->use_threadextra_query)
getpkt (&rs->buf, &rs->buf_size, 0);
if (rs->buf[0] != 0)
{
- n = std::min (strlen (rs->buf) / 2, sizeof (display_buf));
- result = hex2bin (rs->buf, (gdb_byte *) display_buf, n);
- display_buf [result] = '\0';
- return display_buf;
+ extra.resize (strlen (rs->buf) / 2);
+ hex2bin (rs->buf, (gdb_byte *) &extra[0], extra.size ());
+ return extra.c_str ();
}
}
rs->use_threadextra_query = 0;
set = TAG_THREADID | TAG_EXISTS | TAG_THREADNAME
| TAG_MOREDISPLAY | TAG_DISPLAY;
- int_to_threadref (&id, ptid_get_lwp (tp->ptid));
+ int_to_threadref (&id, tp->ptid.lwp ());
if (remote_get_threadinfo (&id, set, &threadinfo))
if (threadinfo.active)
{
if (*threadinfo.shortname)
- n += xsnprintf (&display_buf[0], sizeof (display_buf) - n,
- " Name: %s,", threadinfo.shortname);
+ string_appendf (extra, " Name: %s", threadinfo.shortname);
if (*threadinfo.display)
- n += xsnprintf (&display_buf[n], sizeof (display_buf) - n,
- " State: %s,", threadinfo.display);
+ {
+ if (!extra.empty ())
+ extra += ',';
+ string_appendf (extra, " State: %s", threadinfo.display);
+ }
if (*threadinfo.more_display)
- n += xsnprintf (&display_buf[n], sizeof (display_buf) - n,
- " Priority: %s", threadinfo.more_display);
-
- if (n > 0)
{
- /* For purely cosmetic reasons, clear up trailing commas. */
- if (',' == display_buf[n-1])
- display_buf[n-1] = ' ';
- return display_buf;
+ if (!extra.empty ())
+ extra += ',';
+ string_appendf (extra, " Priority: %s", threadinfo.more_display);
}
+ return extra.c_str ();
}
return NULL;
}
ptid_t
remote_target::get_ada_task_ptid (long lwp, long thread)
{
- return ptid_build (ptid_get_pid (inferior_ptid), lwp, 0);
+ return ptid_t (inferior_ptid.pid (), lwp, 0);
}
\f
this point. */
if (wait_status != NULL)
ptid = stop_reply_extract_thread (wait_status);
- if (ptid_equal (ptid, null_ptid))
+ if (ptid == null_ptid)
ptid = remote_current_thread (inferior_ptid);
return ptid;
fake_pid_p = 1;
}
- remote_add_inferior (fake_pid_p, ptid_get_pid (curr_ptid), -1, 1);
+ remote_add_inferior (fake_pid_p, curr_ptid.pid (), -1, 1);
/* Add the main thread and switch to it. Don't try reading
registers yet, since we haven't fetched the target description
remote_target::process_initial_stop_replies (int from_tty)
{
int pending_stop_replies = stop_reply_queue_length ();
- struct inferior *inf;
- struct thread_info *thread;
struct thread_info *selected = NULL;
struct thread_info *lowest_stopped = NULL;
struct thread_info *first = NULL;
ptid_t event_ptid;
struct target_waitstatus ws;
int ignore_event = 0;
- struct thread_info *thread;
memset (&ws, 0, sizeof (ws));
event_ptid = target_wait (waiton_ptid, &ws, TARGET_WNOHANG);
if (ignore_event)
continue;
- thread = find_thread_ptid (event_ptid);
+ struct thread_info *evthread = find_thread_ptid (event_ptid);
if (ws.kind == TARGET_WAITKIND_STOPPED)
{
instead of signal 0. Suppress it. */
if (sig == GDB_SIGNAL_TRAP)
sig = GDB_SIGNAL_0;
- thread->suspend.stop_signal = sig;
+ evthread->suspend.stop_signal = sig;
ws.value.sig = sig;
}
- thread->suspend.waitstatus = ws;
+ evthread->suspend.waitstatus = ws;
if (ws.kind != TARGET_WAITKIND_STOPPED
|| ws.value.sig != GDB_SIGNAL_0)
- thread->suspend.waitstatus_pending_p = 1;
+ evthread->suspend.waitstatus_pending_p = 1;
set_executing (event_ptid, 0);
set_running (event_ptid, 0);
- get_remote_thread_info (thread)->vcont_resumed = 0;
+ get_remote_thread_info (evthread)->vcont_resumed = 0;
}
/* "Notice" the new inferiors before anything related to
registers/memory. */
- ALL_INFERIORS (inf)
+ for (inferior *inf : all_non_exited_inferiors ())
{
- if (inf->pid == 0)
- continue;
-
inf->needs_setup = 1;
if (non_stop)
{
- thread = any_live_thread_of_inferior (inf);
+ thread_info *thread = any_live_thread_of_inferior (inf);
notice_new_inferior (thread, thread->state == THREAD_RUNNING,
from_tty);
}
/* If all threads of an inferior were already stopped, we
haven't setup the inferior yet. */
- ALL_INFERIORS (inf)
+ for (inferior *inf : all_non_exited_inferiors ())
{
- if (inf->pid == 0)
- continue;
-
if (inf->needs_setup)
{
- thread = any_live_thread_of_inferior (inf);
+ thread_info *thread = any_live_thread_of_inferior (inf);
switch_to_thread_no_regs (thread);
setup_inferior (0);
}
/* Now go over all threads that are stopped, and print their current
frame. If all-stop, then if there's a signalled thread, pick
that as current. */
- ALL_NON_EXITED_THREADS (thread)
+ for (thread_info *thread : all_non_exited_threads ())
{
if (first == NULL)
first = thread;
others with their status pending. */
if (!non_stop)
{
- thread = selected;
+ thread_info *thread = selected;
if (thread == NULL)
thread = lowest_stopped;
if (thread == NULL)
}
/* For "info program". */
- thread = inferior_thread ();
+ thread_info *thread = inferior_thread ();
if (thread->state == THREAD_STOPPED)
set_last_target_status (inferior_ptid, thread->suspend.waitstatus);
}
multi-threaded program, this will ideally be the thread
that last reported an event before GDB disconnected. */
inferior_ptid = get_current_thread (wait_status);
- if (ptid_equal (inferior_ptid, null_ptid))
+ if (inferior_ptid == null_ptid)
{
/* Odd... The target was able to list threads, but not
tell us which thread was current (no "thread"
"warning: couldn't determine remote "
"current thread; picking first in list.\n");
- inferior_ptid = thread_list->ptid;
+ inferior_ptid = inferior_list->thread_list->ptid;
}
}
/* First delete any symbols previously loaded from shared libraries. */
no_shared_libraries (NULL, 0);
- /* Start afresh. */
- init_thread_list ();
-
/* Start the remote connection. If error() or QUIT, discard this
target (we'd otherwise be in an inconsistent state) and then
propogate the error on up the exception chain. This ensures that
{
struct remote_state *rs = get_remote_state ();
+ /* This should not be necessary, but the handling for D;PID in
+ GDBserver versions prior to 8.2 incorrectly assumes that the
+ selected process points to the same process we're detaching,
+ leading to misbehavior (and possibly GDBserver crashing) when it
+ does not. Since it's easy and cheap, work around it by forcing
+ GDBserver to select GDB's current process. */
+ set_general_process ();
+
if (remote_multi_process_p (rs))
xsnprintf (rs->buf, get_remote_packet_size (), "D;%x", pid);
else
void
remote_target::remote_detach_1 (inferior *inf, int from_tty)
{
- int pid = ptid_get_pid (inferior_ptid);
+ int pid = inferior_ptid.pid ();
struct remote_state *rs = get_remote_state ();
int is_fork_parent;
{
/* Save the pid as a string before mourning, since that will
unpush the remote target, and we need the string after. */
- std::string infpid = target_pid_to_str (pid_to_ptid (pid));
+ std::string infpid = target_pid_to_str (ptid_t (pid));
target_mourn_inferior (inferior_ptid);
if (print_inferior_events)
pid_t child_pid;
child_ptid = inferior_thread ()->pending_follow.value.related_pid;
- child_pid = ptid_get_pid (child_ptid);
+ child_pid = child_ptid.pid ();
remote_detach_pid (child_pid);
}
if (exec_file)
printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
- target_pid_to_str (pid_to_ptid (pid)));
+ target_pid_to_str (ptid_t (pid)));
else
printf_unfiltered (_("Attaching to %s\n"),
- target_pid_to_str (pid_to_ptid (pid)));
+ target_pid_to_str (ptid_t (pid)));
gdb_flush (gdb_stdout);
}
}
else if (strcmp (rs->buf, "OK") != 0)
error (_("Attaching to %s failed with: %s"),
- target_pid_to_str (pid_to_ptid (pid)),
+ target_pid_to_str (ptid_t (pid)),
rs->buf);
break;
case PACKET_UNKNOWN:
error (_("This target does not support attaching to a process"));
default:
error (_("Attaching to %s failed"),
- target_pid_to_str (pid_to_ptid (pid)));
+ target_pid_to_str (ptid_t (pid)));
}
set_current_inferior (remote_add_inferior (0, pid, 1, 0));
- inferior_ptid = pid_to_ptid (pid);
+ inferior_ptid = ptid_t (pid);
if (target_is_non_stop_p ())
{
if (thread)
inferior_ptid = thread->ptid;
else
- inferior_ptid = pid_to_ptid (pid);
+ inferior_ptid = ptid_t (pid);
/* Invalidate our notion of the remote current thread. */
record_currthread (rs, minus_one_ptid);
threads with a wildcard (though the protocol allows it,
so stubs shouldn't make an active effort to forbid
it). */
- && !(remote_multi_process_p (rs) && ptid_is_pid (ptid)))
+ && !(remote_multi_process_p (rs) && ptid.is_pid ()))
{
struct thread_info *tp;
- if (ptid_equal (ptid, minus_one_ptid))
+ if (ptid == minus_one_ptid)
{
/* If we don't know about the target thread's tid, then
we're resuming magic_null_ptid (see caller). */
else
p += xsnprintf (p, endp - p, ";c");
- if (remote_multi_process_p (rs) && ptid_is_pid (ptid))
+ if (remote_multi_process_p (rs) && ptid.is_pid ())
{
ptid_t nptid;
/* All (-1) threads of process. */
- nptid = ptid_build (ptid_get_pid (ptid), -1, 0);
+ nptid = ptid_t (ptid.pid (), -1, 0);
p += xsnprintf (p, endp - p, ":");
p = write_ptid (p, endp, nptid);
}
- else if (!ptid_equal (ptid, minus_one_ptid))
+ else if (ptid != minus_one_ptid)
{
p += xsnprintf (p, endp - p, ":");
p = write_ptid (p, endp, ptid);
remote_target::append_pending_thread_resumptions (char *p, char *endp,
ptid_t ptid)
{
- struct thread_info *thread;
-
- ALL_NON_EXITED_THREADS (thread)
- if (ptid_match (thread->ptid, ptid)
- && !ptid_equal (inferior_ptid, thread->ptid)
+ for (thread_info *thread : all_non_exited_threads (ptid))
+ if (inferior_ptid != thread->ptid
&& thread->suspend.stop_signal != GDB_SIGNAL_0)
{
p = append_resumption (p, endp, thread->ptid,
gdb_signal siggnal)
{
struct remote_state *rs = get_remote_state ();
- struct thread_info *thread;
char *buf;
rs->last_sent_signal = siggnal;
/* The c/s/C/S resume packets use Hc, so set the continue
thread. */
- if (ptid_equal (ptid, minus_one_ptid))
+ if (ptid == minus_one_ptid)
set_continue_thread (any_thread_ptid);
else
set_continue_thread (ptid);
- ALL_NON_EXITED_THREADS (thread)
+ for (thread_info *thread : all_non_exited_threads ())
resume_clear_thread_private_info (thread);
buf = rs->buf;
p += xsnprintf (p, endp - p, "vCont");
- if (ptid_equal (ptid, magic_null_ptid))
+ if (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_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
+ else if (ptid == minus_one_ptid || ptid.is_pid ())
{
/* Resume all threads (of all processes, or of a single
process), with preference for INFERIOR_PTID. This assumes
{
remote_thread_info *remote_thr;
- if (ptid_equal (minus_one_ptid, ptid) || ptid_is_pid (ptid))
+ if (minus_one_ptid == ptid || ptid.is_pid ())
remote_thr = get_remote_thread_info (inferior_ptid);
else
remote_thr = get_remote_thread_info (ptid);
void
remote_target::commit_resume ()
{
- struct inferior *inf;
- struct thread_info *tp;
int any_process_wildcard;
int may_global_wildcard_vcont;
may_global_wildcard_vcont = 1;
/* And assume every process is individually wildcard-able too. */
- ALL_NON_EXITED_INFERIORS (inf)
+ for (inferior *inf : all_non_exited_inferiors ())
{
remote_inferior *priv = get_remote_inferior (inf);
disable process and global wildcard resumes appropriately. */
check_pending_events_prevent_wildcard_vcont (&may_global_wildcard_vcont);
- ALL_NON_EXITED_THREADS (tp)
+ for (thread_info *tp : all_non_exited_threads ())
{
/* If a thread of a process is not meant to be resumed, then we
can't wildcard that process. */
struct vcont_builder vcont_builder (this);
/* Threads first. */
- ALL_NON_EXITED_THREADS (tp)
+ for (thread_info *tp : all_non_exited_threads ())
{
remote_thread_info *remote_thr = get_remote_thread_info (tp);
supposed to be resumed. */
any_process_wildcard = 0;
- ALL_NON_EXITED_INFERIORS (inf)
+ for (inferior *inf : all_non_exited_inferiors ())
{
if (get_remote_inferior (inf)->may_wildcard_vcont)
{
}
else
{
- ALL_NON_EXITED_INFERIORS (inf)
+ for (inferior *inf : all_non_exited_inferiors ())
{
if (get_remote_inferior (inf)->may_wildcard_vcont)
{
- vcont_builder.push_action (pid_to_ptid (inf->pid),
+ vcont_builder.push_action (ptid_t (inf->pid),
false, GDB_SIGNAL_0);
}
}
if (!rs->supports_vCont.t)
error (_("Remote server does not support stopping threads"));
- if (ptid_equal (ptid, minus_one_ptid)
- || (!remote_multi_process_p (rs) && ptid_is_pid (ptid)))
+ if (ptid == minus_one_ptid
+ || (!remote_multi_process_p (rs) && ptid.is_pid ()))
p += xsnprintf (p, endp - p, "vCont;t");
else
{
p += xsnprintf (p, endp - p, "vCont;t:");
- if (ptid_is_pid (ptid))
+ if (ptid.is_pid ())
/* All (-1) threads of process. */
- nptid = ptid_build (ptid_get_pid (ptid), -1, 0);
+ nptid = ptid_t (ptid.pid (), -1, 0);
else
{
/* Small optimization: if we already have a stop reply for
if (ws->kind == TARGET_WAITKIND_FORKED
|| ws->kind == TARGET_WAITKIND_VFORKED)
{
- if (event_pid == -1 || event_pid == ptid_get_pid (thread_ptid))
+ if (event_pid == -1 || event_pid == thread_ptid.pid ())
return 1;
}
void
remote_target::remove_new_fork_children (threads_listing_context *context)
{
- struct thread_info * thread;
int pid = -1;
struct notif_client *notif = ¬if_client_stop;
/* For any threads stopped at a fork event, remove the corresponding
fork child threads from the CONTEXT list. */
- ALL_NON_EXITED_THREADS (thread)
+ for (thread_info *thread : all_non_exited_threads ())
{
struct target_waitstatus *ws = thread_pending_fork_status (thread);
reply = (struct stop_reply *) rns->pending_event[notif_client_stop.id];
/* Discard the in-flight notification. */
- if (reply != NULL && ptid_get_pid (reply->ptid) == inf->pid)
+ if (reply != NULL && reply->ptid.pid () == inf->pid)
{
stop_reply_xfree (reply);
rns->pending_event[notif_client_stop.id] = NULL;
break;
case 'w': /* Thread exited. */
{
- const char *p;
ULONGEST value;
event->ws.kind = TARGET_WAITKIND_THREAD_EXITED;
case 'W': /* Target exited. */
case 'X':
{
- const char *p;
int pid;
ULONGEST value;
}
/* If no process is specified, assume inferior_ptid. */
- pid = ptid_get_pid (inferior_ptid);
+ pid = inferior_ptid.pid ();
if (*p == '\0')
;
else if (*p == ';')
}
else
error (_("unknown stop reply packet: %s"), buf);
- event->ptid = pid_to_ptid (pid);
+ event->ptid = ptid_t (pid);
}
break;
case 'N':
break;
}
- if (target_is_non_stop_p () && ptid_equal (event->ptid, null_ptid))
+ if (target_is_non_stop_p () && event->ptid == null_ptid)
error (_("No process or thread specified in stop reply: %s"), buf);
}
/* If no thread/process was reported by the stub, assume the current
inferior. */
- if (ptid_equal (ptid, null_ptid))
+ if (ptid == null_ptid)
ptid = inferior_ptid;
if (status->kind != TARGET_WAITKIND_EXITED
break;
case 'N': case 'T': case 'S': case 'X': case 'W':
{
- struct stop_reply *stop_reply;
-
/* There is a stop reply to handle. */
rs->waiting_for_stop_reply = 0;
else if (status->kind != TARGET_WAITKIND_EXITED
&& status->kind != TARGET_WAITKIND_SIGNALLED)
{
- if (!ptid_equal (event_ptid, null_ptid))
+ if (event_ptid != null_ptid)
record_currthread (rs, event_ptid);
else
event_ptid = inferior_ptid;
va_start (ap, format);
rs->buf[0] = '\0';
- if (vsnprintf (rs->buf, max_size, format, ap) >= max_size)
+ int size = vsnprintf (rs->buf, max_size, format, ap);
+
+ va_end (ap);
+
+ if (size >= max_size)
internal_error (__FILE__, __LINE__, _("Too long remote packet."));
if (putpkt (rs->buf) < 0)
remote_target::kill_new_fork_children (int pid)
{
remote_state *rs = get_remote_state ();
- struct thread_info *thread;
struct notif_client *notif = ¬if_client_stop;
/* Kill the fork child threads of any threads in process PID
that are stopped at a fork event. */
- ALL_NON_EXITED_THREADS (thread)
+ for (thread_info *thread : all_non_exited_threads ())
{
struct target_waitstatus *ws = &thread->pending_follow;
remote_target::kill ()
{
int res = -1;
- int pid = ptid_get_pid (inferior_ptid);
+ int pid = inferior_ptid.pid ();
struct remote_state *rs = get_remote_state ();
if (packet_support (PACKET_vKill) != PACKET_DISABLE)
if (remote_exec_file[0])
error (_("Remote target does not support \"set remote exec-file\""));
if (!args.empty ())
- error (_("Remote target does not support \"set args\" or run <ARGS>"));
+ error (_("Remote target does not support \"set args\" or run ARGS"));
/* Fall back to "R". */
extended_remote_restart ();
}
- if (!have_inferiors ())
- {
- /* Clean up from the last time we ran, before we mark the target
- running again. This will mark breakpoints uninserted, and
- get_offsets may insert breakpoints. */
- init_thread_list ();
- init_wait_for_inferior ();
- }
-
/* vRun's success return is a stop reply. */
stop_reply = run_worked ? rs->buf : NULL;
add_current_inferior_and_thread (stop_reply);
threadalive_test (const char *cmd, int tty)
{
int sample_thread = SAMPLE_THREAD;
- int pid = ptid_get_pid (inferior_ptid);
- ptid_t ptid = ptid_build (pid, sample_thread, 0);
+ int pid = inferior_ptid.pid ();
+ ptid_t ptid = ptid_t (pid, sample_thread, 0);
if (remote_thread_alive (ptid))
printf_filtered ("PASS: Thread alive test\n");
static char buf[64];
struct remote_state *rs = get_remote_state ();
- if (ptid_equal (ptid, null_ptid))
+ if (ptid == null_ptid)
return normal_pid_to_str (ptid);
- else if (ptid_is_pid (ptid))
+ else if (ptid.is_pid ())
{
/* Printing an inferior target id. */
}
else
{
- if (ptid_equal (magic_null_ptid, ptid))
+ if (magic_null_ptid == ptid)
xsnprintf (buf, sizeof buf, "Thread <main>");
else if (remote_multi_process_p (rs))
- if (ptid_get_lwp (ptid) == 0)
+ if (ptid.lwp () == 0)
return normal_pid_to_str (ptid);
else
xsnprintf (buf, sizeof buf, "Thread %d.%ld",
- ptid_get_pid (ptid), ptid_get_lwp (ptid));
+ ptid.pid (), ptid.lwp ());
else
xsnprintf (buf, sizeof buf, "Thread %ld",
- ptid_get_lwp (ptid));
+ ptid.lwp ());
return buf;
}
}
&remote_protocol_packets[PACKET_qGetTLSAddr]);
if (result == PACKET_OK)
{
- ULONGEST result;
+ ULONGEST addr;
- unpack_varlen_hex (rs->buf, &result);
- return result;
+ unpack_varlen_hex (rs->buf, &addr);
+ return addr;
}
else if (result == PACKET_UNKNOWN)
throw_error (TLS_GENERIC_ERROR,
&remote_protocol_packets[PACKET_qGetTIBAddr]);
if (result == PACKET_OK)
{
- ULONGEST result;
-
- unpack_varlen_hex (rs->buf, &result);
+ ULONGEST val;
+ unpack_varlen_hex (rs->buf, &val);
if (addr)
- *addr = (CORE_ADDR) result;
+ *addr = (CORE_ADDR) val;
return true;
}
else if (result == PACKET_UNKNOWN)
struct remote_g_packet_guess
{
+ remote_g_packet_guess (int bytes_, const struct target_desc *tdesc_)
+ : bytes (bytes_),
+ tdesc (tdesc_)
+ {
+ }
+
int bytes;
const struct target_desc *tdesc;
};
-typedef struct remote_g_packet_guess remote_g_packet_guess_s;
-DEF_VEC_O(remote_g_packet_guess_s);
-struct remote_g_packet_data
+struct remote_g_packet_data : public allocate_on_obstack
{
- VEC(remote_g_packet_guess_s) *guesses;
+ std::vector<remote_g_packet_guess> guesses;
};
static struct gdbarch_data *remote_g_packet_data_handle;
static void *
remote_g_packet_data_init (struct obstack *obstack)
{
- return OBSTACK_ZALLOC (obstack, struct remote_g_packet_data);
+ return new (obstack) remote_g_packet_data;
}
void
struct remote_g_packet_data *data
= ((struct remote_g_packet_data *)
gdbarch_data (gdbarch, remote_g_packet_data_handle));
- struct remote_g_packet_guess new_guess, *guess;
- int ix;
gdb_assert (tdesc != NULL);
- for (ix = 0;
- VEC_iterate (remote_g_packet_guess_s, data->guesses, ix, guess);
- ix++)
- if (guess->bytes == bytes)
+ for (const remote_g_packet_guess &guess : data->guesses)
+ if (guess.bytes == bytes)
internal_error (__FILE__, __LINE__,
_("Duplicate g packet description added for size %d"),
bytes);
- new_guess.bytes = bytes;
- new_guess.tdesc = tdesc;
- VEC_safe_push (remote_g_packet_guess_s, data->guesses, &new_guess);
+ data->guesses.emplace_back (bytes, tdesc);
}
-/* Return 1 if remote_read_description would do anything on this target
- and architecture, 0 otherwise. */
+/* Return true if remote_read_description would do anything on this target
+ and architecture, false otherwise. */
-static int
+static bool
remote_read_description_p (struct target_ops *target)
{
struct remote_g_packet_data *data
= ((struct remote_g_packet_data *)
gdbarch_data (target_gdbarch (), remote_g_packet_data_handle));
- if (!VEC_empty (remote_g_packet_guess_s, data->guesses))
- return 1;
-
- return 0;
+ return !data->guesses.empty ();
}
const struct target_desc *
/* Do not try this during initial connection, when we do not know
whether there is a running but stopped thread. */
- if (!target_has_execution || ptid_equal (inferior_ptid, null_ptid))
+ if (!target_has_execution || inferior_ptid == null_ptid)
return beneath ()->read_description ();
- if (!VEC_empty (remote_g_packet_guess_s, data->guesses))
+ if (!data->guesses.empty ())
{
- struct remote_g_packet_guess *guess;
- int ix;
int bytes = send_g_packet ();
- for (ix = 0;
- VEC_iterate (remote_g_packet_guess_s, data->guesses, ix, guess);
- ix++)
- if (guess->bytes == bytes)
- return guess->tdesc;
+ for (const remote_g_packet_guess &guess : data->guesses)
+ if (guess.bytes == bytes)
+ return guess.tdesc;
/* We discard the g packet. A minor optimization would be to
hold on to it, and fill the register cache once we have selected
void
remote_target::download_tracepoint (struct bp_location *loc)
{
-#define BUF_SIZE 2048
-
CORE_ADDR tpaddr;
char addrbuf[40];
- char buf[BUF_SIZE];
std::vector<std::string> tdp_actions;
std::vector<std::string> stepping_actions;
char *pkt;
struct breakpoint *b = loc->owner;
struct tracepoint *t = (struct tracepoint *) b;
struct remote_state *rs = get_remote_state ();
+ int ret;
+ const char *err_msg = _("Tracepoint packet too large for target.");
+ size_t size_left;
+
+ /* We use a buffer other than rs->buf because we'll build strings
+ across multiple statements, and other statements in between could
+ modify rs->buf. */
+ gdb::char_vector buf (get_remote_packet_size ());
encode_actions_rsp (loc, &tdp_actions, &stepping_actions);
tpaddr = loc->address;
sprintf_vma (addrbuf, tpaddr);
- xsnprintf (buf, BUF_SIZE, "QTDP:%x:%s:%c:%lx:%x", b->number,
- addrbuf, /* address */
- (b->enable_state == bp_enabled ? 'E' : 'D'),
- t->step_count, t->pass_count);
+ ret = snprintf (buf.data (), buf.size (), "QTDP:%x:%s:%c:%lx:%x",
+ b->number, addrbuf, /* address */
+ (b->enable_state == bp_enabled ? 'E' : 'D'),
+ t->step_count, t->pass_count);
+
+ if (ret < 0 || ret >= buf.size ())
+ error ("%s", err_msg);
+
/* Fast tracepoints are mostly handled by the target, but we can
tell the target how big of an instruction block should be moved
around. */
{
if (gdbarch_fast_tracepoint_valid_at (loc->gdbarch, tpaddr,
NULL))
- xsnprintf (buf + strlen (buf), BUF_SIZE - strlen (buf), ":F%x",
- gdb_insn_length (loc->gdbarch, tpaddr));
+ {
+ size_left = buf.size () - strlen (buf.data ());
+ ret = snprintf (buf.data () + strlen (buf.data ()),
+ size_left, ":F%x",
+ gdb_insn_length (loc->gdbarch, tpaddr));
+
+ if (ret < 0 || ret >= size_left)
+ error ("%s", err_msg);
+ }
else
/* If it passed validation at definition but fails now,
something is very wrong. */
struct static_tracepoint_marker marker;
if (target_static_tracepoint_marker_at (tpaddr, &marker))
- strcat (buf, ":S");
+ {
+ size_left = buf.size () - strlen (buf.data ());
+ ret = snprintf (buf.data () + strlen (buf.data ()),
+ size_left, ":S");
+
+ if (ret < 0 || ret >= size_left)
+ error ("%s", err_msg);
+ }
else
error (_("Static tracepoint not valid during download"));
}
capabilities at definition time. */
if (remote_supports_cond_tracepoints ())
{
- agent_expr_up aexpr = gen_eval_for_expr (tpaddr, loc->cond.get ());
- xsnprintf (buf + strlen (buf), BUF_SIZE - strlen (buf), ":X%x,",
- aexpr->len);
- pkt = buf + strlen (buf);
+ agent_expr_up aexpr = gen_eval_for_expr (tpaddr,
+ loc->cond.get ());
+
+ size_left = buf.size () - strlen (buf.data ());
+
+ ret = snprintf (buf.data () + strlen (buf.data ()),
+ size_left, ":X%x,", aexpr->len);
+
+ if (ret < 0 || ret >= size_left)
+ error ("%s", err_msg);
+
+ size_left = buf.size () - strlen (buf.data ());
+
+ /* Two bytes to encode each aexpr byte, plus the terminating
+ null byte. */
+ if (aexpr->len * 2 + 1 > size_left)
+ error ("%s", err_msg);
+
+ pkt = buf.data () + strlen (buf.data ());
+
for (int ndx = 0; ndx < aexpr->len; ++ndx)
pkt = pack_hex_byte (pkt, aexpr->buf[ndx]);
*pkt = '\0';
}
if (b->commands || *default_collect)
- strcat (buf, "-");
- putpkt (buf);
+ {
+ size_left = buf.size () - strlen (buf.data ());
+
+ ret = snprintf (buf.data () + strlen (buf.data ()),
+ size_left, "-");
+
+ if (ret < 0 || ret >= size_left)
+ error ("%s", err_msg);
+ }
+
+ putpkt (buf.data ());
remote_get_noisy_reply ();
if (strcmp (rs->buf, "OK"))
error (_("Target does not support tracepoints."));
{
QUIT; /* Allow user to bail out with ^C. */
- bool has_more = (action_it != tdp_actions.end ()
+ bool has_more = ((action_it + 1) != tdp_actions.end ()
|| !stepping_actions.empty ());
- xsnprintf (buf, BUF_SIZE, "QTDP:-%x:%s:%s%c",
- b->number, addrbuf, /* address */
- action_it->c_str (),
- has_more ? '-' : 0);
- putpkt (buf);
+ ret = snprintf (buf.data (), buf.size (), "QTDP:-%x:%s:%s%c",
+ b->number, addrbuf, /* address */
+ action_it->c_str (),
+ has_more ? '-' : 0);
+
+ if (ret < 0 || ret >= buf.size ())
+ error ("%s", err_msg);
+
+ putpkt (buf.data ());
remote_get_noisy_reply ();
if (strcmp (rs->buf, "OK"))
error (_("Error on target while setting tracepoints."));
}
- for (auto action_it = stepping_actions.begin ();
- action_it != stepping_actions.end (); action_it++)
- {
- QUIT; /* Allow user to bail out with ^C. */
-
- bool is_first = action_it == stepping_actions.begin ();
- bool has_more = action_it != stepping_actions.end ();
-
- xsnprintf (buf, BUF_SIZE, "QTDP:-%x:%s:%s%s%s",
- b->number, addrbuf, /* address */
- is_first ? "S" : "",
- action_it->c_str (),
- has_more ? "-" : "");
- putpkt (buf);
- remote_get_noisy_reply ();
- if (strcmp (rs->buf, "OK"))
- error (_("Error on target while setting tracepoints."));
- }
+ for (auto action_it = stepping_actions.begin ();
+ action_it != stepping_actions.end (); action_it++)
+ {
+ QUIT; /* Allow user to bail out with ^C. */
+
+ bool is_first = action_it == stepping_actions.begin ();
+ bool has_more = (action_it + 1) != stepping_actions.end ();
+
+ ret = snprintf (buf.data (), buf.size (), "QTDP:-%x:%s:%s%s%s",
+ b->number, addrbuf, /* address */
+ is_first ? "S" : "",
+ action_it->c_str (),
+ has_more ? "-" : "");
+
+ if (ret < 0 || ret >= buf.size ())
+ error ("%s", err_msg);
+
+ putpkt (buf.data ());
+ remote_get_noisy_reply ();
+ if (strcmp (rs->buf, "OK"))
+ error (_("Error on target while setting tracepoints."));
+ }
if (packet_support (PACKET_TracepointSource) == PACKET_ENABLE)
{
if (b->location != NULL)
{
- strcpy (buf, "QTDPsrc:");
+ ret = snprintf (buf.data (), buf.size (), "QTDPsrc:");
+
+ if (ret < 0 || ret >= buf.size ())
+ error ("%s", err_msg);
+
encode_source_string (b->number, loc->address, "at",
event_location_to_string (b->location.get ()),
- buf + strlen (buf), 2048 - strlen (buf));
- putpkt (buf);
+ buf.data () + strlen (buf.data ()),
+ buf.size () - strlen (buf.data ()));
+ putpkt (buf.data ());
remote_get_noisy_reply ();
if (strcmp (rs->buf, "OK"))
warning (_("Target does not support source download."));
}
if (b->cond_string)
{
- strcpy (buf, "QTDPsrc:");
+ ret = snprintf (buf.data (), buf.size (), "QTDPsrc:");
+
+ if (ret < 0 || ret >= buf.size ())
+ error ("%s", err_msg);
+
encode_source_string (b->number, loc->address,
- "cond", b->cond_string, buf + strlen (buf),
- 2048 - strlen (buf));
- putpkt (buf);
+ "cond", b->cond_string,
+ buf.data () + strlen (buf.data ()),
+ buf.size () - strlen (buf.data ()));
+ putpkt (buf.data ());
remote_get_noisy_reply ();
if (strcmp (rs->buf, "OK"))
warning (_("Target does not support source download."));
remote_target::remote_btrace_maybe_reopen ()
{
struct remote_state *rs = get_remote_state ();
- struct thread_info *tp;
int btrace_target_pushed = 0;
+#if !defined (HAVE_LIBIPT)
int warned = 0;
+#endif
scoped_restore_current_thread restore_thread;
- ALL_NON_EXITED_THREADS (tp)
+ for (thread_info *tp : all_non_exited_threads ())
{
set_general_thread (tp->ptid);
int handle_len,
inferior *inf)
{
- struct thread_info *tp;
-
- ALL_NON_EXITED_THREADS (tp)
+ for (thread_info *tp : all_non_exited_threads ())
{
remote_thread_info *priv = get_remote_thread_info (tp);
_("Show the maximum number of bytes per memory-read packet."),
&remote_show_cmdlist);
- add_setshow_zinteger_cmd ("hardware-watchpoint-limit", no_class,
+ add_setshow_zuinteger_unlimited_cmd ("hardware-watchpoint-limit", no_class,
&remote_hw_watchpoint_limit, _("\
Set the maximum number of target hardware watchpoints."), _("\
Show the maximum number of target hardware watchpoints."), _("\
-Specify a negative limit for unlimited."),
- NULL, NULL, /* FIXME: i18n: The maximum
- number of target hardware
- watchpoints is %s. */
- &remote_set_cmdlist, &remote_show_cmdlist);
- add_setshow_zinteger_cmd ("hardware-watchpoint-length-limit", no_class,
+Specify \"unlimited\" for unlimited hardware watchpoints."),
+ NULL, show_hardware_watchpoint_limit,
+ &remote_set_cmdlist,
+ &remote_show_cmdlist);
+ add_setshow_zuinteger_unlimited_cmd ("hardware-watchpoint-length-limit",
+ no_class,
&remote_hw_watchpoint_length_limit, _("\
Set the maximum length (in bytes) of a target hardware watchpoint."), _("\
Show the maximum length (in bytes) of a target hardware watchpoint."), _("\
-Specify a negative limit for unlimited."),
- NULL, NULL, /* FIXME: i18n: The maximum
- length (in bytes) of a target
- hardware watchpoint is %s. */
+Specify \"unlimited\" to allow watchpoints of unlimited size."),
+ NULL, show_hardware_watchpoint_length_limit,
&remote_set_cmdlist, &remote_show_cmdlist);
- add_setshow_zinteger_cmd ("hardware-breakpoint-limit", no_class,
+ add_setshow_zuinteger_unlimited_cmd ("hardware-breakpoint-limit", no_class,
&remote_hw_breakpoint_limit, _("\
Set the maximum number of target hardware breakpoints."), _("\
Show the maximum number of target hardware breakpoints."), _("\
-Specify a negative limit for unlimited."),
- NULL, NULL, /* FIXME: i18n: The maximum
- number of target hardware
- breakpoints is %s. */
+Specify \"unlimited\" for unlimited hardware breakpoints."),
+ NULL, show_hardware_breakpoint_limit,
&remote_set_cmdlist, &remote_show_cmdlist);
add_setshow_zuinteger_cmd ("remoteaddresssize", class_obscure,
/* Take advantage of the fact that the TID field is not used, to tag
special ptids with it set to != 0. */
- magic_null_ptid = ptid_build (42000, -1, 1);
- not_sent_ptid = ptid_build (42000, -2, 1);
- any_thread_ptid = ptid_build (42000, 0, 1);
+ magic_null_ptid = ptid_t (42000, -1, 1);
+ not_sent_ptid = ptid_t (42000, -2, 1);
+ any_thread_ptid = ptid_t (42000, 0, 1);
}