aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/gdbserver/server.c')
-rw-r--r--gdb/gdbserver/server.c531
1 files changed, 282 insertions, 249 deletions
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 3838351..f3eee31 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -40,6 +40,22 @@
#include "job-control.h"
#include "environ.h"
+#include "common/selftest.h"
+
+#define require_running_or_return(BUF) \
+ if (!target_running ()) \
+ { \
+ write_enn (BUF); \
+ return; \
+ }
+
+#define require_running_or_break(BUF) \
+ if (!target_running ()) \
+ { \
+ write_enn (BUF); \
+ break; \
+ }
+
/* The environment to pass to the inferior when creating it. */
static gdb_environ our_environ;
@@ -631,6 +647,67 @@ handle_general_set (char *own_buf)
return;
}
+ if (strcmp (own_buf, "QEnvironmentReset") == 0)
+ {
+ our_environ = gdb_environ::from_host_environ ();
+
+ write_ok (own_buf);
+ return;
+ }
+
+ if (startswith (own_buf, "QEnvironmentHexEncoded:"))
+ {
+ const char *p = own_buf + sizeof ("QEnvironmentHexEncoded:") - 1;
+ /* The final form of the environment variable. FINAL_VAR will
+ hold the 'VAR=VALUE' format. */
+ std::string final_var = hex2str (p);
+ std::string var_name, var_value;
+
+ if (remote_debug)
+ {
+ debug_printf (_("[QEnvironmentHexEncoded received '%s']\n"), p);
+ debug_printf (_("[Environment variable to be set: '%s']\n"),
+ final_var.c_str ());
+ debug_flush ();
+ }
+
+ size_t pos = final_var.find ('=');
+ if (pos == std::string::npos)
+ {
+ warning (_("Unexpected format for environment variable: '%s'"),
+ final_var.c_str ());
+ write_enn (own_buf);
+ return;
+ }
+
+ var_name = final_var.substr (0, pos);
+ var_value = final_var.substr (pos + 1, std::string::npos);
+
+ our_environ.set (var_name.c_str (), var_value.c_str ());
+
+ write_ok (own_buf);
+ return;
+ }
+
+ if (startswith (own_buf, "QEnvironmentUnset:"))
+ {
+ const char *p = own_buf + sizeof ("QEnvironmentUnset:") - 1;
+ std::string varname = hex2str (p);
+
+ if (remote_debug)
+ {
+ debug_printf (_("[QEnvironmentUnset received '%s']\n"), p);
+ debug_printf (_("[Environment variable to be unset: '%s']\n"),
+ varname.c_str ());
+ debug_flush ();
+ }
+
+ our_environ.unset (varname.c_str ());
+
+ write_ok (own_buf);
+ return;
+ }
+
if (strcmp (own_buf, "QStartNoAckMode") == 0)
{
if (remote_debug)
@@ -810,12 +887,14 @@ get_features_xml (const char *annex)
This variable is set up from the auto-generated
init_registers_... routine for the current target. */
- if (desc->xmltarget != NULL && strcmp (annex, "target.xml") == 0)
+ if (strcmp (annex, "target.xml") == 0)
{
- if (*desc->xmltarget == '@')
- return desc->xmltarget + 1;
+ const char *ret = tdesc_get_features_xml ((target_desc*) desc);
+
+ if (*ret == '@')
+ return ret + 1;
else
- annex = desc->xmltarget;
+ annex = ret;
}
#ifdef USE_XML
@@ -890,7 +969,7 @@ gdb_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
res = prepare_to_access_memory ();
if (res == 0)
{
- if (set_desired_thread (1))
+ if (set_desired_thread ())
res = read_inferior_memory (memaddr, myaddr, len);
else
res = 1;
@@ -917,7 +996,7 @@ gdb_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
ret = prepare_to_access_memory ();
if (ret == 0)
{
- if (set_desired_thread (1))
+ if (set_desired_thread ())
ret = write_inferior_memory (memaddr, myaddr, len);
else
ret = EIO;
@@ -1078,12 +1157,99 @@ handle_search_memory (char *own_buf, int packet_len)
free (pattern);
}
-#define require_running(BUF) \
- if (!target_running ()) \
- { \
- write_enn (BUF); \
- return; \
+/* Handle the "D" packet. */
+
+static void
+handle_detach (char *own_buf)
+{
+ require_running_or_return (own_buf);
+
+ int pid;
+
+ if (multi_process)
+ {
+ /* skip 'D;' */
+ pid = strtol (&own_buf[2], NULL, 16);
}
+ else
+ pid = ptid_get_pid (current_ptid);
+
+ if ((tracing && disconnected_tracing) || any_persistent_commands ())
+ {
+ struct process_info *process = find_process_pid (pid);
+
+ if (process == NULL)
+ {
+ write_enn (own_buf);
+ return;
+ }
+
+ if (tracing && disconnected_tracing)
+ fprintf (stderr,
+ "Disconnected tracing in effect, "
+ "leaving gdbserver attached to the process\n");
+
+ if (any_persistent_commands ())
+ fprintf (stderr,
+ "Persistent commands are present, "
+ "leaving gdbserver attached to the process\n");
+
+ /* Make sure we're in non-stop/async mode, so we we can both
+ wait for an async socket accept, and handle async target
+ events simultaneously. There's also no point either in
+ having the target stop all threads, when we're going to
+ pass signals down without informing GDB. */
+ if (!non_stop)
+ {
+ if (debug_threads)
+ debug_printf ("Forcing non-stop mode\n");
+
+ non_stop = 1;
+ start_non_stop (1);
+ }
+
+ process->gdb_detached = 1;
+
+ /* Detaching implicitly resumes all threads. */
+ target_continue_no_signal (minus_one_ptid);
+
+ write_ok (own_buf);
+ return;
+ }
+
+ fprintf (stderr, "Detaching from process %d\n", pid);
+ stop_tracing ();
+ if (detach_inferior (pid) != 0)
+ write_enn (own_buf);
+ else
+ {
+ discard_queued_stop_replies (pid_to_ptid (pid));
+ write_ok (own_buf);
+
+ if (extended_protocol || target_running ())
+ {
+ /* 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);
+
+ current_thread = NULL;
+ }
+ else
+ {
+ putpkt (own_buf);
+ remote_close ();
+
+ /* If we are attached, then we can exit. Otherwise, we
+ need to hang around doing nothing, until the child is
+ gone. */
+ join_inferior (pid);
+ exit (0);
+ }
+ }
+}
/* Parse options to --debug-format= and "monitor set debug-format".
ARG is the text after "--debug-format=" or "monitor set debug-format".
@@ -1343,45 +1509,18 @@ handle_qxfer_features (const char *annex,
}
/* Worker routine for handle_qxfer_libraries.
- Add to the length pointed to by ARG a conservative estimate of the
- length needed to transmit the file name of INF. */
-
-static void
-accumulate_file_name_length (struct inferior_list_entry *inf, void *arg)
-{
- struct dll_info *dll = (struct dll_info *) inf;
- unsigned int *total_len = (unsigned int *) arg;
-
- /* Over-estimate the necessary memory. Assume that every character
- in the library name must be escaped. */
- *total_len += 128 + 6 * strlen (dll->name);
-}
-
-/* Worker routine for handle_qxfer_libraries.
Emit the XML to describe the library in INF. */
static void
emit_dll_description (struct inferior_list_entry *inf, void *arg)
{
struct dll_info *dll = (struct dll_info *) inf;
- char **p_ptr = (char **) arg;
- char *p = *p_ptr;
- char *name;
-
- strcpy (p, " <library name=\"");
- p = p + strlen (p);
- name = xml_escape_text (dll->name);
- strcpy (p, name);
- free (name);
- p = p + strlen (p);
- strcpy (p, "\"><segment address=\"");
- p = p + strlen (p);
- sprintf (p, "0x%lx", (long) dll->base_addr);
- p = p + strlen (p);
- strcpy (p, "\"/></library>\n");
- p = p + strlen (p);
-
- *p_ptr = p;
+ std::string *document = (std::string *) arg;
+ std::string name = xml_escape_text (dll->name);
+
+ *document += string_printf
+ (" <library name=\"%s\"><segment address=\"0x%lx\"/></library>\n",
+ name.c_str (), (long) dll->base_addr);
}
/* Handle qXfer:libraries:read. */
@@ -1391,43 +1530,26 @@ handle_qxfer_libraries (const char *annex,
gdb_byte *readbuf, const gdb_byte *writebuf,
ULONGEST offset, LONGEST len)
{
- unsigned int total_len;
- char *document, *p;
-
if (writebuf != NULL)
return -2;
if (annex[0] != '\0' || current_thread == NULL)
return -1;
- total_len = 64;
- for_each_inferior_with_data (&all_dlls, accumulate_file_name_length,
- &total_len);
+ std::string document = "<library-list version=\"1.0\">\n";
- document = (char *) malloc (total_len);
- if (document == NULL)
- return -1;
+ for_each_inferior_with_data (&all_dlls, emit_dll_description, &document);
- strcpy (document, "<library-list version=\"1.0\">\n");
- p = document + strlen (document);
+ document += "</library-list>\n";
- for_each_inferior_with_data (&all_dlls, emit_dll_description, &p);
-
- strcpy (p, "</library-list>\n");
-
- total_len = strlen (document);
+ if (offset > document.length ())
+ return -1;
- if (offset > total_len)
- {
- free (document);
- return -1;
- }
+ if (offset + len > document.length ())
+ len = document.length () - offset;
- if (offset + len > total_len)
- len = total_len - offset;
+ memcpy (readbuf, &document[offset], len);
- memcpy (readbuf, document + offset, len);
- free (document);
return len;
}
@@ -1521,11 +1643,14 @@ handle_qxfer_threads_worker (struct inferior_list_entry *inf, void *arg)
{
struct thread_info *thread = (struct thread_info *) inf;
struct buffer *buffer = (struct buffer *) arg;
- ptid_t ptid = thread_to_gdb_id (thread);
+ ptid_t ptid = ptid_of (thread);
char ptid_s[100];
int core = target_core_of_thread (ptid);
char core_s[21];
const char *name = target_thread_name (ptid);
+ int handle_len;
+ gdb_byte *handle;
+ bool handle_status = target_thread_handle (ptid, &handle, &handle_len);
write_ptid (ptid_s, ptid);
@@ -1540,6 +1665,13 @@ handle_qxfer_threads_worker (struct inferior_list_entry *inf, void *arg)
if (name != NULL)
buffer_xml_printf (buffer, " name=\"%s\"", name);
+ if (handle_status)
+ {
+ char *handle_s = (char *) alloca (handle_len * 2 + 1);
+ bin2hex (handle, handle_s, handle_len);
+ buffer_xml_printf (buffer, " handle=\"%s\"", handle_s);
+ }
+
buffer_xml_printf (buffer, "/>\n");
}
@@ -2005,21 +2137,20 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
/* Reply the current thread id. */
if (strcmp ("qC", own_buf) == 0 && !disable_packet_qC)
{
- ptid_t gdb_id;
- require_running (own_buf);
+ ptid_t ptid;
+ require_running_or_return (own_buf);
- if (!ptid_equal (general_thread, null_ptid)
- && !ptid_equal (general_thread, minus_one_ptid))
- gdb_id = general_thread;
+ if (general_thread != null_ptid && general_thread != minus_one_ptid)
+ ptid = general_thread;
else
{
thread_ptr = get_first_inferior (&all_threads);
- gdb_id = thread_to_gdb_id ((struct thread_info *)thread_ptr);
+ ptid = thread_ptr->id;
}
sprintf (own_buf, "QC");
own_buf += 2;
- write_ptid (own_buf, gdb_id);
+ write_ptid (own_buf, ptid);
return;
}
@@ -2075,28 +2206,22 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
{
if (strcmp ("qfThreadInfo", own_buf) == 0)
{
- ptid_t gdb_id;
-
- require_running (own_buf);
+ require_running_or_return (own_buf);
thread_ptr = get_first_inferior (&all_threads);
*own_buf++ = 'm';
- gdb_id = thread_to_gdb_id ((struct thread_info *)thread_ptr);
- write_ptid (own_buf, gdb_id);
+ write_ptid (own_buf, thread_ptr->id);
thread_ptr = thread_ptr->next;
return;
}
if (strcmp ("qsThreadInfo", own_buf) == 0)
{
- ptid_t gdb_id;
-
- require_running (own_buf);
+ require_running_or_return (own_buf);
if (thread_ptr != NULL)
{
*own_buf++ = 'm';
- gdb_id = thread_to_gdb_id ((struct thread_info *)thread_ptr);
- write_ptid (own_buf, gdb_id);
+ write_ptid (own_buf, thread_ptr->id);
thread_ptr = thread_ptr->next;
return;
}
@@ -2113,7 +2238,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
{
CORE_ADDR text, data;
- require_running (own_buf);
+ require_running_or_return (own_buf);
if (the_target->read_offsets (&text, &data))
sprintf (own_buf, "Text=%lX;Data=%lX;Bss=%lX",
(long)text, (long)data, (long)data);
@@ -2228,7 +2353,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
}
sprintf (own_buf,
- "PacketSize=%x;QPassSignals+;QProgramSignals+;QStartupWithShell+",
+ "PacketSize=%x;QPassSignals+;QProgramSignals+;"
+ "QStartupWithShell+;QEnvironmentHexEncoded+;"
+ "QEnvironmentReset+;QEnvironmentUnset+",
PBUFSIZ - 1);
if (target_supports_catch_syscall ())
@@ -2348,7 +2475,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
int i, err;
ptid_t ptid = null_ptid;
- require_running (own_buf);
+ require_running_or_return (own_buf);
for (i = 0; i < 3; i++)
{
@@ -2461,7 +2588,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
if (startswith (own_buf, "qSearch:memory:"))
{
- require_running (own_buf);
+ require_running_or_return (own_buf);
handle_search_memory (own_buf, packet_len);
return;
}
@@ -2479,7 +2606,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
}
else
{
- require_running (own_buf);
+ require_running_or_return (own_buf);
process = current_process ();
}
@@ -2501,7 +2628,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
int len;
unsigned long long crc;
- require_running (own_buf);
+ require_running_or_return (own_buf);
comma = unpack_varlen_hex (own_buf + 5, &base);
if (*comma++ != ',')
{
@@ -3116,14 +3243,12 @@ queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg)
{
if (debug_threads)
{
- char *status_string
+ std::string status_string
= target_waitstatus_to_string (&thread->last_status);
debug_printf ("Reporting thread %s as already stopped with %s\n",
target_pid_to_str (entry->id),
- status_string);
-
- xfree (status_string);
+ status_string.c_str ());
}
gdb_assert (thread->last_status.kind != TARGET_WAITKIND_IGNORE);
@@ -3283,7 +3408,7 @@ handle_status (char *own_buf)
/* GDB assumes the current thread is the thread we're
reporting the status for. */
general_thread = thread->id;
- set_desired_thread (1);
+ set_desired_thread ();
gdb_assert (tp->last_status.kind != TARGET_WAITKIND_IGNORE);
prepare_resume_reply (own_buf, tp->entry.id, &tp->last_status);
@@ -3376,26 +3501,6 @@ gdbserver_show_disableable (FILE *stream)
" threads \tAll of the above\n");
}
-
-#undef require_running
-#define require_running(BUF) \
- if (!target_running ()) \
- { \
- write_enn (BUF); \
- break; \
- }
-
-static int
-first_thread_of (struct inferior_list_entry *entry, void *args)
-{
- int pid = * (int *) args;
-
- if (ptid_get_pid (entry->id) == pid)
- return 1;
-
- return 0;
-}
-
static void
kill_inferior_callback (struct inferior_list_entry *entry)
{
@@ -3521,6 +3626,8 @@ captured_main (int argc, char *argv[])
volatile int multi_mode = 0;
volatile int attach = 0;
int was_running;
+ bool selftest = false;
+ const char *selftest_filter = NULL;
while (*next_arg != NULL && **next_arg == '-')
{
@@ -3639,6 +3746,13 @@ captured_main (int argc, char *argv[])
startup_with_shell = false;
else if (strcmp (*next_arg, "--once") == 0)
run_once = 1;
+ else if (strcmp (*next_arg, "--selftest") == 0)
+ selftest = true;
+ else if (startswith (*next_arg, "--selftest="))
+ {
+ selftest = true;
+ selftest_filter = *next_arg + strlen ("--selftest=");
+ }
else
{
fprintf (stderr, "Unknown argument: %s\n", *next_arg);
@@ -3654,7 +3768,8 @@ captured_main (int argc, char *argv[])
port = *next_arg;
next_arg++;
}
- if (port == NULL || (!attach && !multi_mode && *next_arg == NULL))
+ if ((port == NULL || (!attach && !multi_mode && *next_arg == NULL))
+ && !selftest)
{
gdbserver_usage (stderr);
exit (1);
@@ -3670,7 +3785,8 @@ captured_main (int argc, char *argv[])
starting the inferior. Inferiors created in this scenario have
stdin,stdout redirected. So do this here before we call
start_inferior. */
- remote_prepare (port);
+ if (port != NULL)
+ remote_prepare (port);
bad_attach = 0;
pid = 0;
@@ -3711,6 +3827,12 @@ captured_main (int argc, char *argv[])
own_buf = (char *) xmalloc (PBUFSIZ + 1);
mem_buf = (unsigned char *) xmalloc (PBUFSIZ);
+ if (selftest)
+ {
+ selftests::run_tests (selftest_filter);
+ throw_quit ("Quit");
+ }
+
if (pid == 0 && *next_arg != NULL)
{
int i, n;
@@ -3940,13 +4062,10 @@ process_point_options (struct gdb_breakpoint *bp, char **packet)
static int
process_serial_event (void)
{
- char ch;
- int i = 0;
int signal;
unsigned int len;
int res;
CORE_ADDR mem_addr;
- int pid;
unsigned char sig;
int packet_len;
int new_packet_len = -1;
@@ -3963,8 +4082,7 @@ process_serial_event (void)
}
response_needed = 1;
- i = 0;
- ch = own_buf[i++];
+ char ch = own_buf[0];
switch (ch)
{
case 'q':
@@ -3974,91 +4092,7 @@ process_serial_event (void)
handle_general_set (own_buf);
break;
case 'D':
- require_running (own_buf);
-
- if (multi_process)
- {
- i++; /* skip ';' */
- pid = strtol (&own_buf[i], NULL, 16);
- }
- else
- pid = ptid_get_pid (current_ptid);
-
- if ((tracing && disconnected_tracing) || any_persistent_commands ())
- {
- struct process_info *process = find_process_pid (pid);
-
- if (process == NULL)
- {
- write_enn (own_buf);
- break;
- }
-
- if (tracing && disconnected_tracing)
- fprintf (stderr,
- "Disconnected tracing in effect, "
- "leaving gdbserver attached to the process\n");
-
- if (any_persistent_commands ())
- fprintf (stderr,
- "Persistent commands are present, "
- "leaving gdbserver attached to the process\n");
-
- /* Make sure we're in non-stop/async mode, so we we can both
- wait for an async socket accept, and handle async target
- events simultaneously. There's also no point either in
- having the target stop all threads, when we're going to
- pass signals down without informing GDB. */
- if (!non_stop)
- {
- if (debug_threads)
- debug_printf ("Forcing non-stop mode\n");
-
- non_stop = 1;
- start_non_stop (1);
- }
-
- process->gdb_detached = 1;
-
- /* Detaching implicitly resumes all threads. */
- target_continue_no_signal (minus_one_ptid);
-
- write_ok (own_buf);
- break; /* from switch/case */
- }
-
- fprintf (stderr, "Detaching from process %d\n", pid);
- stop_tracing ();
- if (detach_inferior (pid) != 0)
- write_enn (own_buf);
- else
- {
- discard_queued_stop_replies (pid_to_ptid (pid));
- write_ok (own_buf);
-
- if (extended_protocol || target_running ())
- {
- /* 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);
-
- current_thread = NULL;
- }
- else
- {
- putpkt (own_buf);
- remote_close ();
-
- /* If we are attached, then we can exit. Otherwise, we
- need to hang around doing nothing, until the child is
- gone. */
- join_inferior (pid);
- exit (0);
- }
- }
+ handle_detach (own_buf);
break;
case '!':
extended_protocol = 1;
@@ -4070,27 +4104,18 @@ process_serial_event (void)
case 'H':
if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's')
{
- ptid_t gdb_id, thread_id;
- int pid;
-
- require_running (own_buf);
+ require_running_or_break (own_buf);
- gdb_id = read_ptid (&own_buf[2], NULL);
+ ptid_t thread_id = read_ptid (&own_buf[2], NULL);
- pid = ptid_get_pid (gdb_id);
-
- if (ptid_equal (gdb_id, null_ptid)
- || ptid_equal (gdb_id, minus_one_ptid))
+ if (thread_id == null_ptid || thread_id == minus_one_ptid)
thread_id = null_ptid;
- else if (pid != 0
- && ptid_equal (pid_to_ptid (pid),
- gdb_id))
+ else if (thread_id.is_pid ())
{
- struct thread_info *thread =
- (struct thread_info *) find_inferior (&all_threads,
- first_thread_of,
- &pid);
- if (!thread)
+ /* The ptid represents a pid. */
+ thread_info *thread = find_any_thread_of_pid (thread_id.pid ());
+
+ if (thread == NULL)
{
write_enn (own_buf);
break;
@@ -4100,8 +4125,8 @@ process_serial_event (void)
}
else
{
- thread_id = gdb_id_to_thread_id (gdb_id);
- if (ptid_equal (thread_id, null_ptid))
+ /* The ptid represents a lwp/tid. */
+ if (find_thread_ptid (thread_id) == NULL)
{
write_enn (own_buf);
break;
@@ -4124,7 +4149,7 @@ process_serial_event (void)
}
general_thread = thread_id;
- set_desired_thread (1);
+ set_desired_thread ();
gdb_assert (current_thread != NULL);
}
else if (own_buf[1] == 'c')
@@ -4140,7 +4165,7 @@ process_serial_event (void)
}
break;
case 'g':
- require_running (own_buf);
+ require_running_or_break (own_buf);
if (current_traceframe >= 0)
{
struct regcache *regcache
@@ -4157,7 +4182,7 @@ process_serial_event (void)
{
struct regcache *regcache;
- if (!set_desired_thread (1))
+ if (!set_desired_thread ())
write_enn (own_buf);
else
{
@@ -4167,14 +4192,14 @@ process_serial_event (void)
}
break;
case 'G':
- require_running (own_buf);
+ require_running_or_break (own_buf);
if (current_traceframe >= 0)
write_enn (own_buf);
else
{
struct regcache *regcache;
- if (!set_desired_thread (1))
+ if (!set_desired_thread ())
write_enn (own_buf);
else
{
@@ -4185,7 +4210,7 @@ process_serial_event (void)
}
break;
case 'm':
- require_running (own_buf);
+ 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)
@@ -4194,7 +4219,7 @@ process_serial_event (void)
bin2hex (mem_buf, own_buf, res);
break;
case 'M':
- require_running (own_buf);
+ require_running_or_break (own_buf);
decode_M_packet (&own_buf[1], &mem_addr, &len, &mem_buf);
if (gdb_write_memory (mem_addr, mem_buf, len) == 0)
write_ok (own_buf);
@@ -4202,7 +4227,7 @@ process_serial_event (void)
write_enn (own_buf);
break;
case 'X':
- require_running (own_buf);
+ require_running_or_break (own_buf);
if (decode_X_packet (&own_buf[1], packet_len - 1,
&mem_addr, &len, &mem_buf) < 0
|| gdb_write_memory (mem_addr, mem_buf, len) != 0)
@@ -4211,7 +4236,7 @@ process_serial_event (void)
write_ok (own_buf);
break;
case 'C':
- require_running (own_buf);
+ require_running_or_break (own_buf);
hex2bin (own_buf + 1, &sig, 1);
if (gdb_signal_to_host_p ((enum gdb_signal) sig))
signal = gdb_signal_to_host ((enum gdb_signal) sig);
@@ -4220,7 +4245,7 @@ process_serial_event (void)
myresume (own_buf, 0, signal);
break;
case 'S':
- require_running (own_buf);
+ require_running_or_break (own_buf);
hex2bin (own_buf + 1, &sig, 1);
if (gdb_signal_to_host_p ((enum gdb_signal) sig))
signal = gdb_signal_to_host ((enum gdb_signal) sig);
@@ -4229,12 +4254,12 @@ process_serial_event (void)
myresume (own_buf, 1, signal);
break;
case 'c':
- require_running (own_buf);
+ require_running_or_break (own_buf);
signal = 0;
myresume (own_buf, 0, signal);
break;
case 's':
- require_running (own_buf);
+ require_running_or_break (own_buf);
signal = 0;
myresume (own_buf, 1, signal);
break;
@@ -4306,13 +4331,10 @@ process_serial_event (void)
case 'T':
{
- ptid_t gdb_id, thread_id;
+ require_running_or_break (own_buf);
- require_running (own_buf);
-
- gdb_id = read_ptid (&own_buf[1], NULL);
- thread_id = gdb_id_to_thread_id (gdb_id);
- if (ptid_equal (thread_id, null_ptid))
+ ptid_t thread_id = read_ptid (&own_buf[1], NULL);
+ if (find_thread_ptid (thread_id) == NULL)
{
write_enn (own_buf);
break;
@@ -4408,7 +4430,7 @@ handle_serial_event (int err, gdb_client_data client_data)
/* Be sure to not change the selected thread behind GDB's back.
Important in the non-stop mode asynchronous protocol. */
- set_desired_thread (1);
+ set_desired_thread ();
return 0;
}
@@ -4503,7 +4525,18 @@ handle_target_event (int err, gdb_client_data client_data)
/* Be sure to not change the selected thread behind GDB's back.
Important in the non-stop mode asynchronous protocol. */
- set_desired_thread (1);
+ set_desired_thread ();
return 0;
}
+
+#if GDB_SELF_TEST
+namespace selftests
+{
+
+void
+reset ()
+{}
+
+} // namespace selftests
+#endif /* GDB_SELF_TEST */