X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fgdbserver%2Fserver.c;h=d711c53e5fd6520648ef973552bf893344eff774;hb=96643e35c077ed36c74b231ceefa4c30b3b02e28;hp=5ce62810bf6d80a7bee43ab055013c859a583b27;hpb=9ee23a853c18da3c83530c7957464bc6b6e9fb16;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 5ce62810bf..d711c53e5f 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -39,6 +39,8 @@ #include "common-inferior.h" #include "job-control.h" #include "environ.h" +#include "filenames.h" +#include "pathstuff.h" #include "common/selftest.h" @@ -56,6 +58,10 @@ break; \ } +/* String containing the current directory (what getwd would return). */ + +char *current_directory; + /* The environment to pass to the inferior when creating it. */ static gdb_environ our_environ; @@ -66,17 +72,6 @@ static gdb_environ our_environ; int startup_with_shell = 1; -/* The thread set with an `Hc' packet. `Hc' is deprecated in favor of - `vCont'. Note the multi-process extensions made `vCont' a - requirement, so `Hc pPID.TID' is pretty much undefined. So - CONT_THREAD can be null_ptid for no `Hc' thread, minus_one_ptid for - resuming all threads of the process (again, `Hc' isn't used for - multi-process), or a specific thread ptid_t. */ -ptid_t cont_thread; - -/* The thread set with an `Hg' packet. */ -ptid_t general_thread; - int server_waiting; static int extended_protocol; @@ -86,36 +81,43 @@ static int exit_requested; /* --once: Exit after the first connection has closed. */ int run_once; -int multi_process; -int report_fork_events; -int report_vfork_events; -int report_exec_events; -int report_thread_events; - /* Whether to report TARGET_WAITKING_NO_RESUMED events. */ static int report_no_resumed; int non_stop; -int swbreak_feature; -int hwbreak_feature; -/* True if the "vContSupported" feature is active. In that case, GDB - wants us to report whether single step is supported in the reply to - "vCont?" packet. */ -static int vCont_supported; +static struct { + /* Set the PROGRAM_PATH. Here we adjust the path of the provided + binary if needed. */ + void set (gdb::unique_xmalloc_ptr &&path) + { + m_path = std::move (path); -/* Whether we should attempt to disable the operating system's address - space randomization feature before starting an inferior. */ -int disable_randomization = 1; + /* Make sure we're using the absolute path of the inferior when + creating it. */ + if (!contains_dir_separator (m_path.get ())) + { + int reg_file_errno; -static char *program_name = NULL; + /* Check if the file is in our CWD. If it is, then we prefix + its name with CURRENT_DIRECTORY. Otherwise, we leave the + name as-is because we'll try searching for it in $PATH. */ + if (is_regular_file (m_path.get (), ®_file_errno)) + m_path = gdb_abspath (m_path.get ()); + } + } + + /* Return the PROGRAM_PATH. */ + char *get () + { return m_path.get (); } + +private: + /* The program name, adjusted if needed. */ + gdb::unique_xmalloc_ptr m_path; +} program_path; static std::vector program_args; static std::string wrapper_argv; -int pass_signals[GDB_SIGNAL_LAST]; -int program_signals[GDB_SIGNAL_LAST]; -int program_signals_p; - /* The PID of the originally created or attached inferior. Used to send signals to the process when GDB sends us an asynchronous interrupt (user hitting Control-C in the client), and to wait for the child to exit @@ -131,11 +133,6 @@ int disable_packet_Tthread; int disable_packet_qC; int disable_packet_qfThreadInfo; -/* Last status reported to GDB. */ -struct target_waitstatus last_status; -ptid_t last_ptid; - -char *own_buf; static unsigned char *mem_buf; /* A sub-class of 'struct notif_event' for stop, holding information @@ -159,6 +156,18 @@ static struct btrace_config current_btrace_conf; DEFINE_QUEUE_P (notif_event_p); +/* The client remote protocol state. */ + +static client_state g_client_state; + +client_state & +get_client_state () +{ + client_state &cs = g_client_state; + return cs; +} + + /* Put a stop reply to the stop reply queue. */ static void @@ -181,7 +190,7 @@ remove_all_on_match_ptid (QUEUE (notif_event_p) *q, ptid_t filter_ptid = *(ptid_t *) data; struct vstop_notif *vstop_event = (struct vstop_notif *) event; - if (ptid_match (vstop_event->ptid, filter_ptid)) + if (vstop_event->ptid.matches (filter_ptid)) { if (q->free_func != NULL) q->free_func (event); @@ -220,13 +229,13 @@ in_queued_stop_replies_ptid (QUEUE (notif_event_p) *q, ptid_t filter_ptid = *(ptid_t *) data; struct vstop_notif *vstop_event = (struct vstop_notif *) event; - if (ptid_match (vstop_event->ptid, filter_ptid)) + if (vstop_event->ptid.matches (filter_ptid)) return 0; /* Don't resume fork children that GDB does not know about yet. */ if ((vstop_event->status.kind == TARGET_WAITKIND_FORKED || vstop_event->status.kind == TARGET_WAITKIND_VFORKED) - && ptid_match (vstop_event->status.value.related_pid, filter_ptid)) + && vstop_event->status.value.related_pid.matches (filter_ptid)) return 0; return 1; @@ -265,10 +274,10 @@ get_exec_wrapper () char * get_exec_file (int err) { - if (err && program_name == NULL) + if (err && program_path.get () == NULL) error (_("No executable file specified.")); - return program_name; + return program_path.get (); } /* See server.h. */ @@ -282,6 +291,7 @@ get_environ () static int attach_inferior (int pid) { + client_state &cs = get_client_state (); /* myattach should return -1 if attaching is unsupported, 0 if it succeeded, and call error() otherwise. */ @@ -298,17 +308,17 @@ attach_inferior (int pid) if (!non_stop) { - last_ptid = mywait (pid_to_ptid (pid), &last_status, 0, 0); + cs.last_ptid = mywait (ptid_t (pid), &cs.last_status, 0, 0); /* GDB knows to ignore the first SIGSTOP after attaching to a running process using the "attach" command, but this is different; it's just using "target remote". Pretend it's just starting up. */ - if (last_status.kind == TARGET_WAITKIND_STOPPED - && last_status.value.sig == GDB_SIGNAL_STOP) - last_status.value.sig = GDB_SIGNAL_TRAP; + if (cs.last_status.kind == TARGET_WAITKIND_STOPPED + && cs.last_status.value.sig == GDB_SIGNAL_STOP) + cs.last_status.value.sig = GDB_SIGNAL_TRAP; current_thread->last_resume_kind = resume_stop; - current_thread->last_status = last_status; + current_thread->last_status = cs.last_status; } return 0; @@ -422,6 +432,7 @@ handle_btrace_disable (struct thread_info *thread) static int handle_btrace_general_set (char *own_buf) { + client_state &cs = get_client_state (); struct thread_info *thread; char *op; @@ -430,14 +441,14 @@ handle_btrace_general_set (char *own_buf) op = own_buf + strlen ("Qbtrace:"); - if (ptid_equal (general_thread, null_ptid) - || ptid_equal (general_thread, minus_one_ptid)) + if (cs.general_thread == null_ptid + || cs.general_thread == minus_one_ptid) { strcpy (own_buf, "E.Must select a single thread."); return -1; } - thread = find_thread_ptid (general_thread); + thread = find_thread_ptid (cs.general_thread); if (thread == NULL) { strcpy (own_buf, "E.No such thread."); @@ -471,6 +482,7 @@ handle_btrace_general_set (char *own_buf) static int handle_btrace_conf_general_set (char *own_buf) { + client_state &cs = get_client_state (); struct thread_info *thread; char *op; @@ -479,14 +491,14 @@ handle_btrace_conf_general_set (char *own_buf) op = own_buf + strlen ("Qbtrace-conf:"); - if (ptid_equal (general_thread, null_ptid) - || ptid_equal (general_thread, minus_one_ptid)) + if (cs.general_thread == null_ptid + || cs.general_thread == minus_one_ptid) { strcpy (own_buf, "E.Must select a single thread."); return -1; } - thread = find_thread_ptid (general_thread); + thread = find_thread_ptid (cs.general_thread); if (thread == NULL) { strcpy (own_buf, "E.No such thread."); @@ -538,6 +550,7 @@ handle_btrace_conf_general_set (char *own_buf) static void handle_general_set (char *own_buf) { + client_state &cs = get_client_state (); if (startswith (own_buf, "QPassSignals:")) { int numsigs = (int) GDB_SIGNAL_LAST, i; @@ -549,7 +562,7 @@ handle_general_set (char *own_buf) { if (i == cursig) { - pass_signals[i] = 1; + cs.pass_signals[i] = 1; if (*p == '\0') /* Keep looping, to clear the remaining signals. */ cursig = -1; @@ -557,7 +570,7 @@ handle_general_set (char *own_buf) p = decode_address_to_semicolon (&cursig, p); } else - pass_signals[i] = 0; + cs.pass_signals[i] = 0; } strcpy (own_buf, "OK"); return; @@ -569,14 +582,14 @@ handle_general_set (char *own_buf) const char *p = own_buf + strlen ("QProgramSignals:"); CORE_ADDR cursig; - program_signals_p = 1; + cs.program_signals_p = 1; p = decode_address_to_semicolon (&cursig, p); for (i = 0; i < numsigs; i++) { if (i == cursig) { - program_signals[i] = 1; + cs.program_signals[i] = 1; if (*p == '\0') /* Keep looping, to clear the remaining signals. */ cursig = -1; @@ -584,7 +597,7 @@ handle_general_set (char *own_buf) p = decode_address_to_semicolon (&cursig, p); } else - program_signals[i] = 0; + cs.program_signals[i] = 0; } strcpy (own_buf, "OK"); return; @@ -707,7 +720,7 @@ handle_general_set (char *own_buf) debug_flush (); } - noack_mode = 1; + cs.noack_mode = 1; write_ok (own_buf); return; } @@ -755,11 +768,11 @@ handle_general_set (char *own_buf) ULONGEST setting; unpack_varlen_hex (packet, &setting); - disable_randomization = setting; + cs.disable_randomization = setting; if (remote_debug) { - debug_printf (disable_randomization + debug_printf (cs.disable_randomization ? "[address space randomization disabled]\n" : "[address space randomization enabled]\n"); } @@ -813,20 +826,17 @@ handle_general_set (char *own_buf) req = TRIBOOL_TRUE; else { - char *mode_copy = xstrdup (mode); - /* We don't know what this mode is, so complain to GDB. */ sprintf (own_buf, "E.Unknown thread-events mode requested: %s\n", - mode_copy); - xfree (mode_copy); + mode); return; } - report_thread_events = (req == TRIBOOL_TRUE); + cs.report_thread_events = (req == TRIBOOL_TRUE); if (remote_debug) { - const char *req_str = report_thread_events ? "enabled" : "disabled"; + const char *req_str = cs.report_thread_events ? "enabled" : "disabled"; debug_printf ("[thread events are now %s]\n", req_str); } @@ -909,7 +919,7 @@ get_features_xml (const char *annex) if (strcmp (annex, "target.xml") == 0) { - const char *ret = tdesc_get_features_xml ((target_desc*) desc); + const char *ret = tdesc_get_features_xml (desc); if (*ret == '@') return ret + 1; @@ -967,14 +977,15 @@ monitor_show_help (void) static int gdb_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) { + client_state &cs = get_client_state (); int res; - if (current_traceframe >= 0) + if (cs.current_traceframe >= 0) { ULONGEST nbytes; ULONGEST length = len; - if (traceframe_read_mem (current_traceframe, + if (traceframe_read_mem (cs.current_traceframe, memaddr, myaddr, len, &nbytes)) return -1; /* Data read from trace buffer, we're done. */ @@ -1007,7 +1018,8 @@ gdb_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) static int gdb_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len) { - if (current_traceframe >= 0) + client_state &cs = get_client_state (); + if (cs.current_traceframe >= 0) return EIO; else { @@ -1182,34 +1194,38 @@ handle_search_memory (char *own_buf, int packet_len) static void handle_detach (char *own_buf) { - require_running_or_return (own_buf); + client_state &cs = get_client_state (); - int pid; + process_info *process; - if (multi_process) + if (cs.multi_process) { /* skip 'D;' */ - pid = strtol (&own_buf[2], NULL, 16); + int pid = strtol (&own_buf[2], NULL, 16); + + process = find_process_pid (pid); } else - pid = ptid_get_pid (current_ptid); - - if ((tracing && disconnected_tracing) || any_persistent_commands ()) { - struct process_info *process = find_process_pid (pid); + process = (current_thread != nullptr + ? get_thread_process (current_thread) + : nullptr); + } - if (process == NULL) - { - write_enn (own_buf); - return; - } + if (process == NULL) + { + write_enn (own_buf); + return; + } + if ((tracing && disconnected_tracing) || any_persistent_commands (process)) + { if (tracing && disconnected_tracing) fprintf (stderr, "Disconnected tracing in effect, " "leaving gdbserver attached to the process\n"); - if (any_persistent_commands ()) + if (any_persistent_commands (process)) fprintf (stderr, "Persistent commands are present, " "leaving gdbserver attached to the process\n"); @@ -1237,13 +1253,13 @@ handle_detach (char *own_buf) return; } - fprintf (stderr, "Detaching from process %d\n", pid); + fprintf (stderr, "Detaching from process %d\n", process->pid); stop_tracing (); - if (detach_inferior (pid) != 0) + if (detach_inferior (process) != 0) write_enn (own_buf); else { - discard_queued_stop_replies (pid_to_ptid (pid)); + discard_queued_stop_replies (ptid_t (process->pid)); write_ok (own_buf); if (extended_protocol || target_running ()) @@ -1251,9 +1267,9 @@ handle_detach (char *own_buf) /* There is still at least one inferior remaining or we are in extended mode, so don't terminate gdbserver, and instead treat this like a normal program exit. */ - last_status.kind = TARGET_WAITKIND_EXITED; - last_status.value.integer = 0; - last_ptid = pid_to_ptid (pid); + cs.last_status.kind = TARGET_WAITKIND_EXITED; + cs.last_status.value.integer = 0; + cs.last_ptid = ptid_t (process->pid); current_thread = NULL; } @@ -1265,7 +1281,7 @@ handle_detach (char *own_buf) /* If we are attached, then we can exit. Otherwise, we need to hang around doing nothing, until the child is gone. */ - join_inferior (pid); + join_inferior (process); exit (0); } } @@ -1275,8 +1291,8 @@ handle_detach (char *own_buf) ARG is the text after "--debug-format=" or "monitor set debug-format". IS_MONITOR is non-zero if we're invoked via "monitor set debug-format". This triggers calls to monitor_output. - The result is NULL if all options were parsed ok, otherwise an error - message which the caller must free. + The result is an empty string if all options were parsed ok, otherwise an + error message which the caller must free. N.B. These commands affect all debug format settings, they are not cumulative. If a format is not specified, it is turned off. @@ -1291,10 +1307,6 @@ handle_detach (char *own_buf) static std::string parse_debug_format_options (const char *arg, int is_monitor) { - VEC (char_ptr) *options; - int ix; - char *option; - /* First turn all debug format options off. */ debug_timestamp = 0; @@ -1302,23 +1314,24 @@ parse_debug_format_options (const char *arg, int is_monitor) while (isspace (*arg)) ++arg; - options = delim_string_to_char_ptr_vec (arg, ','); + std::vector> options + = delim_string_to_char_ptr_vec (arg, ','); - for (ix = 0; VEC_iterate (char_ptr, options, ix, option); ++ix) + for (const gdb::unique_xmalloc_ptr &option : options) { - if (strcmp (option, "all") == 0) + if (strcmp (option.get (), "all") == 0) { debug_timestamp = 1; if (is_monitor) monitor_output ("All extra debug format options enabled.\n"); } - else if (strcmp (option, "none") == 0) + else if (strcmp (option.get (), "none") == 0) { debug_timestamp = 0; if (is_monitor) monitor_output ("All extra debug format options disabled.\n"); } - else if (strcmp (option, "timestamp") == 0) + else if (strcmp (option.get (), "timestamp") == 0) { debug_timestamp = 1; if (is_monitor) @@ -1330,16 +1343,10 @@ parse_debug_format_options (const char *arg, int is_monitor) continue; } else - { - std::string msg - = string_printf ("Unknown debug-format argument: \"%s\"\n", option); - - free_char_ptr_vec (options); - return msg; - } + return string_printf ("Unknown debug-format argument: \"%s\"\n", + option.get ()); } - free_char_ptr_vec (options); return std::string (); } @@ -1624,15 +1631,17 @@ handle_qxfer_statictrace (const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, LONGEST len) { + client_state &cs = get_client_state (); ULONGEST nbytes; if (writebuf != NULL) return -2; - if (annex[0] != '\0' || current_thread == NULL || current_traceframe == -1) + if (annex[0] != '\0' || current_thread == NULL + || cs.current_traceframe == -1) return -1; - if (traceframe_read_sdata (current_traceframe, offset, + if (traceframe_read_sdata (cs.current_traceframe, offset, readbuf, len, &nbytes)) return -1; return nbytes; @@ -1748,13 +1757,14 @@ handle_qxfer_traceframe_info (const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, LONGEST len) { + client_state &cs = get_client_state (); static char *result = 0; static unsigned int result_length = 0; if (writebuf != NULL) return -2; - if (!target_running () || annex[0] != '\0' || current_traceframe == -1) + if (!target_running () || annex[0] != '\0' || cs.current_traceframe == -1) return -1; if (offset == 0) @@ -1768,7 +1778,7 @@ handle_qxfer_traceframe_info (const char *annex, buffer_init (&buffer); - traceframe_read_info (current_traceframe, &buffer); + traceframe_read_info (cs.current_traceframe, &buffer); result = buffer_finish (&buffer); result_length = strlen (result); @@ -1813,31 +1823,32 @@ handle_qxfer_btrace (const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, LONGEST len) { + client_state &cs = get_client_state (); static struct buffer cache; struct thread_info *thread; enum btrace_read_type type; int result; - if (the_target->read_btrace == NULL || writebuf != NULL) + if (writebuf != NULL) return -2; - if (ptid_equal (general_thread, null_ptid) - || ptid_equal (general_thread, minus_one_ptid)) + if (cs.general_thread == null_ptid + || cs.general_thread == minus_one_ptid) { - strcpy (own_buf, "E.Must select a single thread."); + strcpy (cs.own_buf, "E.Must select a single thread."); return -3; } - thread = find_thread_ptid (general_thread); + thread = find_thread_ptid (cs.general_thread); if (thread == NULL) { - strcpy (own_buf, "E.No such thread."); + strcpy (cs.own_buf, "E.No such thread."); return -3; } if (thread->btrace == NULL) { - strcpy (own_buf, "E.Btrace not enabled."); + strcpy (cs.own_buf, "E.Btrace not enabled."); return -3; } @@ -1849,7 +1860,7 @@ handle_qxfer_btrace (const char *annex, type = BTRACE_READ_DELTA; else { - strcpy (own_buf, "E.Bad annex."); + strcpy (cs.own_buf, "E.Bad annex."); return -3; } @@ -1857,12 +1868,21 @@ handle_qxfer_btrace (const char *annex, { buffer_free (&cache); - result = target_read_btrace (thread->btrace, &cache, type); - if (result != 0) + TRY + { + result = target_read_btrace (thread->btrace, &cache, type); + if (result != 0) + memcpy (cs.own_buf, cache.buffer, cache.used_size); + } + CATCH (exception, RETURN_MASK_ERROR) { - memcpy (own_buf, cache.buffer, cache.used_size); - return -3; + sprintf (cs.own_buf, "E.%s", exception.message); + result = -1; } + END_CATCH + + if (result != 0) + return -3; } else if (offset > cache.used_size) { @@ -1885,33 +1905,34 @@ handle_qxfer_btrace_conf (const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, LONGEST len) { + client_state &cs = get_client_state (); static struct buffer cache; struct thread_info *thread; int result; - if (the_target->read_btrace_conf == NULL || writebuf != NULL) + if (writebuf != NULL) return -2; if (annex[0] != '\0') return -1; - if (ptid_equal (general_thread, null_ptid) - || ptid_equal (general_thread, minus_one_ptid)) + if (cs.general_thread == null_ptid + || cs.general_thread == minus_one_ptid) { - strcpy (own_buf, "E.Must select a single thread."); + strcpy (cs.own_buf, "E.Must select a single thread."); return -3; } - thread = find_thread_ptid (general_thread); + thread = find_thread_ptid (cs.general_thread); if (thread == NULL) { - strcpy (own_buf, "E.No such thread."); + strcpy (cs.own_buf, "E.No such thread."); return -3; } if (thread->btrace == NULL) { - strcpy (own_buf, "E.Btrace not enabled."); + strcpy (cs.own_buf, "E.Btrace not enabled."); return -3; } @@ -1919,12 +1940,21 @@ handle_qxfer_btrace_conf (const char *annex, { buffer_free (&cache); - result = target_read_btrace_conf (thread->btrace, &cache); - if (result != 0) + TRY + { + result = target_read_btrace_conf (thread->btrace, &cache); + if (result != 0) + memcpy (cs.own_buf, cache.buffer, cache.used_size); + } + CATCH (exception, RETURN_MASK_ERROR) { - memcpy (own_buf, cache.buffer, cache.used_size); - return -3; + sprintf (cs.own_buf, "E.%s", exception.message); + result = -1; } + END_CATCH + + if (result != 0) + return -3; } else if (offset > cache.used_size) { @@ -2104,27 +2134,10 @@ crc32 (CORE_ADDR base, int len, unsigned int crc) static void supported_btrace_packets (char *buf) { - int btrace_supported = 0; - - if (target_supports_btrace (BTRACE_FORMAT_BTS)) - { - strcat (buf, ";Qbtrace:bts+"); - strcat (buf, ";Qbtrace-conf:bts:size+"); - - btrace_supported = 1; - } - - if (target_supports_btrace (BTRACE_FORMAT_PT)) - { - strcat (buf, ";Qbtrace:pt+"); - strcat (buf, ";Qbtrace-conf:pt:size+"); - - btrace_supported = 1; - } - - if (!btrace_supported) - return; - + strcat (buf, ";Qbtrace:bts+"); + strcat (buf, ";Qbtrace-conf:bts:size+"); + strcat (buf, ";Qbtrace:pt+"); + strcat (buf, ";Qbtrace-conf:pt:size+"); strcat (buf, ";Qbtrace:off+"); strcat (buf, ";qXfer:btrace:read+"); strcat (buf, ";qXfer:btrace-conf:read+"); @@ -2135,6 +2148,7 @@ supported_btrace_packets (char *buf) static void handle_query (char *own_buf, int packet_len, int *new_packet_len_p) { + client_state &cs = get_client_state (); static std::list::const_iterator thread_iter; /* Reply the current thread id. */ @@ -2143,8 +2157,8 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p) ptid_t ptid; require_running_or_return (own_buf); - if (general_thread != null_ptid && general_thread != minus_one_ptid) - ptid = general_thread; + if (cs.general_thread != null_ptid && cs.general_thread != minus_one_ptid) + ptid = cs.general_thread; else { thread_iter = all_threads.begin (); @@ -2169,7 +2183,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p) if (current_thread == NULL) { current_thread - = find_any_thread_of_pid (ptid_get_pid (general_thread)); + = find_any_thread_of_pid (cs.general_thread.pid ()); /* Just in case, if we didn't find a thread, then bail out instead of crashing. */ @@ -2289,7 +2303,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p) /* GDB supports and wants multi-process support if possible. */ if (target_supports_multi_process ()) - multi_process = 1; + cs.multi_process = 1; } else if (strcmp (p, "qRelocInsn+") == 0) { @@ -2302,35 +2316,35 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p) by a software breakpoint and for us to handle PC adjustment if necessary on this target. */ if (target_supports_stopped_by_sw_breakpoint ()) - swbreak_feature = 1; + cs.swbreak_feature = 1; } else if (strcmp (p, "hwbreak+") == 0) { /* GDB wants us to report whether a trap is caused by a hardware breakpoint. */ if (target_supports_stopped_by_hw_breakpoint ()) - hwbreak_feature = 1; + cs.hwbreak_feature = 1; } else if (strcmp (p, "fork-events+") == 0) { /* GDB supports and wants fork events if possible. */ if (target_supports_fork_events ()) - report_fork_events = 1; + cs.report_fork_events = 1; } else if (strcmp (p, "vfork-events+") == 0) { /* GDB supports and wants vfork events if possible. */ if (target_supports_vfork_events ()) - report_vfork_events = 1; + cs.report_vfork_events = 1; } else if (strcmp (p, "exec-events+") == 0) { /* GDB supports and wants exec events if possible. */ if (target_supports_exec_events ()) - report_exec_events = 1; + cs.report_exec_events = 1; } else if (strcmp (p, "vContSupported+") == 0) - vCont_supported = 1; + cs.vCont_supported = 1; else if (strcmp (p, "QThreadEvents+") == 0) ; else if (strcmp (p, "no-resumed+") == 0) @@ -2395,7 +2409,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p) qXfer:feature:read at all, we will never be re-queried. */ strcat (own_buf, ";qXfer:features:read+"); - if (transport_is_reliable) + if (cs.transport_is_reliable) strcat (own_buf, ";QStartNoAckMode+"); if (the_target->qxfer_osdata != NULL) @@ -2685,11 +2699,11 @@ visit_actioned_threads (thread_info *thread, { const struct thread_resume *action = &actions[i]; - if (ptid_equal (action->thread, minus_one_ptid) - || ptid_equal (action->thread, thread->id) - || ((ptid_get_pid (action->thread) + if (action->thread == minus_one_ptid + || action->thread == thread->id + || ((action->thread.pid () == thread->id.pid ()) - && ptid_get_lwp (action->thread) == -1)) + && action->thread.lwp () == -1)) { if ((*callback) (action, thread)) return true; @@ -2706,13 +2720,14 @@ static int handle_pending_status (const struct thread_resume *resumption, struct thread_info *thread) { + client_state &cs = get_client_state (); if (thread->status_pending_p) { thread->status_pending_p = 0; - last_status = thread->last_status; - last_ptid = thread->id; - prepare_resume_reply (own_buf, last_ptid, &last_status); + cs.last_status = thread->last_status; + cs.last_ptid = thread->id; + prepare_resume_reply (cs.own_buf, cs.last_ptid, &cs.last_status); return 1; } return 0; @@ -2832,6 +2847,7 @@ err: static void resume (struct thread_resume *actions, size_t num_actions) { + client_state &cs = get_client_state (); if (!non_stop) { /* Check if among the threads that GDB wants actioned, there's @@ -2854,37 +2870,37 @@ resume (struct thread_resume *actions, size_t num_actions) (*the_target->resume) (actions, num_actions); if (non_stop) - write_ok (own_buf); + write_ok (cs.own_buf); else { - last_ptid = mywait (minus_one_ptid, &last_status, 0, 1); + cs.last_ptid = mywait (minus_one_ptid, &cs.last_status, 0, 1); - if (last_status.kind == TARGET_WAITKIND_NO_RESUMED + if (cs.last_status.kind == TARGET_WAITKIND_NO_RESUMED && !report_no_resumed) { /* The client does not support this stop reply. At least return error. */ - sprintf (own_buf, "E.No unwaited-for children left."); + sprintf (cs.own_buf, "E.No unwaited-for children left."); disable_async_io (); return; } - if (last_status.kind != TARGET_WAITKIND_EXITED - && last_status.kind != TARGET_WAITKIND_SIGNALLED - && last_status.kind != TARGET_WAITKIND_NO_RESUMED) - current_thread->last_status = last_status; + if (cs.last_status.kind != TARGET_WAITKIND_EXITED + && cs.last_status.kind != TARGET_WAITKIND_SIGNALLED + && cs.last_status.kind != TARGET_WAITKIND_NO_RESUMED) + current_thread->last_status = cs.last_status; /* From the client's perspective, all-stop mode always stops all threads implicitly (and the target backend has already done so by now). Tag all threads as "want-stopped", so we don't resume them implicitly without the client telling us to. */ gdb_wants_all_threads_stopped (); - prepare_resume_reply (own_buf, last_ptid, &last_status); + prepare_resume_reply (cs.own_buf, cs.last_ptid, &cs.last_status); disable_async_io (); - if (last_status.kind == TARGET_WAITKIND_EXITED - || last_status.kind == TARGET_WAITKIND_SIGNALLED) - target_mourn_inferior (last_ptid); + if (cs.last_status.kind == TARGET_WAITKIND_EXITED + || cs.last_status.kind == TARGET_WAITKIND_SIGNALLED) + target_mourn_inferior (cs.last_ptid); } } @@ -2892,6 +2908,7 @@ resume (struct thread_resume *actions, size_t num_actions) static int handle_v_attach (char *own_buf) { + client_state &cs = get_client_state (); int pid; pid = strtol (own_buf + 8, NULL, 16); @@ -2911,7 +2928,7 @@ handle_v_attach (char *own_buf) write_ok (own_buf); } else - prepare_resume_reply (own_buf, last_ptid, &last_status); + prepare_resume_reply (own_buf, cs.last_ptid, &cs.last_status); return 1; } @@ -2926,6 +2943,7 @@ handle_v_attach (char *own_buf) static int handle_v_run (char *own_buf) { + client_state &cs = get_client_state (); char *p, *next_p; std::vector new_argv; char *new_program_name = NULL; @@ -3016,7 +3034,7 @@ handle_v_run (char *own_buf) { /* GDB didn't specify a program to run. Use the program from the last run with the new argument list. */ - if (program_name == NULL) + if (program_path.get () == NULL) { write_enn (own_buf); free_vector_argv (new_argv); @@ -3024,26 +3042,23 @@ handle_v_run (char *own_buf) } } else - { - xfree (program_name); - program_name = new_program_name; - } + program_path.set (gdb::unique_xmalloc_ptr (new_program_name)); /* Free the old argv and install the new one. */ free_vector_argv (program_args); program_args = new_argv; - create_inferior (program_name, program_args); + create_inferior (program_path.get (), program_args); - if (last_status.kind == TARGET_WAITKIND_STOPPED) + if (cs.last_status.kind == TARGET_WAITKIND_STOPPED) { - prepare_resume_reply (own_buf, last_ptid, &last_status); + prepare_resume_reply (own_buf, cs.last_ptid, &cs.last_status); /* In non-stop, sending a resume reply doesn't set the general thread, but GDB assumes a vRun sets it (this is so GDB can query which is the main thread of the new inferior. */ if (non_stop) - general_thread = last_ptid; + cs.general_thread = cs.last_ptid; return 1; } @@ -3058,18 +3073,22 @@ handle_v_run (char *own_buf) static int handle_v_kill (char *own_buf) { + client_state &cs = get_client_state (); int pid; char *p = &own_buf[6]; - if (multi_process) + if (cs.multi_process) pid = strtol (p, NULL, 16); else pid = signal_pid; - if (pid != 0 && kill_inferior (pid) == 0) + + process_info *proc = find_process_pid (pid); + + if (proc != nullptr && kill_inferior (proc) == 0) { - last_status.kind = TARGET_WAITKIND_SIGNALLED; - last_status.value.sig = GDB_SIGNAL_KILL; - last_ptid = pid_to_ptid (pid); - discard_queued_stop_replies (last_ptid); + cs.last_status.kind = TARGET_WAITKIND_SIGNALLED; + cs.last_status.value.sig = GDB_SIGNAL_KILL; + cs.last_ptid = ptid_t (pid); + discard_queued_stop_replies (cs.last_ptid); write_ok (own_buf); return 1; } @@ -3084,6 +3103,7 @@ handle_v_kill (char *own_buf) void handle_v_requests (char *own_buf, int packet_len, int *new_packet_len) { + client_state &cs = get_client_state (); if (!disable_packet_vCont) { if (strcmp (own_buf, "vCtrlC") == 0) @@ -3105,7 +3125,7 @@ handle_v_requests (char *own_buf, int packet_len, int *new_packet_len) if (target_supports_hardware_single_step () || target_supports_software_single_step () - || !vCont_supported) + || !cs.vCont_supported) { /* If target supports single step either by hardware or by software, add actions s and S to the list of supported @@ -3131,7 +3151,7 @@ handle_v_requests (char *own_buf, int packet_len, int *new_packet_len) if (startswith (own_buf, "vAttach;")) { - if ((!extended_protocol || !multi_process) && target_running ()) + if ((!extended_protocol || !cs.multi_process) && target_running ()) { fprintf (stderr, "Already debugging a process\n"); write_enn (own_buf); @@ -3143,7 +3163,7 @@ handle_v_requests (char *own_buf, int packet_len, int *new_packet_len) if (startswith (own_buf, "vRun;")) { - if ((!extended_protocol || !multi_process) && target_running ()) + if ((!extended_protocol || !cs.multi_process) && target_running ()) { fprintf (stderr, "Already debugging a process\n"); write_enn (own_buf); @@ -3180,12 +3200,13 @@ handle_v_requests (char *own_buf, int packet_len, int *new_packet_len) static void myresume (char *own_buf, int step, int sig) { + client_state &cs = get_client_state (); struct thread_resume resume_info[2]; int n = 0; int valid_cont_thread; - valid_cont_thread = (!ptid_equal (cont_thread, null_ptid) - && !ptid_equal (cont_thread, minus_one_ptid)); + valid_cont_thread = (cs.cont_thread != null_ptid + && cs.cont_thread != minus_one_ptid); if (step || sig || valid_cont_thread) { @@ -3300,6 +3321,8 @@ set_pending_status_callback (thread_info *thread) static void handle_status (char *own_buf) { + client_state &cs = get_client_state (); + /* GDB is connected, don't forward events to the target anymore. */ for_each_process ([] (process_info *process) { process->gdb_detached = 0; @@ -3316,7 +3339,7 @@ handle_status (char *own_buf) /* The first is sent immediatly. OK is sent if there is no stopped thread, which is the same handling of the vStopped packet (by design). */ - notif_write_event (¬if_stop, own_buf); + notif_write_event (¬if_stop, cs.own_buf); } else { @@ -3336,17 +3359,17 @@ handle_status (char *own_buf) /* Prefer the last thread that reported an event to GDB (even if that was a GDB_SIGNAL_TRAP). */ - if (last_status.kind != TARGET_WAITKIND_IGNORE - && last_status.kind != TARGET_WAITKIND_EXITED - && last_status.kind != TARGET_WAITKIND_SIGNALLED) - thread = find_thread_ptid (last_ptid); + if (cs.last_status.kind != TARGET_WAITKIND_IGNORE + && cs.last_status.kind != TARGET_WAITKIND_EXITED + && cs.last_status.kind != TARGET_WAITKIND_SIGNALLED) + thread = find_thread_ptid (cs.last_ptid); /* If the last event thread is not found for some reason, look for some other thread that might have an event to report. */ if (thread == NULL) - thread = find_thread ([] (thread_info *thread) + thread = find_thread ([] (thread_info *thr_arg) { - return thread->status_pending_p; + return thr_arg->status_pending_p; }); /* If we're still out of luck, simply pick the first thread in @@ -3364,7 +3387,7 @@ handle_status (char *own_buf) /* GDB assumes the current thread is the thread we're reporting the status for. */ - general_thread = thread->id; + cs.general_thread = thread->id; set_desired_thread (); gdb_assert (tp->last_status.kind != TARGET_WAITKIND_IGNORE); @@ -3461,10 +3484,8 @@ gdbserver_show_disableable (FILE *stream) static void kill_inferior_callback (process_info *process) { - int pid = process->pid; - - kill_inferior (pid); - discard_queued_stop_replies (pid_to_ptid (pid)); + kill_inferior (process); + discard_queued_stop_replies (ptid_t (process->pid)); } /* Call this when exiting gdbserver with possible inferiors that need @@ -3506,11 +3527,11 @@ detach_or_kill_for_exit (void) int pid = process->pid; if (process->attached) - detach_inferior (pid); + detach_inferior (process); else - kill_inferior (pid); + kill_inferior (process); - discard_queued_stop_replies (pid_to_ptid (pid)); + discard_queued_stop_replies (ptid_t (pid)); }); } @@ -3556,6 +3577,15 @@ captured_main (int argc, char *argv[]) const char *selftest_filter = NULL; #endif + current_directory = getcwd (NULL, 0); + client_state &cs = get_client_state (); + + if (current_directory == NULL) + { + error (_("Could not find current working directory: %s"), + safe_strerror (errno)); + } + while (*next_arg != NULL && **next_arg == '-') { if (strcmp (*next_arg, "--version") == 0) @@ -3664,9 +3694,9 @@ captured_main (int argc, char *argv[]) break; } else if (strcmp (*next_arg, "--disable-randomization") == 0) - disable_randomization = 1; + cs.disable_randomization = 1; else if (strcmp (*next_arg, "--no-disable-randomization") == 0) - disable_randomization = 0; + cs.disable_randomization = 0; else if (strcmp (*next_arg, "--startup-with-shell") == 0) startup_with_shell = true; else if (strcmp (*next_arg, "--no-startup-with-shell") == 0) @@ -3753,7 +3783,6 @@ captured_main (int argc, char *argv[]) initialize_tracepoint (); initialize_notif (); - own_buf = (char *) xmalloc (PBUFSIZ + 1); mem_buf = (unsigned char *) xmalloc (PBUFSIZ); if (selftest) @@ -3771,13 +3800,13 @@ captured_main (int argc, char *argv[]) int i, n; n = argc - (next_arg - argv); - program_name = xstrdup (next_arg[0]); + program_path.set (gdb::unique_xmalloc_ptr (xstrdup (next_arg[0]))); for (i = 1; i < n; i++) program_args.push_back (xstrdup (next_arg[i])); program_args.push_back (NULL); /* Wait till we are at first instruction in program. */ - create_inferior (program_name, program_args); + create_inferior (program_path.get (), program_args); /* We are now (hopefully) stopped at the first instruction of the target process. This assumes that the target process was @@ -3792,9 +3821,9 @@ captured_main (int argc, char *argv[]) } else { - last_status.kind = TARGET_WAITKIND_EXITED; - last_status.value.integer = 0; - last_ptid = minus_one_ptid; + cs.last_status.kind = TARGET_WAITKIND_EXITED; + cs.last_status.value.integer = 0; + cs.last_ptid = minus_one_ptid; } make_cleanup (detach_or_kill_for_exit_cleanup, NULL); @@ -3803,8 +3832,8 @@ captured_main (int argc, char *argv[]) shared library event" notice on gdb side. */ dlls_changed = 0; - if (last_status.kind == TARGET_WAITKIND_EXITED - || last_status.kind == TARGET_WAITKIND_SIGNALLED) + if (cs.last_status.kind == TARGET_WAITKIND_EXITED + || cs.last_status.kind == TARGET_WAITKIND_SIGNALLED) was_running = 0; else was_running = 1; @@ -3814,18 +3843,17 @@ captured_main (int argc, char *argv[]) while (1) { - - noack_mode = 0; - multi_process = 0; - report_fork_events = 0; - report_vfork_events = 0; - report_exec_events = 0; + cs.noack_mode = 0; + cs.multi_process = 0; + cs.report_fork_events = 0; + cs.report_vfork_events = 0; + cs.report_exec_events = 0; /* Be sure we're out of tfind mode. */ - current_traceframe = -1; - cont_thread = null_ptid; - swbreak_feature = 0; - hwbreak_feature = 0; - vCont_supported = 0; + cs.current_traceframe = -1; + cs.cont_thread = null_ptid; + cs.swbreak_feature = 0; + cs.hwbreak_feature = 0; + cs.vCont_supported = 0; remote_open (port); @@ -3901,8 +3929,8 @@ captured_main (int argc, char *argv[]) if (response_needed) { - write_enn (own_buf); - putpkt (own_buf); + write_enn (cs.own_buf); + putpkt (cs.own_buf); } if (run_once) @@ -3997,9 +4025,9 @@ process_point_options (struct gdb_breakpoint *bp, const char **packet) static int process_serial_event (void) { + client_state &cs = get_client_state (); int signal; unsigned int len; - int res; CORE_ADDR mem_addr; unsigned char sig; int packet_len; @@ -4008,7 +4036,7 @@ process_serial_event (void) disable_async_io (); response_needed = 0; - packet_len = getpkt (own_buf); + packet_len = getpkt (cs.own_buf); if (packet_len <= 0) { remote_close (); @@ -4017,31 +4045,31 @@ process_serial_event (void) } response_needed = 1; - char ch = own_buf[0]; + char ch = cs.own_buf[0]; switch (ch) { case 'q': - handle_query (own_buf, packet_len, &new_packet_len); + handle_query (cs.own_buf, packet_len, &new_packet_len); break; case 'Q': - handle_general_set (own_buf); + handle_general_set (cs.own_buf); break; case 'D': - handle_detach (own_buf); + handle_detach (cs.own_buf); break; case '!': extended_protocol = 1; - write_ok (own_buf); + write_ok (cs.own_buf); break; case '?': - handle_status (own_buf); + handle_status (cs.own_buf); break; case 'H': - if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's') + if (cs.own_buf[1] == 'c' || cs.own_buf[1] == 'g' || cs.own_buf[1] == 's') { - require_running_or_break (own_buf); + require_running_or_break (cs.own_buf); - ptid_t thread_id = read_ptid (&own_buf[2], NULL); + ptid_t thread_id = read_ptid (&cs.own_buf[2], NULL); if (thread_id == null_ptid || thread_id == minus_one_ptid) thread_id = null_ptid; @@ -4052,7 +4080,7 @@ process_serial_event (void) if (thread == NULL) { - write_enn (own_buf); + write_enn (cs.own_buf); break; } @@ -4063,52 +4091,52 @@ process_serial_event (void) /* The ptid represents a lwp/tid. */ if (find_thread_ptid (thread_id) == NULL) { - write_enn (own_buf); + write_enn (cs.own_buf); break; } } - if (own_buf[1] == 'g') + if (cs.own_buf[1] == 'g') { - if (ptid_equal (thread_id, null_ptid)) + if (thread_id == null_ptid) { /* GDB is telling us to choose any thread. Check if the currently selected thread is still valid. If it is not, select the first available. */ - thread_info *thread = find_thread_ptid (general_thread); + thread_info *thread = find_thread_ptid (cs.general_thread); if (thread == NULL) thread = get_first_thread (); thread_id = thread->id; } - general_thread = thread_id; + cs.general_thread = thread_id; set_desired_thread (); gdb_assert (current_thread != NULL); } - else if (own_buf[1] == 'c') - cont_thread = thread_id; + else if (cs.own_buf[1] == 'c') + cs.cont_thread = thread_id; - write_ok (own_buf); + write_ok (cs.own_buf); } else { /* Silently ignore it so that gdb can extend the protocol without compatibility headaches. */ - own_buf[0] = '\0'; + cs.own_buf[0] = '\0'; } break; case 'g': - require_running_or_break (own_buf); - if (current_traceframe >= 0) + require_running_or_break (cs.own_buf); + if (cs.current_traceframe >= 0) { struct regcache *regcache = new_register_cache (current_target_desc ()); - if (fetch_traceframe_registers (current_traceframe, + if (fetch_traceframe_registers (cs.current_traceframe, regcache, -1) == 0) - registers_to_string (regcache, own_buf); + registers_to_string (regcache, cs.own_buf); else - write_enn (own_buf); + write_enn (cs.own_buf); free_register_cache (regcache); } else @@ -4116,85 +4144,87 @@ process_serial_event (void) struct regcache *regcache; if (!set_desired_thread ()) - write_enn (own_buf); + write_enn (cs.own_buf); else { regcache = get_thread_regcache (current_thread, 1); - registers_to_string (regcache, own_buf); + registers_to_string (regcache, cs.own_buf); } } break; case 'G': - require_running_or_break (own_buf); - if (current_traceframe >= 0) - write_enn (own_buf); + require_running_or_break (cs.own_buf); + if (cs.current_traceframe >= 0) + write_enn (cs.own_buf); else { struct regcache *regcache; if (!set_desired_thread ()) - write_enn (own_buf); + write_enn (cs.own_buf); else { regcache = get_thread_regcache (current_thread, 1); - registers_from_string (regcache, &own_buf[1]); - write_ok (own_buf); + registers_from_string (regcache, &cs.own_buf[1]); + write_ok (cs.own_buf); } } break; case 'm': - require_running_or_break (own_buf); - decode_m_packet (&own_buf[1], &mem_addr, &len); - res = gdb_read_memory (mem_addr, mem_buf, len); - if (res < 0) - write_enn (own_buf); - else - bin2hex (mem_buf, own_buf, res); + { + require_running_or_break (cs.own_buf); + decode_m_packet (&cs.own_buf[1], &mem_addr, &len); + int res = gdb_read_memory (mem_addr, mem_buf, len); + if (res < 0) + write_enn (cs.own_buf); + else + bin2hex (mem_buf, cs.own_buf, res); + } break; case 'M': - require_running_or_break (own_buf); - decode_M_packet (&own_buf[1], &mem_addr, &len, &mem_buf); + require_running_or_break (cs.own_buf); + decode_M_packet (&cs.own_buf[1], &mem_addr, &len, &mem_buf); if (gdb_write_memory (mem_addr, mem_buf, len) == 0) - write_ok (own_buf); + write_ok (cs.own_buf); else - write_enn (own_buf); + write_enn (cs.own_buf); break; case 'X': - require_running_or_break (own_buf); - if (decode_X_packet (&own_buf[1], packet_len - 1, + require_running_or_break (cs.own_buf); + if (decode_X_packet (&cs.own_buf[1], packet_len - 1, &mem_addr, &len, &mem_buf) < 0 || gdb_write_memory (mem_addr, mem_buf, len) != 0) - write_enn (own_buf); + write_enn (cs.own_buf); else - write_ok (own_buf); + write_ok (cs.own_buf); break; case 'C': - require_running_or_break (own_buf); - hex2bin (own_buf + 1, &sig, 1); + require_running_or_break (cs.own_buf); + hex2bin (cs.own_buf + 1, &sig, 1); if (gdb_signal_to_host_p ((enum gdb_signal) sig)) signal = gdb_signal_to_host ((enum gdb_signal) sig); else signal = 0; - myresume (own_buf, 0, signal); + myresume (cs.own_buf, 0, signal); break; case 'S': - require_running_or_break (own_buf); - hex2bin (own_buf + 1, &sig, 1); + require_running_or_break (cs.own_buf); + hex2bin (cs.own_buf + 1, &sig, 1); if (gdb_signal_to_host_p ((enum gdb_signal) sig)) signal = gdb_signal_to_host ((enum gdb_signal) sig); else signal = 0; - myresume (own_buf, 1, signal); + myresume (cs.own_buf, 1, signal); break; case 'c': - require_running_or_break (own_buf); + require_running_or_break (cs.own_buf); signal = 0; - myresume (own_buf, 0, signal); + myresume (cs.own_buf, 0, signal); break; case 's': - require_running_or_break (own_buf); + require_running_or_break (cs.own_buf); signal = 0; - myresume (own_buf, 1, signal); + myresume (cs.own_buf, 1, signal); break; case 'Z': /* insert_ ... */ /* Fallthrough. */ @@ -4203,10 +4233,10 @@ process_serial_event (void) char *dataptr; ULONGEST addr; int kind; - char type = own_buf[1]; + char type = cs.own_buf[1]; int res; const int insert = ch == 'Z'; - const char *p = &own_buf[3]; + const char *p = &cs.own_buf[3]; p = unpack_varlen_hex (p, &addr); kind = strtol (p + 1, &dataptr, 16); @@ -4234,12 +4264,12 @@ process_serial_event (void) res = delete_gdb_breakpoint (type, addr, kind); if (res == 0) - write_ok (own_buf); + write_ok (cs.own_buf); else if (res == 1) /* Unsupported. */ - own_buf[0] = '\0'; + cs.own_buf[0] = '\0'; else - write_enn (own_buf); + write_enn (cs.own_buf); break; } case 'k': @@ -4257,8 +4287,8 @@ process_serial_event (void) running. The traditional protocol will exit instead. */ if (extended_protocol) { - last_status.kind = TARGET_WAITKIND_EXITED; - last_status.value.sig = GDB_SIGNAL_KILL; + cs.last_status.kind = TARGET_WAITKIND_EXITED; + cs.last_status.value.sig = GDB_SIGNAL_KILL; return 0; } else @@ -4266,19 +4296,19 @@ process_serial_event (void) case 'T': { - require_running_or_break (own_buf); + require_running_or_break (cs.own_buf); - ptid_t thread_id = read_ptid (&own_buf[1], NULL); + ptid_t thread_id = read_ptid (&cs.own_buf[1], NULL); if (find_thread_ptid (thread_id) == NULL) { - write_enn (own_buf); + write_enn (cs.own_buf); break; } if (mythread_alive (thread_id)) - write_ok (own_buf); + write_ok (cs.own_buf); else - write_enn (own_buf); + write_enn (cs.own_buf); } break; case 'R': @@ -4294,26 +4324,26 @@ process_serial_event (void) fprintf (stderr, "GDBserver restarting\n"); /* Wait till we are at 1st instruction in prog. */ - if (program_name != NULL) + if (program_path.get () != NULL) { - create_inferior (program_name, program_args); + create_inferior (program_path.get (), program_args); - if (last_status.kind == TARGET_WAITKIND_STOPPED) + if (cs.last_status.kind == TARGET_WAITKIND_STOPPED) { /* Stopped at the first instruction of the target process. */ - general_thread = last_ptid; + cs.general_thread = cs.last_ptid; } else { /* Something went wrong. */ - general_thread = null_ptid; + cs.general_thread = null_ptid; } } else { - last_status.kind = TARGET_WAITKIND_EXITED; - last_status.value.sig = GDB_SIGNAL_KILL; + cs.last_status.kind = TARGET_WAITKIND_EXITED; + cs.last_status.value.sig = GDB_SIGNAL_KILL; } return 0; } @@ -4322,26 +4352,26 @@ process_serial_event (void) /* It is a request we don't understand. Respond with an empty packet so that gdb knows that we don't support this request. */ - own_buf[0] = '\0'; + cs.own_buf[0] = '\0'; break; } case 'v': /* Extended (long) request. */ - handle_v_requests (own_buf, packet_len, &new_packet_len); + handle_v_requests (cs.own_buf, packet_len, &new_packet_len); break; default: /* It is a request we don't understand. Respond with an empty packet so that gdb knows that we don't support this request. */ - own_buf[0] = '\0'; + cs.own_buf[0] = '\0'; break; } if (new_packet_len != -1) - putpkt_binary (own_buf, new_packet_len); + putpkt_binary (cs.own_buf, new_packet_len); else - putpkt (own_buf); + putpkt (cs.own_buf); response_needed = 0; @@ -4388,30 +4418,31 @@ push_stop_notification (ptid_t ptid, struct target_waitstatus *status) int handle_target_event (int err, gdb_client_data client_data) { + client_state &cs = get_client_state (); if (debug_threads) debug_printf ("handling possible target event\n"); - last_ptid = mywait (minus_one_ptid, &last_status, + cs.last_ptid = mywait (minus_one_ptid, &cs.last_status, TARGET_WNOHANG, 1); - if (last_status.kind == TARGET_WAITKIND_NO_RESUMED) + if (cs.last_status.kind == TARGET_WAITKIND_NO_RESUMED) { if (gdb_connected () && report_no_resumed) - push_stop_notification (null_ptid, &last_status); + push_stop_notification (null_ptid, &cs.last_status); } - else if (last_status.kind != TARGET_WAITKIND_IGNORE) + else if (cs.last_status.kind != TARGET_WAITKIND_IGNORE) { - int pid = ptid_get_pid (last_ptid); + int pid = cs.last_ptid.pid (); struct process_info *process = find_process_pid (pid); int forward_event = !gdb_connected () || process->gdb_detached; - if (last_status.kind == TARGET_WAITKIND_EXITED - || last_status.kind == TARGET_WAITKIND_SIGNALLED) + if (cs.last_status.kind == TARGET_WAITKIND_EXITED + || cs.last_status.kind == TARGET_WAITKIND_SIGNALLED) { mark_breakpoints_out (process); - target_mourn_inferior (last_ptid); + target_mourn_inferior (cs.last_ptid); } - else if (last_status.kind == TARGET_WAITKIND_THREAD_EXITED) + else if (cs.last_status.kind == TARGET_WAITKIND_THREAD_EXITED) ; else { @@ -4419,7 +4450,7 @@ handle_target_event (int err, gdb_client_data client_data) "want-stopped" state to what the client wants, until it gets a new resume action. */ current_thread->last_resume_kind = resume_stop; - current_thread->last_status = last_status; + current_thread->last_status = cs.last_status; } if (forward_event) @@ -4430,9 +4461,9 @@ handle_target_event (int err, gdb_client_data client_data) exit (0); } - if (last_status.kind == TARGET_WAITKIND_EXITED - || last_status.kind == TARGET_WAITKIND_SIGNALLED - || last_status.kind == TARGET_WAITKIND_THREAD_EXITED) + if (cs.last_status.kind == TARGET_WAITKIND_EXITED + || cs.last_status.kind == TARGET_WAITKIND_SIGNALLED + || cs.last_status.kind == TARGET_WAITKIND_THREAD_EXITED) ; else { @@ -4444,18 +4475,18 @@ handle_target_event (int err, gdb_client_data client_data) if (debug_threads) debug_printf ("GDB not connected; forwarding event %d for" " [%s]\n", - (int) last_status.kind, - target_pid_to_str (last_ptid)); + (int) cs.last_status.kind, + target_pid_to_str (cs.last_ptid)); - if (last_status.kind == TARGET_WAITKIND_STOPPED) - signal = last_status.value.sig; + if (cs.last_status.kind == TARGET_WAITKIND_STOPPED) + signal = cs.last_status.value.sig; else signal = GDB_SIGNAL_0; - target_continue (last_ptid, signal); + target_continue (cs.last_ptid, signal); } } else - push_stop_notification (last_ptid, &last_status); + push_stop_notification (cs.last_ptid, &cs.last_status); } /* Be sure to not change the selected thread behind GDB's back.