X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fremote.c;h=7453a3b31a7bff7ba90adf3c2c346bae0e6d70e9;hb=5b6d1e4fa4fc6827c7b3f0e99ff120dfa14d65d2;hp=2b21aeacdc29638827b8a0e0635c7508ee55b41f;hpb=3d6e9d2336c9ffcedb10f89631981a23dd518e8e;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/remote.c b/gdb/remote.c index 2b21aeacdc..7453a3b31a 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. @@ -42,12 +42,12 @@ #include "cli/cli-setshow.h" #include "target-descriptions.h" #include "gdb_bfd.h" -#include "common/filestuff.h" -#include "common/rsp-low.h" +#include "gdbsupport/filestuff.h" +#include "gdbsupport/rsp-low.h" #include "disasm.h" #include "location.h" -#include "common/gdb_sys_time.h" +#include "gdbsupport/gdb_sys_time.h" #include "event-loop.h" #include "event-top.h" @@ -68,13 +68,14 @@ #include "tracepoint.h" #include "ax.h" #include "ax-gdb.h" -#include "common/agent.h" +#include "gdbsupport/agent.h" #include "btrace.h" #include "record-btrace.h" #include -#include "common/scoped_restore.h" -#include "common/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. */ @@ -141,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 @@ -277,6 +278,9 @@ public: /* data */ /* The status of the stub support for the various vCont actions. */ vCont_action_support supports_vCont; + /* Whether vCont support was probed already. This is a workaround + until packet_support is per-connection. */ + bool supports_vCont_probed; /* True if the user has pressed Ctrl-C, but the target hasn't responded to that. */ @@ -485,6 +489,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; @@ -533,6 +540,8 @@ public: void async (int) override; + int async_wait_fd () override; + void thread_events (int) override; int can_do_single_step () override; @@ -664,7 +673,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; @@ -764,7 +773,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); @@ -966,7 +975,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 @@ -1021,7 +1031,7 @@ static void remote_console_output (const char *msg); static void remote_btrace_reset (remote_state *rs); -static void remote_unpush_and_throw (void); +static void remote_unpush_and_throw (remote_target *target); /* For "remote". */ @@ -1034,12 +1044,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 @@ -1146,12 +1151,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) { @@ -1170,7 +1175,6 @@ remote_target::remote_get_noisy_reply () } putpkt ("E01"); } - END_CATCH if (relocated) { @@ -1227,16 +1231,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 * @@ -1244,9 +1238,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 ""; @@ -1257,13 +1249,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. */ @@ -1282,23 +1273,7 @@ static void show_remote_exec_file (struct ui_file *file, int from_tty, struct cmd_list_element *cmd, const char *value) { - 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; + fprintf_filtered (file, "%s\n", get_remote_exec_file ()); } static int @@ -1331,8 +1306,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++) { @@ -1405,7 +1381,7 @@ remote_arch_state::remote_arch_state (struct gdbarch *gdbarch) static remote_target * get_current_remote_target () { - target_ops *proc_target = find_target_at (process_stratum); + target_ops *proc_target = current_inferior ()->process_target (); return dynamic_cast (proc_target); } @@ -1502,12 +1478,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) @@ -1533,7 +1509,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; @@ -1686,6 +1662,7 @@ show_memory_packet_size (struct memory_packet_config *config) } } +/* FIXME: needs to be per-remote-target. */ static struct memory_packet_config memory_write_packet_config = { "memory-write-packet-size", @@ -1736,12 +1713,30 @@ 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 () { return get_memory_packet_size (&memory_write_packet_config); } +/* FIXME: needs to be per-remote-target. */ static struct memory_packet_config memory_read_packet_config = { "memory-read-packet-size", @@ -1835,10 +1830,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); @@ -1874,7 +1869,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 @@ -1980,8 +1975,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, @@ -2100,6 +2093,9 @@ enum { PACKET_MAX }; +/* FIXME: needs to be per-remote-target. Ignoring this for now, + assuming all remote targets are the same server (thus all support + the same packets). */ static struct packet_config remote_protocol_packets[PACKET_MAX]; /* Returns the packet's corresponding "set remote foo-packet" command @@ -2352,7 +2348,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; @@ -2381,6 +2377,27 @@ remote_target::remote_add_inferior (int fake_pid_p, int pid, int attached, between program/address spaces. We simply bind the inferior to the program space's address space. */ inf = current_inferior (); + + /* However, if the current inferior is already bound to a + process, find some other empty inferior. */ + if (inf->pid != 0) + { + inf = nullptr; + for (inferior *it : all_inferiors ()) + if (it->pid == 0) + { + inf = it; + break; + } + } + if (inf == nullptr) + { + /* Since all inferiors were already bound to a process, add + a new inferior. */ + inf = add_inferior_with_spaces (); + } + switch_to_inferior_no_thread (inf); + push_target (this); inferior_appeared (inf, pid); } @@ -2396,7 +2413,8 @@ remote_target::remote_add_inferior (int fake_pid_p, int pid, int attached, } static remote_thread_info *get_remote_thread_info (thread_info *thread); -static remote_thread_info *get_remote_thread_info (ptid_t ptid); +static remote_thread_info *get_remote_thread_info (remote_target *target, + ptid_t ptid); /* Add thread PTID to GDB's thread list. Tag it as executing/running according to RUNNING. */ @@ -2414,13 +2432,13 @@ remote_target::remote_add_thread (ptid_t ptid, bool running, bool executing) might be confusing to the user. Be silent then, preserving the age old behavior. */ if (rs->starting_up) - thread = add_thread_silent (ptid); + thread = add_thread_silent (this, ptid); else - thread = add_thread (ptid); + thread = add_thread (this, ptid); get_remote_thread_info (thread)->vcont_resumed = executing; - set_executing (ptid, executing); - set_running (ptid, running); + set_executing (this, ptid, executing); + set_running (this, ptid, running); return thread; } @@ -2443,7 +2461,7 @@ remote_target::remote_notice_new_inferior (ptid_t currthread, int executing) /* If this is a new thread, add it to GDB's thread list. If we leave it up to WFI to do this, bad things will happen. */ - thread_info *tp = find_thread_ptid (currthread); + thread_info *tp = find_thread_ptid (this, currthread); if (tp != NULL && tp->state == THREAD_EXITED) { /* We're seeing an event on a thread id we knew had exited. @@ -2452,7 +2470,7 @@ remote_target::remote_notice_new_inferior (ptid_t currthread, int executing) return; } - if (!in_thread_list (currthread)) + if (!in_thread_list (this, currthread)) { struct inferior *inf = NULL; int pid = currthread.pid (); @@ -2465,8 +2483,8 @@ remote_target::remote_notice_new_inferior (ptid_t currthread, int executing) 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 (ptid_t (pid))) - thread_change_ptid (inferior_ptid, currthread); + if (in_thread_list (this, ptid_t (pid))) + thread_change_ptid (this, inferior_ptid, currthread); else { remote_add_thread (currthread, running, executing); @@ -2482,7 +2500,7 @@ remote_target::remote_notice_new_inferior (ptid_t currthread, int executing) 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. */ - thread_change_ptid (inferior_ptid, currthread); + thread_change_ptid (this, inferior_ptid, currthread); return; } @@ -2490,10 +2508,10 @@ remote_target::remote_notice_new_inferior (ptid_t currthread, int executing) 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 (currthread.pid ()) == NULL) + if (find_inferior_pid (this, 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); @@ -2530,10 +2548,12 @@ get_remote_thread_info (thread_info *thread) return static_cast (thread->priv.get ()); } +/* Return PTID's private thread data, creating it if necessary. */ + static remote_thread_info * -get_remote_thread_info (ptid_t ptid) +get_remote_thread_info (remote_target *target, ptid_t ptid) { - thread_info *thr = find_thread_ptid (ptid); + thread_info *thr = find_thread_ptid (target, ptid); return get_remote_thread_info (thr); } @@ -2855,7 +2875,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. */ @@ -3262,7 +3282,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) @@ -3401,7 +3421,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; @@ -3423,8 +3443,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 @@ -3793,6 +3813,9 @@ remote_target::update_thread_list () target. */ for (thread_info *tp : all_threads_safe ()) { + if (tp->inf->process_target () != this) + continue; + if (!context.contains_thread (tp->ptid)) { /* Not found. */ @@ -3818,7 +3841,7 @@ remote_target::update_thread_list () remote_notice_new_inferior (item.ptid, executing); - thread_info *tp = find_thread_ptid (item.ptid); + thread_info *tp = find_thread_ptid (this, item.ptid); remote_thread_info *info = get_remote_thread_info (tp); info->core = item.core; info->extra = std::move (item.extra); @@ -4020,13 +4043,6 @@ remote_target::close () /* Make sure we leave stdin registered in the event loop. */ terminal_ours (); - /* We don't have a connection to the remote stub anymore. Get rid - of all the inferiors and their threads we were controlling. - Reset inferior_ptid to null_ptid first, as otherwise has_stack_frame - will be unable to find the thread corresponding to (pid, 0, 0). */ - inferior_ptid = null_ptid; - discard_all_inferiors (); - trace_reset_local_state (); delete this; @@ -4050,7 +4066,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. */ @@ -4063,7 +4079,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) @@ -4142,10 +4157,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); @@ -4198,15 +4210,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); @@ -4309,7 +4321,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; @@ -4319,7 +4331,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 { @@ -4328,7 +4340,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); @@ -4336,7 +4348,7 @@ remote_target::add_current_inferior_and_thread (char *wait_status) /* Add the main thread and switch to it. Don't try reading registers yet, since we haven't fetched the target description yet. */ - thread_info *tp = add_thread_silent (curr_ptid); + thread_info *tp = add_thread_silent (this, curr_ptid); switch_to_thread_no_regs (tp); } @@ -4412,7 +4424,7 @@ remote_target::process_initial_stop_replies (int from_tty) if (ignore_event) continue; - struct thread_info *evthread = find_thread_ptid (event_ptid); + thread_info *evthread = find_thread_ptid (this, event_ptid); if (ws.kind == TARGET_WAITKIND_STOPPED) { @@ -4432,14 +4444,14 @@ remote_target::process_initial_stop_replies (int from_tty) || ws.value.sig != GDB_SIGNAL_0) evthread->suspend.waitstatus_pending_p = 1; - set_executing (event_ptid, 0); - set_running (event_ptid, 0); + set_executing (this, event_ptid, 0); + set_running (this, event_ptid, 0); get_remote_thread_info (evthread)->vcont_resumed = 0; } /* "Notice" the new inferiors before anything related to registers/memory. */ - for (inferior *inf : all_non_exited_inferiors ()) + for (inferior *inf : all_non_exited_inferiors (this)) { inf->needs_setup = 1; @@ -4460,7 +4472,7 @@ remote_target::process_initial_stop_replies (int from_tty) /* If all threads of an inferior were already stopped, we haven't setup the inferior yet. */ - for (inferior *inf : all_non_exited_inferiors ()) + for (inferior *inf : all_non_exited_inferiors (this)) { if (inf->needs_setup) { @@ -4474,7 +4486,7 @@ remote_target::process_initial_stop_replies (int from_tty) /* 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. */ - for (thread_info *thread : all_non_exited_threads ()) + for (thread_info *thread : all_non_exited_threads (this)) { if (first == NULL) first = thread; @@ -4513,7 +4525,7 @@ remote_target::process_initial_stop_replies (int from_tty) /* For "info program". */ thread_info *thread = inferior_thread (); if (thread->state == THREAD_STOPPED) - set_last_target_status (inferior_ptid, thread->suspend.waitstatus); + set_last_target_status (this, inferior_ptid, thread->suspend.waitstatus); } /* Start the remote connection and sync state. */ @@ -4686,7 +4698,7 @@ remote_target::start_remote (int from_tty, int extended_p) /* Let the stub know that we want it to return the thread. */ set_continue_thread (minus_one_ptid); - if (thread_count () == 0) + if (thread_count (this) == 0) { /* Target has no concept of threads at all. GDB treats non-threaded target as single-threaded; add a main @@ -4699,8 +4711,8 @@ remote_target::start_remote (int from_tty, int extended_p) says should be current. If we're reconnecting to a 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 (inferior_ptid == null_ptid) + ptid_t curr_thread = get_current_thread (wait_status); + if (curr_thread == null_ptid) { /* Odd... The target was able to list threads, but not tell us which thread was current (no "thread" @@ -4712,8 +4724,15 @@ remote_target::start_remote (int from_tty, int extended_p) "warning: couldn't determine remote " "current thread; picking first in list.\n"); - inferior_ptid = inferior_list->thread_list->ptid; + for (thread_info *tp : all_non_exited_threads (this, + minus_one_ptid)) + { + switch_to_thread (tp); + break; + } } + else + switch_to_thread (find_thread_ptid (this, curr_thread)); } /* init_wait_for_inferior should be called before get_offsets in order @@ -4772,7 +4791,7 @@ remote_target::start_remote (int from_tty, int extended_p) remote_notif_get_pending_events (notif); } - if (thread_count () == 0) + if (thread_count (this) == 0) { if (!extended_p) error (_("The target is not running (try extended-remote?)")); @@ -5070,7 +5089,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) { @@ -5093,10 +5112,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, @@ -5199,7 +5214,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 { @@ -5210,7 +5226,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, @@ -5429,7 +5445,7 @@ remote_target::remote_serial_quit_handler () { if (query (_("The target is not responding to GDB commands.\n" "Stop debugging it? "))) - remote_unpush_and_throw (); + remote_unpush_and_throw (this); } /* If ^C has already been sent once, offer to disconnect. */ else if (!target_terminal::is_ours () && rs->ctrlc_pending_p) @@ -5453,19 +5469,29 @@ remote_serial_quit_handler () curr_quit_handler_target->remote_serial_quit_handler (); } -/* Remove any of the remote.c targets from target stack. Upper targets depend - on it so remove them first. */ +/* Remove the remote target from the target stack of each inferior + that is using it. Upper targets depend on it so remove them + first. */ static void -remote_unpush_target (void) +remote_unpush_target (remote_target *target) { - pop_all_targets_at_and_above (process_stratum); + /* We have to unpush the target from all inferiors, even those that + aren't running. */ + scoped_restore_current_inferior restore_current_inferior; + + for (inferior *inf : all_inferiors (target)) + { + switch_to_inferior_no_thread (inf); + pop_all_targets_at_and_above (process_stratum); + generic_mourn_inferior (); + } } static void -remote_unpush_and_throw (void) +remote_unpush_and_throw (remote_target *target) { - remote_unpush_target (); + remote_unpush_target (target); throw_error (TARGET_CLOSE_ERROR, _("Disconnected from target.")); } @@ -5482,7 +5508,7 @@ remote_target::open_1 (const char *name, int from_tty, int extended_p) /* If we're connected to a running target, target_preopen will kill it. Ask this question first, before target_preopen has a chance to kill anything. */ - if (curr_remote != NULL && !have_inferiors ()) + if (curr_remote != NULL && !target_has_execution) { if (from_tty && !query (_("Already connected to a remote target. Disconnect? "))) @@ -5602,19 +5628,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); + remote_unpush_target (remote); + throw; } - END_CATCH } remote_btrace_reset (rs); @@ -5676,10 +5701,10 @@ remote_target::remote_detach_1 (inferior *inf, int from_tty) remote_detach_pid (pid); /* Exit only if this is the only active inferior. */ - if (from_tty && !rs->extended && number_of_live_inferiors () == 1) + if (from_tty && !rs->extended && number_of_live_inferiors (this) == 1) puts_filtered (_("Ending remote debugging.\n")); - struct thread_info *tp = find_thread_ptid (inferior_ptid); + thread_info *tp = find_thread_ptid (this, inferior_ptid); /* Check to see if we are detaching a fork parent. Note that if we are detaching a fork child, tp == NULL. */ @@ -5762,7 +5787,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. */ @@ -5781,10 +5806,10 @@ remote_target::disconnect (const char *args, int from_tty) error (_("Argument given to \"disconnect\" when remotely debugging.")); /* Make sure we unpush even the extended remote targets. Calling - target_mourn_inferior won't unpush, and remote_mourn won't - unpush if there is more than one inferior left. */ - unpush_target (this); - generic_mourn_inferior (); + target_mourn_inferior won't unpush, and + remote_target::mourn_inferior won't unpush if there is more than + one inferior left. */ + remote_unpush_target (this); if (from_tty) puts_filtered ("Ending remote debugging.\n"); @@ -5810,7 +5835,7 @@ 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, @@ -5846,7 +5871,7 @@ extended_remote_target::attach (const char *args, int from_tty) 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); @@ -5872,10 +5897,10 @@ extended_remote_target::attach (const char *args, int from_tty) inferior_ptid = remote_current_thread (inferior_ptid); /* Add the main thread to the thread list. */ - thread_info *thr = add_thread_silent (inferior_ptid); + thread_info *thr = add_thread_silent (this, inferior_ptid); /* Don't consider the thread stopped until we've processed the saved stop reply. */ - set_executing (thr->ptid, true); + set_executing (this, thr->ptid, true); } /* Next, if the target can specify a description, read it. We do @@ -5977,6 +6002,7 @@ remote_target::remote_vcont_probe () } packet_ok (rs->buf, &remote_protocol_packets[PACKET_vCont]); + rs->supports_vCont_probed = true; } /* Helper function for building "vCont" resumptions. Write a @@ -6014,10 +6040,10 @@ remote_target::append_resumption (char *p, char *endp, { /* If we don't know about the target thread's tid, then we're resuming magic_null_ptid (see caller). */ - tp = find_thread_ptid (magic_null_ptid); + tp = find_thread_ptid (this, magic_null_ptid); } else - tp = find_thread_ptid (ptid); + tp = find_thread_ptid (this, ptid); gdb_assert (tp != NULL); if (tp->control.may_range_step) @@ -6080,7 +6106,7 @@ char * remote_target::append_pending_thread_resumptions (char *p, char *endp, ptid_t ptid) { - for (thread_info *thread : all_non_exited_threads (ptid)) + for (thread_info *thread : all_non_exited_threads (this, ptid)) if (inferior_ptid != thread->ptid && thread->suspend.stop_signal != GDB_SIGNAL_0) { @@ -6113,7 +6139,7 @@ remote_target::remote_resume_with_hc (ptid_t ptid, int step, else set_continue_thread (ptid); - for (thread_info *thread : all_non_exited_threads ()) + for (thread_info *thread : all_non_exited_threads (this)) resume_clear_thread_private_info (thread); buf = rs->buf.data (); @@ -6250,9 +6276,9 @@ remote_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal) remote_thread_info *remote_thr; if (minus_one_ptid == ptid || ptid.is_pid ()) - remote_thr = get_remote_thread_info (inferior_ptid); + remote_thr = get_remote_thread_info (this, inferior_ptid); else - remote_thr = get_remote_thread_info (ptid); + remote_thr = get_remote_thread_info (this, ptid); remote_thr->last_resume_step = step; remote_thr->last_resume_sig = siggnal; @@ -6484,7 +6510,7 @@ remote_target::commit_resume () may_global_wildcard_vcont = 1; /* And assume every process is individually wildcard-able too. */ - for (inferior *inf : all_non_exited_inferiors ()) + for (inferior *inf : all_non_exited_inferiors (this)) { remote_inferior *priv = get_remote_inferior (inf); @@ -6495,7 +6521,7 @@ remote_target::commit_resume () disable process and global wildcard resumes appropriately. */ check_pending_events_prevent_wildcard_vcont (&may_global_wildcard_vcont); - for (thread_info *tp : all_non_exited_threads ()) + for (thread_info *tp : all_non_exited_threads (this)) { /* If a thread of a process is not meant to be resumed, then we can't wildcard that process. */ @@ -6524,7 +6550,7 @@ remote_target::commit_resume () struct vcont_builder vcont_builder (this); /* Threads first. */ - for (thread_info *tp : all_non_exited_threads ()) + for (thread_info *tp : all_non_exited_threads (this)) { remote_thread_info *remote_thr = get_remote_thread_info (tp); @@ -6553,7 +6579,7 @@ remote_target::commit_resume () supposed to be resumed. */ any_process_wildcard = 0; - for (inferior *inf : all_non_exited_inferiors ()) + for (inferior *inf : all_non_exited_inferiors (this)) { if (get_remote_inferior (inf)->may_wildcard_vcont) { @@ -6574,7 +6600,7 @@ remote_target::commit_resume () } else { - for (inferior *inf : all_non_exited_inferiors ()) + for (inferior *inf : all_non_exited_inferiors (this)) { if (get_remote_inferior (inf)->may_wildcard_vcont) { @@ -6601,7 +6627,10 @@ remote_target::remote_stop_ns (ptid_t ptid) char *p = rs->buf.data (); char *endp = p + get_remote_packet_size (); - if (packet_support (PACKET_vCont) == PACKET_SUPPORT_UNKNOWN) + /* FIXME: This supports_vCont_probed check is a workaround until + packet_support is per-connection. */ + if (packet_support (PACKET_vCont) == PACKET_SUPPORT_UNKNOWN + || !rs->supports_vCont_probed) remote_vcont_probe (); if (!rs->supports_vCont.t) @@ -6758,7 +6787,7 @@ remote_target::interrupt_query () if (query (_("The target is not responding to interrupt requests.\n" "Stop debugging it? "))) { - remote_unpush_target (); + remote_unpush_target (this); throw_error (TARGET_CLOSE_ERROR, _("Disconnected from target.")); } } @@ -6844,7 +6873,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) @@ -6965,7 +6994,7 @@ remote_target::remove_new_fork_children (threads_listing_context *context) /* For any threads stopped at a fork event, remove the corresponding fork child threads from the CONTEXT list. */ - for (thread_info *thread : all_non_exited_threads ()) + for (thread_info *thread : all_non_exited_threads (this)) { struct target_waitstatus *ws = thread_pending_fork_status (thread); @@ -7007,7 +7036,7 @@ remote_target::check_pending_events_prevent_wildcard_vcont || event->ws.kind == TARGET_WAITKIND_VFORKED) *may_global_wildcard = 0; - struct inferior *inf = find_inferior_ptid (event->ptid); + struct inferior *inf = find_inferior_ptid (this, event->ptid); /* This may be the first time we heard about this process. Regardless, we must not do a global wildcard resume, otherwise @@ -7373,9 +7402,10 @@ Packet: '%s'\n"), if (rsa == NULL) { - inferior *inf = (event->ptid == null_ptid - ? NULL - : find_inferior_ptid (event->ptid)); + inferior *inf + = (event->ptid == null_ptid + ? NULL + : find_inferior_ptid (this, event->ptid)); /* If this is the first time we learn anything about this process, skip the registers included in this packet, since we don't yet @@ -7463,7 +7493,6 @@ Packet: '%s'\n"), case 'W': /* Target exited. */ case 'X': { - int pid; ULONGEST value; /* GDB used to accept only 2 hex chars here. Stubs should @@ -7487,8 +7516,9 @@ Packet: '%s'\n"), event->ws.value.sig = GDB_SIGNAL_UNKNOWN; } - /* If no process is specified, assume inferior_ptid. */ - pid = inferior_ptid.pid (); + /* If no process is specified, return null_ptid, and let the + caller figure out the right process to use. */ + int pid = 0; if (*p == '\0') ; else if (*p == ';') @@ -7553,7 +7583,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 @@ -7635,7 +7665,7 @@ remote_target::process_stop_reply (struct stop_reply *stop_reply, if (!stop_reply->regcache.empty ()) { struct regcache *regcache - = get_thread_arch_regcache (ptid, stop_reply->arch); + = get_thread_arch_regcache (this, ptid, stop_reply->arch); for (cached_reg_t ® : stop_reply->regcache) { @@ -7647,7 +7677,7 @@ remote_target::process_stop_reply (struct stop_reply *stop_reply, } remote_notice_new_inferior (ptid, 0); - remote_thread_info *remote_thr = get_remote_thread_info (ptid); + remote_thread_info *remote_thr = get_remote_thread_info (this, ptid); remote_thr->core = stop_reply->core; remote_thr->stop_reason = stop_reply->stop_reason; remote_thr->watch_data_address = stop_reply->watch_data_address; @@ -7714,6 +7744,17 @@ remote_target::wait_ns (ptid_t ptid, struct target_waitstatus *status, int optio } } +/* Return the first resumed thread. */ + +static ptid_t +first_remote_resumed_thread (remote_target *target) +{ + for (thread_info *tp : all_non_exited_threads (target, minus_one_ptid)) + if (tp->resumed) + return tp->ptid; + return null_ptid; +} + /* Wait until the remote machine stops, then return, storing status in STATUS just as `wait' would. */ @@ -7850,11 +7891,19 @@ remote_target::wait_as (ptid_t ptid, target_waitstatus *status, int options) if (event_ptid != null_ptid) record_currthread (rs, event_ptid); else - event_ptid = inferior_ptid; + event_ptid = first_remote_resumed_thread (this); } else - /* A process exit. Invalidate our notion of current thread. */ - record_currthread (rs, minus_one_ptid); + { + /* A process exit. Invalidate our notion of current thread. */ + record_currthread (rs, minus_one_ptid); + /* It's possible that the packet did not include a pid. */ + if (event_ptid == null_ptid) + event_ptid = first_remote_resumed_thread (this); + /* EVENT_PTID could still be NULL_PTID. Double-check. */ + if (event_ptid == null_ptid) + event_ptid = magic_null_ptid; + } return event_ptid; } @@ -8760,9 +8809,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; @@ -8967,11 +9014,11 @@ remote_target::files_info () for output compatibility with throw_perror_with_name. */ static void -unpush_and_perror (const char *string) +unpush_and_perror (remote_target *target, const char *string) { int saved_errno = errno; - remote_unpush_target (); + remote_unpush_target (target); throw_error (TARGET_CLOSE_ERROR, "%s: %s.", string, safe_strerror (saved_errno)); } @@ -9007,12 +9054,12 @@ remote_target::readchar (int timeout) switch ((enum serial_rc) ch) { case SERIAL_EOF: - remote_unpush_target (); + remote_unpush_target (this); throw_error (TARGET_CLOSE_ERROR, _("Remote connection closed")); /* no return */ case SERIAL_ERROR: - unpush_and_perror (_("Remote communication error. " - "Target disconnected.")); + unpush_and_perror (this, _("Remote communication error. " + "Target disconnected.")); /* no return */ case SERIAL_TIMEOUT: break; @@ -9040,8 +9087,8 @@ remote_target::remote_serial_write (const char *str, int len) if (serial_write (rs->remote_desc, str, len)) { - unpush_and_perror (_("Remote communication error. " - "Target disconnected.")); + unpush_and_perror (this, _("Remote communication error. " + "Target disconnected.")); } if (rs->got_ctrlc_during_io) @@ -9151,15 +9198,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, "..."); @@ -9460,6 +9513,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 @@ -9544,7 +9611,7 @@ remote_target::getpkt_or_notif_sane_1 (gdb::char_vector *buf, if (forever) /* Watchdog went off? Kill the target. */ { - remote_unpush_target (); + remote_unpush_target (this); throw_error (TARGET_CLOSE_ERROR, _("Watchdog timeout has expired. " "Target detached.")); @@ -9581,16 +9648,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"); } @@ -9654,7 +9728,7 @@ remote_target::kill_new_fork_children (int pid) /* Kill the fork child threads of any threads in process PID that are stopped at a fork event. */ - for (thread_info *thread : all_non_exited_threads ()) + for (thread_info *thread : all_non_exited_threads (this)) { struct target_waitstatus *ws = &thread->pending_follow; @@ -9714,7 +9788,7 @@ remote_target::kill () inferior, then we will tell gdbserver to exit and unpush the target. */ if (res == -1 && !remote_multi_process_p (rs) - && number_of_live_inferiors () == 1) + && number_of_live_inferiors (this) == 1) { remote_kill_k (); @@ -9766,11 +9840,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) { @@ -9786,9 +9860,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 @@ -9801,12 +9874,9 @@ remote_target::mourn_inferior () discard_pending_stop_replies (current_inferior ()); /* In 'target remote' mode with one inferior, we close the connection. */ - if (!rs->extended && number_of_live_inferiors () <= 1) + if (!rs->extended && number_of_live_inferiors (this) <= 1) { - unpush_target (this); - - /* remote_close takes care of doing most of the clean up. */ - generic_mourn_inferior (); + remote_unpush_target (this); return; } @@ -9841,26 +9911,6 @@ remote_target::mourn_inferior () /* Call common code to mark the inferior as not running. */ generic_mourn_inferior (); - - if (!have_inferiors ()) - { - if (!remote_multi_process_p (rs)) - { - /* Check whether the target is running now - some remote stubs - automatically restart after kill. */ - putpkt ("?"); - getpkt (&rs->buf, 0); - - if (rs->buf[0] == 'S' || rs->buf[0] == 'T') - { - /* Assume that the target has been restarted. Set - inferior_ptid so that bits of core GDB realizes - there's something here, e.g., so that the user can - say "kill" again. */ - inferior_ptid = magic_null_ptid; - } - } - } } bool @@ -10364,9 +10414,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) @@ -10654,11 +10704,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. */ @@ -10858,19 +10908,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) { @@ -11302,7 +11339,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])); } @@ -11384,15 +11421,15 @@ 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 */ @@ -13057,7 +13094,6 @@ void remote_target::trace_set_readonly_regions () { asection *s; - bfd *abfd = NULL; bfd_size_type size; bfd_vma vma; int anysecs = 0; @@ -13081,8 +13117,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); @@ -13122,33 +13158,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]); @@ -13426,7 +13460,7 @@ remote_target::set_disconnected_tracing (int val) int remote_target::core_of_thread (ptid_t ptid) { - struct thread_info *info = find_thread_ptid (ptid); + thread_info *info = find_thread_ptid (this, ptid); if (info != NULL && info->priv != NULL) return get_remote_thread_info (info)->core; @@ -13699,9 +13733,14 @@ 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 ()) + for (thread_info *tp : all_non_exited_threads (this)) { set_general_thread (tp->ptid); @@ -13790,16 +13829,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.what ()); } - END_CATCH return tinfo; } @@ -13918,13 +13956,12 @@ char * remote_target::pid_to_exec_file (int pid) { static gdb::optional filename; - struct inferior *inf; char *annex = NULL; if (packet_support (PACKET_qXfer_exec_file) != PACKET_ENABLE) return NULL; - inf = find_inferior_pid (pid); + inferior *inf = find_inferior_pid (this, pid); if (inf == NULL) internal_error (__FILE__, __LINE__, _("not currently attached to process %d"), pid); @@ -13985,7 +14022,7 @@ remote_target::thread_handle_to_thread_info (const gdb_byte *thread_handle, int handle_len, inferior *inf) { - for (thread_info *tp : all_non_exited_threads ()) + for (thread_info *tp : all_non_exited_threads (this)) { remote_thread_info *priv = get_remote_thread_info (tp); @@ -14003,6 +14040,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 () { @@ -14050,6 +14094,13 @@ remote_async_inferior_event_handler (gdb_client_data data) inferior_event_handler (INF_REG_EVENT, data); } +int +remote_target::async_wait_fd () +{ + struct remote_state *rs = get_remote_state (); + return rs->remote_desc->fd; +} + void remote_target::async (int enable) { @@ -14258,10 +14309,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); @@ -14275,15 +14322,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); @@ -14327,8 +14374,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); @@ -14476,12 +14523,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); @@ -14696,8 +14737,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, @@ -14707,7 +14748,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); @@ -14726,8 +14767,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, @@ -14747,6 +14788,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); }