X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fremote.c;h=082499e6e84644aa3c20d34d6b678f7c343186ae;hb=441af85bd9c68dbc0c2a1dbe23bf07c6cb3c3f5d;hp=4e2c85a223a4097166621059714dfeefe2ba0fa2;hpb=8d64371b6b710831ddfd6a8636097396040476ee;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/remote.c b/gdb/remote.c index 4e2c85a223..082499e6e8 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -1,6 +1,6 @@ /* Remote target communications for serial-line targets in custom GDB protocol - Copyright (C) 1988-2019 Free Software Foundation, Inc. + Copyright (C) 1988-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -28,7 +28,6 @@ #include "symfile.h" #include "target.h" #include "process-stratum-target.h" -/*#include "terminal.h" */ #include "gdbcmd.h" #include "objfiles.h" #include "gdb-stabs.h" @@ -43,12 +42,12 @@ #include "cli/cli-setshow.h" #include "target-descriptions.h" #include "gdb_bfd.h" -#include "filestuff.h" -#include "rsp-low.h" +#include "gdbsupport/filestuff.h" +#include "gdbsupport/rsp-low.h" #include "disasm.h" #include "location.h" -#include "gdb_sys_time.h" +#include "gdbsupport/gdb_sys_time.h" #include "event-loop.h" #include "event-top.h" @@ -69,13 +68,14 @@ #include "tracepoint.h" #include "ax.h" #include "ax-gdb.h" -#include "agent.h" +#include "gdbsupport/agent.h" #include "btrace.h" #include "record-btrace.h" #include -#include "common/scoped_restore.h" -#include "environ.h" -#include "common/byte-vector.h" +#include "gdbsupport/scoped_restore.h" +#include "gdbsupport/environ.h" +#include "gdbsupport/byte-vector.h" +#include #include /* The remote target. */ @@ -97,17 +97,7 @@ struct protocol_feature; struct packet_reg; struct stop_reply; -static void stop_reply_xfree (struct stop_reply *); - -struct stop_reply_deleter -{ - void operator() (stop_reply *r) const - { - stop_reply_xfree (r); - } -}; - -typedef std::unique_ptr stop_reply_up; +typedef std::unique_ptr stop_reply_up; /* Generic configuration support for packets the stub optionally supports. Allows the user to specify the use of the packet as well @@ -152,7 +142,7 @@ struct vCont_action_support bool S = false; }; -/* About this many threadisds fit in a packet. */ +/* About this many threadids fit in a packet. */ #define MAXTHREADLISTRESULTS 32 @@ -473,12 +463,12 @@ public: void mourn_inferior () override; - void pass_signals (int, const unsigned char *) override; + void pass_signals (gdb::array_view) override; int set_syscall_catchpoint (int, bool, int, gdb::array_view) override; - void program_signals (int, const unsigned char *) override; + void program_signals (gdb::array_view) override; bool thread_alive (ptid_t ptid) override; @@ -486,7 +476,7 @@ public: void update_thread_list () override; - const char *pid_to_str (ptid_t) override; + std::string pid_to_str (ptid_t) override; const char *extra_thread_info (struct thread_info *) override; @@ -496,6 +486,9 @@ public: int handle_len, inferior *inf) override; + gdb::byte_vector thread_info_to_thread_handle (struct thread_info *tp) + override; + void stop (ptid_t) override; void interrupt () override; @@ -675,7 +668,7 @@ public: const struct btrace_config *btrace_conf (const struct btrace_target_info *) override; bool augmented_libraries_svr4_read () override; int follow_fork (int, int) override; - void follow_exec (struct inferior *, char *) override; + void follow_exec (struct inferior *, const char *) override; int insert_fork_catchpoint (int) override; int remove_fork_catchpoint (int) override; int insert_vfork_catchpoint (int) override; @@ -775,7 +768,7 @@ public: /* Remote specific methods. */ char *remote_get_noisy_reply (); int remote_query_attached (int pid); - inferior *remote_add_inferior (int fake_pid_p, int pid, int attached, + inferior *remote_add_inferior (bool fake_pid_p, int pid, int attached, int try_open_exec); ptid_t remote_current_thread (ptid_t oldpid); @@ -977,7 +970,8 @@ public: }; /* Per-program-space data key. */ -static const struct program_space_data *remote_pspace_data; +static const struct program_space_key> + remote_pspace_data; /* The variable registered as the control variable used by the remote exec-file commands. While the remote exec-file setting is @@ -1045,12 +1039,7 @@ static struct cmd_list_element *remote_show_cmdlist; /* Controls whether GDB is willing to use range stepping. */ -static int use_range_stepping = 1; - -/* The max number of chars in debug output. The rest of chars are - omitted. */ - -#define REMOTE_DEBUG_MAX_CHAR 512 +static bool use_range_stepping = true; /* Private data that we'll store in (struct thread_info)->priv. */ struct remote_thread_info : public private_thread_info @@ -1157,12 +1146,12 @@ remote_target::remote_get_noisy_reply () org_to = to; - TRY + try { gdbarch_relocate_instruction (target_gdbarch (), &to, from); relocated = 1; } - CATCH (ex, RETURN_MASK_ALL) + catch (const gdb_exception &ex) { if (ex.error == MEMORY_ERROR) { @@ -1181,7 +1170,6 @@ remote_target::remote_get_noisy_reply () } putpkt ("E01"); } - END_CATCH if (relocated) { @@ -1238,16 +1226,6 @@ remote_target::get_remote_state () return &m_remote_state; } -/* Cleanup routine for the remote module's pspace data. */ - -static void -remote_pspace_data_cleanup (struct program_space *pspace, void *arg) -{ - char *remote_exec_file = (char *) arg; - - xfree (remote_exec_file); -} - /* Fetch the remote exec-file from the current program space. */ static const char * @@ -1255,9 +1233,7 @@ get_remote_exec_file (void) { char *remote_exec_file; - remote_exec_file - = (char *) program_space_data (current_program_space, - remote_pspace_data); + remote_exec_file = remote_pspace_data.get (current_program_space); if (remote_exec_file == NULL) return ""; @@ -1268,13 +1244,12 @@ get_remote_exec_file (void) static void set_pspace_remote_exec_file (struct program_space *pspace, - char *remote_exec_file) + const char *remote_exec_file) { - char *old_file = (char *) program_space_data (pspace, remote_pspace_data); + char *old_file = remote_pspace_data.get (pspace); xfree (old_file); - set_program_space_data (pspace, remote_pspace_data, - xstrdup (remote_exec_file)); + remote_pspace_data.set (pspace, xstrdup (remote_exec_file)); } /* The "set/show remote exec-file" set command hook. */ @@ -1296,22 +1271,6 @@ show_remote_exec_file (struct ui_file *file, int from_tty, fprintf_filtered (file, "%s\n", remote_exec_file_var); } -static int -compare_pnums (const void *lhs_, const void *rhs_) -{ - const struct packet_reg * const *lhs - = (const struct packet_reg * const *) lhs_; - const struct packet_reg * const *rhs - = (const struct packet_reg * const *) rhs_; - - if ((*lhs)->pnum < (*rhs)->pnum) - return -1; - else if ((*lhs)->pnum == (*rhs)->pnum) - return 0; - else - return 1; -} - static int map_regcache_remote_table (struct gdbarch *gdbarch, struct packet_reg *regs) { @@ -1342,8 +1301,9 @@ map_regcache_remote_table (struct gdbarch *gdbarch, struct packet_reg *regs) if (regs[regnum].pnum != -1) remote_regs[num_remote_regs++] = ®s[regnum]; - qsort (remote_regs, num_remote_regs, sizeof (struct packet_reg *), - compare_pnums); + std::sort (remote_regs, remote_regs + num_remote_regs, + [] (const packet_reg *a, const packet_reg *b) + { return a->pnum < b->pnum; }); for (regnum = 0, offset = 0; regnum < num_remote_regs; regnum++) { @@ -1513,12 +1473,12 @@ show_interrupt_sequence (struct ui_file *file, int from_tty, to the remote target when gdb connects to it. This is mostly needed when you debug the Linux kernel: The Linux kernel expects BREAK g which is Magic SysRq g for connecting gdb. */ -static int interrupt_on_connect = 0; +static bool interrupt_on_connect = false; /* This variable is used to implement the "set/show remotebreak" commands. Since these commands are now deprecated in favor of "set/show remote interrupt-sequence", it no longer has any effect on the code. */ -static int remote_break; +static bool remote_break; static void set_remotebreak (const char *args, int from_tty, struct cmd_list_element *c) @@ -1544,7 +1504,7 @@ show_remotebreak (struct ui_file *file, int from_tty, memory packets to ``host::sizeof long'' bytes - (typically 32 bits). Consequently, for 64 bit targets, the upper 32 bits of an address was never sent. Since fixing this bug may cause a break in - some remote targets this variable is principly provided to + some remote targets this variable is principally provided to facilitate backward compatibility. */ static unsigned int remote_address_size; @@ -1747,6 +1707,23 @@ show_hardware_breakpoint_limit (struct ui_file *file, int from_tty, "breakpoints is %s.\n"), value); } +/* Controls the maximum number of characters to display in the debug output + for each remote packet. The remaining characters are omitted. */ + +static int remote_packet_max_chars = 512; + +/* Show the maximum number of characters to display for each remote packet + when remote debugging is enabled. */ + +static void +show_remote_packet_max_chars (struct ui_file *file, int from_tty, + struct cmd_list_element *c, + const char *value) +{ + fprintf_filtered (file, _("Number of remote packet characters to " + "display is %s.\n"), value); +} + long remote_target::get_memory_write_packet_size () { @@ -1846,10 +1823,10 @@ add_packet_config_cmd (struct packet_config *config, const char *name, config->name = name; config->title = title; - set_doc = xstrprintf ("Set use of remote protocol `%s' (%s) packet", + set_doc = xstrprintf ("Set use of remote protocol `%s' (%s) packet.", name, title); show_doc = xstrprintf ("Show current use of remote " - "protocol `%s' (%s) packet", + "protocol `%s' (%s) packet.", name, title); /* set/show TITLE-packet {auto,on,off} */ cmd_name = xstrprintf ("%s-packet", title); @@ -1885,7 +1862,7 @@ packet_check_result (const char *buf) if (buf[0] == 'E' && isxdigit (buf[1]) && isxdigit (buf[2]) && buf[3] == '\0') - /* "Enn" - definitly an error. */ + /* "Enn" - definitely an error. */ return PACKET_ERROR; /* Always treat "E." as an error. This will be used for @@ -1991,8 +1968,6 @@ enum { PACKET_qXfer_libraries, PACKET_qXfer_libraries_svr4, PACKET_qXfer_memory_map, - PACKET_qXfer_spu_read, - PACKET_qXfer_spu_write, PACKET_qXfer_osdata, PACKET_qXfer_threads, PACKET_qXfer_statictrace_read, @@ -2308,9 +2283,11 @@ remote_target::remove_exec_catchpoint (int pid) -static ptid_t magic_null_ptid; -static ptid_t not_sent_ptid; -static ptid_t any_thread_ptid; +/* Take advantage of the fact that the TID field is not used, to tag + special ptids with it set to != 0. */ +static const ptid_t magic_null_ptid (42000, -1, 1); +static const ptid_t not_sent_ptid (42000, -2, 1); +static const ptid_t any_thread_ptid (42000, 0, 1); /* Find out if the stub attached to PID (and hence GDB should offer to detach instead of killing it when bailing out). */ @@ -2361,7 +2338,7 @@ remote_target::remote_query_attached (int pid) if no main executable is open already. */ inferior * -remote_target::remote_add_inferior (int fake_pid_p, int pid, int attached, +remote_target::remote_add_inferior (bool fake_pid_p, int pid, int attached, int try_open_exec) { struct inferior *inf; @@ -2502,7 +2479,7 @@ remote_target::remote_notice_new_inferior (ptid_t currthread, int executing) if (find_inferior_pid (currthread.pid ()) == NULL) { struct remote_state *rs = get_remote_state (); - int fake_pid_p = !remote_multi_process_p (rs); + bool fake_pid_p = !remote_multi_process_p (rs); inf = remote_add_inferior (fake_pid_p, currthread.pid (), -1, 1); @@ -2561,16 +2538,16 @@ record_currthread (struct remote_state *rs, ptid_t currthread) it can simply pass through to the inferior without reporting. */ void -remote_target::pass_signals (int numsigs, const unsigned char *pass_signals) +remote_target::pass_signals (gdb::array_view pass_signals) { if (packet_support (PACKET_QPassSignals) != PACKET_DISABLE) { char *pass_packet, *p; - int count = 0, i; + int count = 0; struct remote_state *rs = get_remote_state (); - gdb_assert (numsigs < 256); - for (i = 0; i < numsigs; i++) + gdb_assert (pass_signals.size () < 256); + for (size_t i = 0; i < pass_signals.size (); i++) { if (pass_signals[i]) count++; @@ -2578,7 +2555,7 @@ remote_target::pass_signals (int numsigs, const unsigned char *pass_signals) pass_packet = (char *) xmalloc (count * 3 + strlen ("QPassSignals:") + 1); strcpy (pass_packet, "QPassSignals:"); p = pass_packet + strlen (pass_packet); - for (i = 0; i < numsigs; i++) + for (size_t i = 0; i < pass_signals.size (); i++) { if (pass_signals[i]) { @@ -2687,16 +2664,16 @@ remote_target::set_syscall_catchpoint (int pid, bool needed, int any_count, signals it should pass through to the inferior when detaching. */ void -remote_target::program_signals (int numsigs, const unsigned char *signals) +remote_target::program_signals (gdb::array_view signals) { if (packet_support (PACKET_QProgramSignals) != PACKET_DISABLE) { char *packet, *p; - int count = 0, i; + int count = 0; struct remote_state *rs = get_remote_state (); - gdb_assert (numsigs < 256); - for (i = 0; i < numsigs; i++) + gdb_assert (signals.size () < 256); + for (size_t i = 0; i < signals.size (); i++) { if (signals[i]) count++; @@ -2704,7 +2681,7 @@ remote_target::program_signals (int numsigs, const unsigned char *signals) packet = (char *) xmalloc (count * 3 + strlen ("QProgramSignals:") + 1); strcpy (packet, "QProgramSignals:"); p = packet + strlen (packet); - for (i = 0; i < numsigs; i++) + for (size_t i = 0; i < signals.size (); i++) { if (signal_pass_state (i)) { @@ -2864,7 +2841,7 @@ remote_target::thread_name (struct thread_info *info) /* About these extended threadlist and threadinfo packets. They are variable length packets but, the fields within them are often fixed - length. They are redundent enough to send over UDP as is the + length. They are redundant enough to send over UDP as is the remote protocol in general. There is a matching unit test module in libstub. */ @@ -3271,7 +3248,7 @@ remote_target::remote_unpack_thread_info_response (char *pkt, } copy_threadref (&info->threadid, &ref); - /* Loop on tagged fields , try to bail if somthing goes wrong. */ + /* Loop on tagged fields , try to bail if something goes wrong. */ /* Packets are terminated with nulls. */ while ((pkt < limit) && mask && *pkt) @@ -3410,7 +3387,7 @@ remote_target::remote_get_threadlist (int startflag, threadref *nextthread, struct remote_state *rs = get_remote_state (); int result = 1; - /* Trancate result limit to be smaller than the packet size. */ + /* Truncate result limit to be smaller than the packet size. */ if ((((result_limit + 1) * BUF_THREAD_ID_SIZE) + 10) >= get_remote_packet_size ()) result_limit = (get_remote_packet_size () / BUF_THREAD_ID_SIZE) - 2; @@ -3432,8 +3409,8 @@ remote_target::remote_get_threadlist (int startflag, threadref *nextthread, if (!threadmatch (&rs->echo_nextthread, nextthread)) { /* FIXME: This is a good reason to drop the packet. */ - /* Possably, there is a duplicate response. */ - /* Possabilities : + /* Possibly, there is a duplicate response. */ + /* Possibilities : retransmit immediatly - race conditions retransmit after timeout - yes exit @@ -4059,7 +4036,7 @@ remote_target::~remote_target () if (rs->remote_async_inferior_event_token) delete_async_event_handler (&rs->remote_async_inferior_event_token); - remote_notif_state_xfree (rs->notif_state); + delete rs->notif_state; } /* Query the remote side for the text, data and bss offsets. */ @@ -4072,7 +4049,6 @@ remote_target::get_offsets () char *ptr; int lose, num_segments = 0, do_sections, do_segments; CORE_ADDR text_addr, data_addr, bss_addr, segments[2]; - struct section_offsets *offs; struct symfile_segment_data *data; if (symfile_objfile == NULL) @@ -4151,10 +4127,7 @@ remote_target::get_offsets () else if (*ptr != '\0') warning (_("Target reported unsupported offsets: %s"), buf); - offs = ((struct section_offsets *) - alloca (SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections))); - memcpy (offs, symfile_objfile->section_offsets, - SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections)); + section_offsets offs = symfile_objfile->section_offsets; data = get_symfile_segment_data (symfile_objfile->obfd); do_segments = (data != NULL); @@ -4207,15 +4180,15 @@ remote_target::get_offsets () if (do_sections) { - offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_addr; + offs[SECT_OFF_TEXT (symfile_objfile)] = text_addr; /* This is a temporary kludge to force data and bss to use the same offsets because that's what nlmconv does now. The real solution requires changes to the stub and remote.c that I don't have time to do right now. */ - offs->offsets[SECT_OFF_DATA (symfile_objfile)] = data_addr; - offs->offsets[SECT_OFF_BSS (symfile_objfile)] = data_addr; + offs[SECT_OFF_DATA (symfile_objfile)] = data_addr; + offs[SECT_OFF_BSS (symfile_objfile)] = data_addr; } objfile_relocate (symfile_objfile, offs); @@ -4318,7 +4291,7 @@ void remote_target::add_current_inferior_and_thread (char *wait_status) { struct remote_state *rs = get_remote_state (); - int fake_pid_p = 0; + bool fake_pid_p = false; inferior_ptid = null_ptid; @@ -4328,7 +4301,7 @@ remote_target::add_current_inferior_and_thread (char *wait_status) if (curr_ptid != null_ptid) { if (!remote_multi_process_p (rs)) - fake_pid_p = 1; + fake_pid_p = true; } else { @@ -4337,7 +4310,7 @@ remote_target::add_current_inferior_and_thread (char *wait_status) double duty as both the pid of the target process (if it has such), and as a flag indicating that a target is active. */ curr_ptid = magic_null_ptid; - fake_pid_p = 1; + fake_pid_p = true; } remote_add_inferior (fake_pid_p, curr_ptid.pid (), -1, 1); @@ -4797,7 +4770,7 @@ remote_target::start_remote (int from_tty, int extended_p) gdb_assert (wait_status == NULL); /* Report all signals during attach/startup. */ - pass_signals (0, NULL); + pass_signals ({}); /* If there are already stopped threads, mark them stopped and report their stops before giving the prompt to the user. */ @@ -5079,7 +5052,7 @@ remote_target::remote_packet_size (const protocol_feature *feature, rs->explicit_packet_size = packet_size; } -void +static void remote_packet_size (remote_target *remote, const protocol_feature *feature, enum packet_support support, const char *value) { @@ -5102,10 +5075,6 @@ static const struct protocol_feature remote_protocol_features[] = { remote_supported_packet, PACKET_augmented_libraries_svr4_read_feature }, { "qXfer:memory-map:read", PACKET_DISABLE, remote_supported_packet, PACKET_qXfer_memory_map }, - { "qXfer:spu:read", PACKET_DISABLE, remote_supported_packet, - PACKET_qXfer_spu_read }, - { "qXfer:spu:write", PACKET_DISABLE, remote_supported_packet, - PACKET_qXfer_spu_write }, { "qXfer:osdata:read", PACKET_DISABLE, remote_supported_packet, PACKET_qXfer_osdata }, { "qXfer:threads:read", PACKET_DISABLE, remote_supported_packet, @@ -5208,7 +5177,8 @@ register_remote_support_xml (const char *xml) else { char *copy = xstrdup (remote_support_xml + 13); - char *p = strtok (copy, ","); + char *saveptr; + char *p = strtok_r (copy, ",", &saveptr); do { @@ -5219,7 +5189,7 @@ register_remote_support_xml (const char *xml) return; } } - while ((p = strtok (NULL, ",")) != NULL); + while ((p = strtok_r (NULL, ",", &saveptr)) != NULL); xfree (copy); remote_support_xml = reconcat (remote_support_xml, @@ -5548,9 +5518,7 @@ remote_target::open_1 (const char *name, int from_tty, int extended_p) } /* Switch to using the remote target now. */ - push_target (remote); - /* The target stack owns the target now. */ - target_holder.release (); + push_target (std::move (target_holder)); /* Register extra event sources in the event loop. */ rs->remote_async_inferior_event_token @@ -5613,19 +5581,18 @@ remote_target::open_1 (const char *name, int from_tty, int extended_p) function. See cli-dump.c. */ { - TRY + try { remote->start_remote (from_tty, extended_p); } - CATCH (ex, RETURN_MASK_ALL) + catch (const gdb_exception &ex) { /* Pop the partially set up target - unless something else did already before throwing the exception. */ if (ex.error != TARGET_CLOSE_ERROR) remote_unpush_target (); - throw_exception (ex); + throw; } - END_CATCH } remote_btrace_reset (rs); @@ -5773,7 +5740,7 @@ remote_target::follow_fork (int follow_child, int detach_fork) follow-exec-mode is "new". */ void -remote_target::follow_exec (struct inferior *inf, char *execd_pathname) +remote_target::follow_exec (struct inferior *inf, const char *execd_pathname) { /* We know that this is a target file name, so if it has the "target:" prefix we strip it off before saving it in the program space. */ @@ -5821,16 +5788,14 @@ extended_remote_target::attach (const char *args, int from_tty) if (from_tty) { - char *exec_file = get_exec_file (0); + const char *exec_file = get_exec_file (0); if (exec_file) printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file, - target_pid_to_str (ptid_t (pid))); + target_pid_to_str (ptid_t (pid)).c_str ()); else printf_unfiltered (_("Attaching to %s\n"), - target_pid_to_str (ptid_t (pid))); - - gdb_flush (gdb_stdout); + target_pid_to_str (ptid_t (pid)).c_str ()); } xsnprintf (rs->buf.data (), get_remote_packet_size (), "vAttach;%x", pid); @@ -5849,17 +5814,17 @@ extended_remote_target::attach (const char *args, int from_tty) } else if (strcmp (rs->buf.data (), "OK") != 0) error (_("Attaching to %s failed with: %s"), - target_pid_to_str (ptid_t (pid)), + target_pid_to_str (ptid_t (pid)).c_str (), rs->buf.data ()); break; case PACKET_UNKNOWN: error (_("This target does not support attaching to a process")); default: error (_("Attaching to %s failed"), - target_pid_to_str (ptid_t (pid))); + target_pid_to_str (ptid_t (pid)).c_str ()); } - set_current_inferior (remote_add_inferior (0, pid, 1, 0)); + set_current_inferior (remote_add_inferior (false, pid, 1, 0)); inferior_ptid = ptid_t (pid); @@ -6651,7 +6616,7 @@ remote_target::remote_stop_ns (ptid_t ptid) putpkt (rs->buf); getpkt (&rs->buf, 0); if (strcmp (rs->buf.data (), "OK") != 0) - error (_("Stopping %s failed: %s"), target_pid_to_str (ptid), + error (_("Stopping %s failed: %s"), target_pid_to_str (ptid).c_str (), rs->buf.data ()); } @@ -6818,11 +6783,9 @@ remote_console_output (const char *msg) gdb_flush (gdb_stdtarg); } -DEF_VEC_O(cached_reg_t); - -typedef struct stop_reply +struct stop_reply : public notif_event { - struct notif_event base; + ~stop_reply (); /* The identifier of the thread about this event */ ptid_t ptid; @@ -6841,20 +6804,14 @@ typedef struct stop_reply efficient for those targets that provide critical registers as part of their normal status mechanism (as another roundtrip to fetch them is avoided). */ - VEC(cached_reg_t) *regcache; + std::vector regcache; enum target_stop_reason stop_reason; CORE_ADDR watch_data_address; int core; -} *stop_reply_p; - -static void -stop_reply_xfree (struct stop_reply *r) -{ - notif_event_xfree ((struct notif_event *) r); -} +}; /* Return the length of the stop reply queue. */ @@ -6865,7 +6822,7 @@ remote_target::stop_reply_queue_length () return rs->stop_reply_queue.size (); } -void +static void remote_notif_stop_parse (remote_target *remote, struct notif_client *self, const char *buf, struct notif_event *event) @@ -6906,30 +6863,16 @@ remote_notif_stop_can_get_pending_events (remote_target *remote, return 0; } -static void -stop_reply_dtr (struct notif_event *event) +stop_reply::~stop_reply () { - struct stop_reply *r = (struct stop_reply *) event; - cached_reg_t *reg; - int ix; - - for (ix = 0; - VEC_iterate (cached_reg_t, r->regcache, ix, reg); - ix++) - xfree (reg->data); - - VEC_free (cached_reg_t, r->regcache); + for (cached_reg_t ® : regcache) + xfree (reg.data); } -static struct notif_event * -remote_notif_stop_alloc_reply (void) +static notif_event_up +remote_notif_stop_alloc_reply () { - /* We cast to a pointer to the "base class". */ - struct notif_event *r = (struct notif_event *) XNEW (struct stop_reply); - - r->dtr = stop_reply_dtr; - - return r; + return notif_event_up (new struct stop_reply ()); } /* A client of notification Stop. */ @@ -7072,7 +7015,7 @@ remote_target::discard_pending_stop_replies (struct inferior *inf) /* Discard the in-flight notification. */ if (reply != NULL && reply->ptid.pid () == inf->pid) { - stop_reply_xfree (reply); + delete reply; rns->pending_event[notif_client_stop.id] = NULL; } @@ -7131,7 +7074,7 @@ remote_target::remote_notif_remove_queued_reply (ptid_t ptid) if (notif_debug) fprintf_unfiltered (gdb_stdlog, "notif: discard queued event: 'Stop' in %s\n", - target_pid_to_str (ptid)); + target_pid_to_str (ptid).c_str ()); return result; } @@ -7169,7 +7112,7 @@ remote_target::push_stop_reply (struct stop_reply *new_event) if (notif_debug) fprintf_unfiltered (gdb_stdlog, "notif: push 'Stop' %s to queue %d\n", - target_pid_to_str (new_event->ptid), + target_pid_to_str (new_event->ptid).c_str (), int (rs->stop_reply_queue.size ())); mark_async_event_handler (rs->remote_async_inferior_event_token); @@ -7216,7 +7159,7 @@ remote_target::remote_parse_stop_reply (const char *buf, stop_reply *event) event->ws.kind = TARGET_WAITKIND_IGNORE; event->ws.value.integer = 0; event->stop_reason = TARGET_STOPPED_BY_NO_REASON; - event->regcache = NULL; + event->regcache.clear (); event->core = -1; switch (buf[0]) @@ -7341,7 +7284,6 @@ Packet: '%s'\n"), else if (strprefix (p, p1, "exec")) { ULONGEST ignored; - char pathname[PATH_MAX]; int pathlen; /* Determine the length of the execd pathname. */ @@ -7350,11 +7292,13 @@ Packet: '%s'\n"), /* Save the pathname for event reporting and for the next run command. */ - hex2bin (p1, (gdb_byte *) pathname, pathlen); + gdb::unique_xmalloc_ptr pathname + ((char *) xmalloc (pathlen + 1)); + hex2bin (p1, (gdb_byte *) pathname.get (), pathlen); pathname[pathlen] = '\0'; /* This is freed during event handling. */ - event->ws.value.execd_pathname = xstrdup (pathname); + event->ws.value.execd_pathname = pathname.release (); event->ws.kind = TARGET_WAITKIND_EXECD; /* Skip the registers included in this packet, since @@ -7450,7 +7394,7 @@ Packet: '%s'\n"), if (fieldsize < register_size (event->arch, reg->regnum)) warning (_("Remote reply is too short: %s"), buf); - VEC_safe_push (cached_reg_t, event->regcache, &cached_reg); + event->regcache.push_back (cached_reg); } else { @@ -7587,7 +7531,7 @@ Packet: '%s'\n"), 2.5) <-- (registers reply to step #2.3) - Eventualy after step #2.5, we return to the event loop, which + Eventually after step #2.5, we return to the event loop, which notices there's an event on the REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN event and calls the associated callback --- the function below. At this point, we're @@ -7666,22 +7610,18 @@ remote_target::process_stop_reply (struct stop_reply *stop_reply, && status->kind != TARGET_WAITKIND_NO_RESUMED) { /* Expedited registers. */ - if (stop_reply->regcache) + if (!stop_reply->regcache.empty ()) { struct regcache *regcache = get_thread_arch_regcache (ptid, stop_reply->arch); - cached_reg_t *reg; - int ix; - for (ix = 0; - VEC_iterate (cached_reg_t, stop_reply->regcache, ix, reg); - ix++) - { - regcache->raw_supply (reg->num, reg->data); - xfree (reg->data); - } + for (cached_reg_t ® : stop_reply->regcache) + { + regcache->raw_supply (reg.num, reg.data); + xfree (reg.data); + } - VEC_free (cached_reg_t, stop_reply->regcache); + stop_reply->regcache.clear (); } remote_notice_new_inferior (ptid, 0); @@ -7692,7 +7632,7 @@ remote_target::process_stop_reply (struct stop_reply *stop_reply, remote_thr->vcont_resumed = 0; } - stop_reply_xfree (stop_reply); + delete stop_reply; return ptid; } @@ -8798,9 +8738,7 @@ remote_target::remote_xfer_live_readonly_partial (gdb_byte *readbuf, secp = target_section_by_addr (this, memaddr); if (secp != NULL - && (bfd_get_section_flags (secp->the_bfd_section->owner, - secp->the_bfd_section) - & SEC_READONLY)) + && (bfd_section_flags (secp->the_bfd_section) & SEC_READONLY)) { struct target_section *p; ULONGEST memend = memaddr + len; @@ -9189,15 +9127,21 @@ remote_target::putpkt_binary (const char *buf, int cnt) *p = '\0'; int len = (int) (p - buf2); + int max_chars; + + if (remote_packet_max_chars < 0) + max_chars = len; + else + max_chars = remote_packet_max_chars; std::string str - = escape_buffer (buf2, std::min (len, REMOTE_DEBUG_MAX_CHAR)); + = escape_buffer (buf2, std::min (len, max_chars)); fprintf_unfiltered (gdb_stdlog, "Sending packet: %s", str.c_str ()); - if (len > REMOTE_DEBUG_MAX_CHAR) + if (len > max_chars) fprintf_unfiltered (gdb_stdlog, "[%d bytes omitted]", - len - REMOTE_DEBUG_MAX_CHAR); + len - max_chars); fprintf_unfiltered (gdb_stdlog, "..."); @@ -9498,6 +9442,20 @@ remote_target::read_frame (gdb::char_vector *buf_p) } } +/* Set this to the maximum number of seconds to wait instead of waiting forever + in target_wait(). If this timer times out, then it generates an error and + the command is aborted. This replaces most of the need for timeouts in the + GDB test suite, and makes it possible to distinguish between a hung target + and one with slow communications. */ + +static int watchdog = 0; +static void +show_watchdog (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("Watchdog timer is %s.\n"), value); +} + /* Read a packet from the remote machine, with error checking, and store it in *BUF. Resize *BUF if necessary to hold the result. If FOREVER, wait forever rather than timing out; this is used (in @@ -9619,16 +9577,23 @@ remote_target::getpkt_or_notif_sane_1 (gdb::char_vector *buf, { if (remote_debug) { + int max_chars; + + if (remote_packet_max_chars < 0) + max_chars = val; + else + max_chars = remote_packet_max_chars; + std::string str = escape_buffer (buf->data (), - std::min (val, REMOTE_DEBUG_MAX_CHAR)); + std::min (val, max_chars)); fprintf_unfiltered (gdb_stdlog, "Packet received: %s", str.c_str ()); - if (val > REMOTE_DEBUG_MAX_CHAR) + if (val > max_chars) fprintf_unfiltered (gdb_stdlog, "[%d bytes omitted]", - val - REMOTE_DEBUG_MAX_CHAR); + val - max_chars); fprintf_unfiltered (gdb_stdlog, "\n"); } @@ -9804,11 +9769,11 @@ remote_target::remote_kill_k () { /* Catch errors so the user can quit from gdb even when we aren't on speaking terms with the remote system. */ - TRY + try { putpkt ("k"); } - CATCH (ex, RETURN_MASK_ERROR) + catch (const gdb_exception_error &ex) { if (ex.error == TARGET_CLOSE_ERROR) { @@ -9824,9 +9789,8 @@ remote_target::remote_kill_k () /* Otherwise, something went wrong. We didn't actually kill the target. Just propagate the exception, and let the user or higher layers decide what to do. */ - throw_exception (ex); + throw; } - END_CATCH } void @@ -10402,9 +10366,9 @@ remote_target::remove_watchpoint (CORE_ADDR addr, int len, } -int remote_hw_watchpoint_limit = -1; -int remote_hw_watchpoint_length_limit = -1; -int remote_hw_breakpoint_limit = -1; +static int remote_hw_watchpoint_limit = -1; +static int remote_hw_watchpoint_length_limit = -1; +static int remote_hw_breakpoint_limit = -1; int remote_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) @@ -10692,11 +10656,11 @@ compare_sections_command (const char *args, int from_tty) if (read_only && (s->flags & SEC_READONLY) == 0) continue; /* Skip writeable sections */ - size = bfd_get_section_size (s); + size = bfd_section_size (s); if (size == 0) continue; /* Skip zero-length section. */ - sectname = bfd_get_section_name (exec_bfd, s); + sectname = bfd_section_name (s); if (args && strcmp (args, sectname) != 0) continue; /* Not the section selected by user. */ @@ -10896,19 +10860,6 @@ remote_target::xfer_partial (enum target_object object, xfered_len); } - /* Handle SPU memory using qxfer packets. */ - if (object == TARGET_OBJECT_SPU) - { - if (readbuf) - return remote_read_qxfer ("spu", annex, readbuf, offset, len, - xfered_len, &remote_protocol_packets - [PACKET_qXfer_spu_read]); - else - return remote_write_qxfer ("spu", annex, writebuf, offset, len, - xfered_len, &remote_protocol_packets - [PACKET_qXfer_spu_write]); - } - /* Handle extra signal info using qxfer packets. */ if (object == TARGET_OBJECT_SIGNAL_INFO) { @@ -11340,7 +11291,7 @@ output_threadid (char *title, threadref *ref) { char hexid[20]; - pack_threadid (&hexid[0], ref); /* Convert threead id into hex. */ + pack_threadid (&hexid[0], ref); /* Convert thread id into hex. */ hexid[16] = 0; printf_filtered ("%s %s\n", title, (&hexid[0])); } @@ -11422,26 +11373,24 @@ init_remote_threadtests (void) { add_com ("tlist", class_obscure, threadlist_test_cmd, _("Fetch and print the remote list of " - "thread identifiers, one pkt only")); + "thread identifiers, one pkt only.")); add_com ("tinfo", class_obscure, threadinfo_test_cmd, - _("Fetch and display info about one thread")); + _("Fetch and display info about one thread.")); add_com ("tset", class_obscure, threadset_test_cmd, - _("Test setting to a different thread")); + _("Test setting to a different thread.")); add_com ("tupd", class_obscure, threadlist_update_test_cmd, - _("Iterate through updating all remote thread info")); + _("Iterate through updating all remote thread info.")); add_com ("talive", class_obscure, threadalive_test, - _(" Remote thread alive test ")); + _("Remote thread alive test.")); } #endif /* 0 */ -/* Convert a thread ID to a string. Returns the string in a static - buffer. */ +/* Convert a thread ID to a string. */ -const char * +std::string remote_target::pid_to_str (ptid_t ptid) { - static char buf[64]; struct remote_state *rs = get_remote_state (); if (ptid == null_ptid) @@ -11460,27 +11409,22 @@ remote_target::pid_to_str (ptid_t ptid) attached to a process, and reporting yes to qAttached, hence no smart special casing here. */ if (!remote_multi_process_p (rs)) - { - xsnprintf (buf, sizeof buf, "Remote target"); - return buf; - } + return "Remote target"; return normal_pid_to_str (ptid); } else { if (magic_null_ptid == ptid) - xsnprintf (buf, sizeof buf, "Thread
"); + return "Thread
"; else if (remote_multi_process_p (rs)) if (ptid.lwp () == 0) return normal_pid_to_str (ptid); else - xsnprintf (buf, sizeof buf, "Thread %d.%ld", - ptid.pid (), ptid.lwp ()); + return string_printf ("Thread %d.%ld", + ptid.pid (), ptid.lwp ()); else - xsnprintf (buf, sizeof buf, "Thread %ld", - ptid.lwp ()); - return buf; + return string_printf ("Thread %ld", ptid.lwp ()); } } @@ -12411,7 +12355,7 @@ public: DISABLE_COPY_AND_ASSIGN (scoped_remote_fd); /* Release ownership of the file descriptor, and return it. */ - int release () noexcept + ATTRIBUTE_UNUSED_RESULT int release () noexcept { int fd = m_fd; m_fd = -1; @@ -13102,7 +13046,6 @@ void remote_target::trace_set_readonly_regions () { asection *s; - bfd *abfd = NULL; bfd_size_type size; bfd_vma vma; int anysecs = 0; @@ -13126,8 +13069,8 @@ remote_target::trace_set_readonly_regions () continue; anysecs = 1; - vma = bfd_get_section_vma (abfd, s); - size = bfd_get_section_size (s); + vma = bfd_section_vma (s); + size = bfd_section_size (s); sprintf_vma (tmp1, vma); sprintf_vma (tmp2, vma + size); sec_length = 1 + strlen (tmp1) + 1 + strlen (tmp2); @@ -13167,33 +13110,31 @@ remote_target::get_trace_status (struct trace_status *ts) { /* Initialize it just to avoid a GCC false warning. */ char *p = NULL; - /* FIXME we need to get register block size some other way. */ - extern int trace_regblock_size; enum packet_result result; struct remote_state *rs = get_remote_state (); if (packet_support (PACKET_qTStatus) == PACKET_DISABLE) return -1; + /* FIXME we need to get register block size some other way. */ trace_regblock_size = rs->get_remote_arch_state (target_gdbarch ())->sizeof_g_packet; putpkt ("qTStatus"); - TRY + try { p = remote_get_noisy_reply (); } - CATCH (ex, RETURN_MASK_ERROR) + catch (const gdb_exception_error &ex) { if (ex.error != TARGET_CLOSE_ERROR) { exception_fprintf (gdb_stderr, ex, "qTStatus: "); return -1; } - throw_exception (ex); + throw; } - END_CATCH result = packet_ok (p, &remote_protocol_packets[PACKET_qTStatus]); @@ -13744,6 +13685,11 @@ remote_target::remote_btrace_maybe_reopen () int warned = 0; #endif + /* Don't bother walking the entirety of the remote thread list when + we know the feature isn't supported by the remote. */ + if (packet_support (PACKET_qXfer_btrace_conf) != PACKET_ENABLE) + return; + scoped_restore_current_thread restore_thread; for (thread_info *tp : all_non_exited_threads ()) @@ -13824,10 +13770,10 @@ remote_target::enable_btrace (ptid_t ptid, const struct btrace_config *conf) { if (rs->buf[0] == 'E' && rs->buf[1] == '.') error (_("Could not enable branch tracing for %s: %s"), - target_pid_to_str (ptid), &rs->buf[2]); + target_pid_to_str (ptid).c_str (), &rs->buf[2]); else error (_("Could not enable branch tracing for %s."), - target_pid_to_str (ptid)); + target_pid_to_str (ptid).c_str ()); } tinfo = XCNEW (struct btrace_target_info); @@ -13835,16 +13781,15 @@ remote_target::enable_btrace (ptid_t ptid, const struct btrace_config *conf) /* If we fail to read the configuration, we lose some information, but the tracing itself is not impacted. */ - TRY + try { btrace_read_config (&tinfo->conf); } - CATCH (err, RETURN_MASK_ERROR) + catch (const gdb_exception_error &err) { if (err.message != NULL) - warning ("%s", err.message); + warning ("%s", err.what ()); } - END_CATCH return tinfo; } @@ -13872,10 +13817,10 @@ remote_target::disable_btrace (struct btrace_target_info *tinfo) { if (rs->buf[0] == 'E' && rs->buf[1] == '.') error (_("Could not disable branch tracing for %s: %s"), - target_pid_to_str (tinfo->ptid), &rs->buf[2]); + target_pid_to_str (tinfo->ptid).c_str (), &rs->buf[2]); else error (_("Could not disable branch tracing for %s."), - target_pid_to_str (tinfo->ptid)); + target_pid_to_str (tinfo->ptid).c_str ()); } xfree (tinfo); @@ -14048,6 +13993,13 @@ remote_target::thread_handle_to_thread_info (const gdb_byte *thread_handle, return NULL; } +gdb::byte_vector +remote_target::thread_info_to_thread_handle (struct thread_info *tp) +{ + remote_thread_info *priv = get_remote_thread_info (tp); + return priv->thread_handle; +} + bool remote_target::can_async_p () { @@ -14303,10 +14255,6 @@ _initialize_remote (void) remote_g_packet_data_handle = gdbarch_data_register_pre_init (remote_g_packet_data_init); - remote_pspace_data - = register_program_space_data_with_cleanup (NULL, - remote_pspace_data_cleanup); - add_target (remote_target_info, remote_target::open); add_target (extended_remote_target_info, extended_remote_target::open); @@ -14320,15 +14268,15 @@ _initialize_remote (void) /* set/show remote ... */ add_prefix_cmd ("remote", class_maintenance, set_remote_cmd, _("\ -Remote protocol specific variables\n\ +Remote protocol specific variables.\n\ Configure various remote-protocol specific variables such as\n\ -the packets being used"), +the packets being used."), &remote_set_cmdlist, "set remote ", 0 /* allow-unknown */, &setlist); add_prefix_cmd ("remote", class_maintenance, show_remote_cmd, _("\ -Remote protocol specific variables\n\ +Remote protocol specific variables.\n\ Configure various remote-protocol specific variables such as\n\ -the packets being used"), +the packets being used."), &remote_show_cmdlist, "show remote ", 0 /* allow-unknown */, &showlist); @@ -14372,8 +14320,8 @@ Valid value is \"Ctrl-C\", \"BREAK\" or \"BREAK-g\". The default is \"Ctrl-C\"." add_setshow_boolean_cmd ("interrupt-on-connect", class_support, &interrupt_on_connect, _("\ -Set whether interrupt-sequence is sent to remote target when gdb connects to."), _(" \ -Show whether interrupt-sequence is sent to remote target when gdb connects to."), _(" \ +Set whether interrupt-sequence is sent to remote target when gdb connects to."), _("\ +Show whether interrupt-sequence is sent to remote target when gdb connects to."), _("\ If set, interrupt sequence is sent to remote target."), NULL, NULL, &remote_set_cmdlist, &remote_show_cmdlist); @@ -14521,12 +14469,6 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL, add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_memory_map], "qXfer:memory-map:read", "memory-map", 0); - add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_spu_read], - "qXfer:spu:read", "read-spu-object", 0); - - add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_spu_write], - "qXfer:spu:write", "write-spu-object", 0); - add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_osdata], "qXfer:osdata:read", "osdata", 0); @@ -14741,8 +14683,8 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL, documentation). */ add_setshow_auto_boolean_cmd ("Z-packet", class_obscure, &remote_Z_packet_detect, _("\ -Set use of remote protocol `Z' packets"), _("\ -Show use of remote protocol `Z' packets "), _("\ +Set use of remote protocol `Z' packets."), _("\ +Show use of remote protocol `Z' packets."), _("\ When set, GDB will attempt to use the remote breakpoint and watchpoint\n\ packets."), set_remote_protocol_Z_packet_cmd, @@ -14752,7 +14694,7 @@ packets."), &remote_set_cmdlist, &remote_show_cmdlist); add_prefix_cmd ("remote", class_files, remote_command, _("\ -Manipulate files on the remote system\n\ +Manipulate files on the remote system.\n\ Transfer files to and from the remote target system."), &remote_cmdlist, "remote ", 0 /* allow-unknown */, &cmdlist); @@ -14771,8 +14713,8 @@ Transfer files to and from the remote target system."), add_setshow_string_noescape_cmd ("exec-file", class_files, &remote_exec_file_var, _("\ -Set the remote pathname for \"run\""), _("\ -Show the remote pathname for \"run\""), NULL, +Set the remote pathname for \"run\"."), _("\ +Show the remote pathname for \"run\"."), NULL, set_remote_exec_file, show_remote_exec_file, &remote_set_cmdlist, @@ -14792,12 +14734,24 @@ stepping is supported by the target. The default is on."), &setlist, &showlist); + add_setshow_zinteger_cmd ("watchdog", class_maintenance, &watchdog, _("\ +Set watchdog timer."), _("\ +Show watchdog timer."), _("\ +When non-zero, this timeout is used instead of waiting forever for a target\n\ +to finish a low-level step or continue operation. If the specified amount\n\ +of time passes without a response from the target, an error occurs."), + NULL, + show_watchdog, + &setlist, &showlist); + + add_setshow_zuinteger_unlimited_cmd ("remote-packet-max-chars", no_class, + &remote_packet_max_chars, _("\ +Set the maximum number of characters to display for each remote packet."), _("\ +Show the maximum number of characters to display for each remote packet."), _("\ +Specify \"unlimited\" to display all the characters."), + NULL, show_remote_packet_max_chars, + &setdebuglist, &showdebuglist); + /* Eventually initialize fileio. See fileio.c */ initialize_remote_fileio (remote_set_cmdlist, remote_show_cmdlist); - - /* 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_t (42000, -1, 1); - not_sent_ptid = ptid_t (42000, -2, 1); - any_thread_ptid = ptid_t (42000, 0, 1); }