daily update
[deliverable/binutils-gdb.git] / gdb / remote.c
index 528f37435f5d3400068802b0f63c68d73ec1d49b..a6a6227c614f8d20365f271ab5b00ddb2a3d3d14 100644 (file)
@@ -34,6 +34,7 @@
 #include "gdb-stabs.h"
 #include "gdbthread.h"
 #include "remote.h"
+#include "remote-notif.h"
 #include "regcache.h"
 #include "value.h"
 #include "gdb_assert.h"
@@ -89,7 +90,7 @@ static void cleanup_sigint_signal_handler (void *dummy);
 static void initialize_sigint_signal_handler (void);
 static int getpkt_sane (char **buf, long *sizeof_buf, int forever);
 static int getpkt_or_notif_sane (char **buf, long *sizeof_buf,
-                                int forever);
+                                int forever, int *is_notif);
 
 static void handle_remote_sigint (int);
 static void handle_remote_sigint_twice (int);
@@ -223,17 +224,13 @@ static void remote_check_symbols (struct objfile *objfile);
 void _initialize_remote (void);
 
 struct stop_reply;
-static struct stop_reply *stop_reply_xmalloc (void);
 static void stop_reply_xfree (struct stop_reply *);
-static void do_stop_reply_xfree (void *arg);
-static void remote_parse_stop_reply (char *buf, struct stop_reply *);
+static void remote_parse_stop_reply (char *, struct stop_reply *);
 static void push_stop_reply (struct stop_reply *);
-static void remote_get_pending_stop_replies (void);
-static void discard_pending_stop_replies (int pid);
+static void discard_pending_stop_replies (struct inferior *);
 static int peek_stop_reply (ptid_t ptid);
 
 static void remote_async_inferior_event_handler (gdb_client_data);
-static void remote_async_get_pending_events_handler (gdb_client_data);
 
 static void remote_terminal_ours (void);
 
@@ -245,11 +242,6 @@ static int remote_supports_cond_breakpoints (void);
 
 static int remote_can_run_breakpoint_commands (void);
 
-/* The non-stop remote protocol provisions for one pending stop reply.
-   This is where we keep it until it is acknowledged.  */
-
-static struct stop_reply *pending_stop_reply = NULL;
-
 /* For "remote".  */
 
 static struct cmd_list_element *remote_cmdlist;
@@ -397,9 +389,9 @@ struct packet_reg
   long regnum; /* GDB's internal register number.  */
   LONGEST pnum; /* Remote protocol register number.  */
   int in_g_packet; /* Always part of G packet.  */
-  /* long size in bytes;  == register_size (target_gdbarch, regnum);
+  /* long size in bytes;  == register_size (target_gdbarch (), regnum);
      at present.  */
-  /* char *name; == gdbarch_register_name (target_gdbarch, regnum);
+  /* char *name; == gdbarch_register_name (target_gdbarch (), regnum);
      at present.  */
 };
 
@@ -484,7 +476,7 @@ remote_get_noisy_reply (char **buf_p,
 
          TRY_CATCH (ex, RETURN_MASK_ALL)
            {
-             gdbarch_relocate_instruction (target_gdbarch, &to, from);
+             gdbarch_relocate_instruction (target_gdbarch (), &to, from);
            }
          if (ex.reason >= 0)
            {
@@ -525,7 +517,7 @@ static struct gdbarch_data *remote_gdbarch_data_handle;
 static struct remote_arch_state *
 get_remote_arch_state (void)
 {
-  return gdbarch_data (target_gdbarch, remote_gdbarch_data_handle);
+  return gdbarch_data (target_gdbarch (), remote_gdbarch_data_handle);
 }
 
 /* Fetch the global remote target state.  */
@@ -698,7 +690,7 @@ get_remote_packet_size (void)
 static struct packet_reg *
 packet_reg_from_regnum (struct remote_arch_state *rsa, long regnum)
 {
-  if (regnum < 0 && regnum >= gdbarch_num_regs (target_gdbarch))
+  if (regnum < 0 && regnum >= gdbarch_num_regs (target_gdbarch ()))
     return NULL;
   else
     {
@@ -714,7 +706,7 @@ packet_reg_from_pnum (struct remote_arch_state *rsa, LONGEST pnum)
 {
   int i;
 
-  for (i = 0; i < gdbarch_num_regs (target_gdbarch); i++)
+  for (i = 0; i < gdbarch_num_regs (target_gdbarch ()); i++)
     {
       struct packet_reg *r = &rsa->regs[i];
 
@@ -1402,12 +1394,6 @@ static struct async_signal_handler *sigint_remote_token;
 
 static struct async_event_handler *remote_async_inferior_event_token;
 
-/* Asynchronous signal handle registered as event loop source for when
-   the remote sent us a %Stop notification.  The registered callback
-   will do a vStopped sequence to pull the rest of the events out of
-   the remote side into our event queue.  */
-
-static struct async_event_handler *remote_async_get_pending_events_token;
 \f
 
 static ptid_t magic_null_ptid;
@@ -1481,7 +1467,7 @@ remote_add_inferior (int fake_pid_p, int pid, int attached)
   if (attached == -1)
     attached = remote_query_attached (pid);
 
-  if (gdbarch_has_global_solist (target_gdbarch))
+  if (gdbarch_has_global_solist (target_gdbarch ()))
     {
       /* If the target shares code across all inferiors, then every
         attach adds a new inferior.  */
@@ -3022,13 +3008,16 @@ remote_close (int quitting)
   inferior_ptid = null_ptid;
   discard_all_inferiors ();
 
-  /* We're no longer interested in any of these events.  */
-  discard_pending_stop_replies (-1);
+  /* Stop replies may from inferiors which are still unknown to GDB.
+     We are closing the remote target, so we should discard
+     everything, including the stop replies from GDB-unknown
+     inferiors.  */
+  discard_pending_stop_replies (NULL);
 
   if (remote_async_inferior_event_token)
     delete_async_event_handler (&remote_async_inferior_event_token);
-  if (remote_async_get_pending_events_token)
-    delete_async_event_handler (&remote_async_get_pending_events_token);
+
+  remote_notif_unregister_async_event_handler ();
 }
 
 /* Query the remote side for the text, data and bss offsets.  */
@@ -3338,7 +3327,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
 
   /* On OSs where the list of libraries is global to all
      processes, we fetch them early.  */
-  if (gdbarch_has_global_solist (target_gdbarch))
+  if (gdbarch_has_global_solist (target_gdbarch ()))
     solib_add (NULL, from_tty, target, auto_solib_add);
 
   if (non_stop)
@@ -3362,7 +3351,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
   else if (rs->non_stop_aware)
     {
       /* Don't assume that the stub can operate in all-stop mode.
-        Request it explicitely.  */
+        Request it explicitly.  */
       putpkt ("QNonStop:0");
       getpkt (&rs->buf, &rs->buf_size, 0);
 
@@ -3420,7 +3409,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
         supported for non-stop; it could be, but it is tricky if
         there are no stopped threads when we connect.  */
       if (remote_read_description_p (target)
-         && gdbarch_target_desc (target_gdbarch) == NULL)
+         && gdbarch_target_desc (target_gdbarch ()) == NULL)
        {
          target_clear_description ();
          target_find_description ();
@@ -3450,19 +3439,13 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
         mechanism.  */
       if (strcmp (rs->buf, "OK") != 0)
        {
-         struct stop_reply *stop_reply;
-         struct cleanup *old_chain;
-
-         stop_reply = stop_reply_xmalloc ();
-         old_chain = make_cleanup (do_stop_reply_xfree, stop_reply);
+         struct notif_client *notif = &notif_client_stop;
 
-         remote_parse_stop_reply (rs->buf, stop_reply);
-         discard_cleanups (old_chain);
-
-         /* get_pending_stop_replies acks this one, and gets the rest
-            out.  */
-         pending_stop_reply = stop_reply;
-         remote_get_pending_stop_replies ();
+         /* remote_notif_get_pending_replies acks this one, and gets
+            the rest out.  */
+         notif_client_stop.pending_event
+           = remote_notif_parse (notif, rs->buf);
+         remote_notif_get_pending_events (notif);
 
          /* Make sure that threads that were stopped remain
             stopped.  */
@@ -3539,7 +3522,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
   rs->starting_up = 0;
 
   /* If breakpoints are global, insert them now.  */
-  if (gdbarch_has_global_breakpoints (target_gdbarch)
+  if (gdbarch_has_global_breakpoints (target_gdbarch ())
       && breakpoints_always_inserted_mode ())
     insert_breakpoints ();
 }
@@ -3619,12 +3602,12 @@ remote_check_symbols (struct objfile *objfile)
        xsnprintf (msg, get_remote_packet_size (), "qSymbol::%s", &reply[8]);
       else
        {
-         int addr_size = gdbarch_addr_bit (target_gdbarch) / 8;
+         int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
          CORE_ADDR sym_addr = SYMBOL_VALUE_ADDRESS (sym);
 
          /* If this is a function address, return the start of code
             instead of any data function descriptor.  */
-         sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch,
+         sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
                                                         sym_addr,
                                                         &current_target);
 
@@ -4222,9 +4205,7 @@ remote_open_1 (char *name, int from_tty,
   remote_async_inferior_event_token
     = create_async_event_handler (remote_async_inferior_event_handler,
                                  NULL);
-  remote_async_get_pending_events_token
-    = create_async_event_handler (remote_async_get_pending_events_handler,
-                                 NULL);
+  remote_notif_register_async_event_handler ();
 
   /* Reset the target state; these things will be queried either by
      remote_query_supported or as they are needed.  */
@@ -4351,7 +4332,6 @@ remote_detach_1 (char *args, int from_tty, int extended)
   if (from_tty && !extended)
     puts_filtered (_("Ending remote debugging.\n"));
 
-  discard_pending_stop_replies (pid);
   target_mourn_inferior ();
 }
 
@@ -4480,14 +4460,10 @@ extended_remote_attach_1 (struct target_ops *target, char *args, int from_tty)
 
       if (target_can_async_p ())
        {
-         struct stop_reply *stop_reply;
-         struct cleanup *old_chain;
+         struct notif_event *reply
+           =  remote_notif_parse (&notif_client_stop, wait_status);
 
-         stop_reply = stop_reply_xmalloc ();
-         old_chain = make_cleanup (do_stop_reply_xfree, stop_reply);
-         remote_parse_stop_reply (wait_status, stop_reply);
-         discard_cleanups (old_chain);
-         push_stop_reply (stop_reply);
+         push_stop_reply ((struct stop_reply *) reply);
 
          target_async (inferior_event_handler, 0);
        }
@@ -4781,6 +4757,15 @@ remote_resume (struct target_ops *ops,
   struct remote_state *rs = get_remote_state ();
   char *buf;
 
+  /* In all-stop, we can't mark REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN
+     (explained in remote-notif.c:handle_notification) so
+     remote_notif_process is not called.  We need find a place where
+     it is safe to start a 'vNotif' sequence.  It is good to do it
+     before resuming inferior, because inferior was stopped and no RSP
+     traffic at that moment.  */
+  if (!non_stop)
+    remote_notif_process (&notif_client_stop);
+
   last_sent_signal = siggnal;
   last_sent_step = step;
 
@@ -4862,7 +4847,7 @@ static void
 handle_remote_sigint (int sig)
 {
   signal (sig, handle_remote_sigint_twice);
-  mark_async_signal_handler_wrapper (sigint_remote_token);
+  mark_async_signal_handler (sigint_remote_token);
 }
 
 /* Signal handler for SIGINT, installed after SIGINT has already been
@@ -4872,7 +4857,7 @@ static void
 handle_remote_sigint_twice (int sig)
 {
   signal (sig, handle_remote_sigint);
-  mark_async_signal_handler_wrapper (sigint_remote_twice_token);
+  mark_async_signal_handler (sigint_remote_twice_token);
 }
 
 /* Perform the real interruption of the target execution, in response
@@ -5114,10 +5099,11 @@ typedef struct cached_reg
 
 DEF_VEC_O(cached_reg_t);
 
-struct stop_reply
+typedef struct stop_reply
 {
-  struct stop_reply *next;
+  struct notif_event base;
 
+  /* The identifier of the thread about this event  */
   ptid_t ptid;
 
   struct target_waitstatus ws;
@@ -5135,19 +5121,18 @@ struct stop_reply
   int replay_event;
 
   int core;
-};
-
-/* The list of already fetched and acknowledged stop events.  */
-static struct stop_reply *stop_reply_queue;
-
-static struct stop_reply *
-stop_reply_xmalloc (void)
-{
-  struct stop_reply *r = XMALLOC (struct stop_reply);
+} *stop_reply_p;
 
-  r->next = NULL;
-  return r;
-}
+DECLARE_QUEUE_P (stop_reply_p);
+DEFINE_QUEUE_P (stop_reply_p);
+/* The list of already fetched and acknowledged stop events.  This
+   queue is used for notification Stop, and other notifications
+   don't need queue for their events, because the notification events
+   of Stop can't be consumed immediately, so that events should be
+   queued first, and be consumed by remote_wait_{ns,as} one per
+   time.  Other notifications can consume their events immediately,
+   so queue is not needed for them.  */
+static QUEUE (stop_reply_p) *stop_reply_queue;
 
 static void
 stop_reply_xfree (struct stop_reply *r)
@@ -5159,51 +5144,169 @@ stop_reply_xfree (struct stop_reply *r)
     }
 }
 
-/* Discard all pending stop replies of inferior PID.  If PID is -1,
+static void
+remote_notif_stop_parse (struct notif_client *self, char *buf,
+                        struct notif_event *event)
+{
+  remote_parse_stop_reply (buf, (struct stop_reply *) event);
+}
+
+static void
+remote_notif_stop_ack (struct notif_client *self, char *buf,
+                      struct notif_event *event)
+{
+  struct stop_reply *stop_reply = (struct stop_reply *) event;
+
+  /* acknowledge */
+  putpkt ((char *) self->ack_command);
+
+  if (stop_reply->ws.kind == TARGET_WAITKIND_IGNORE)
+      /* We got an unknown stop reply.  */
+      error (_("Unknown stop reply"));
+
+  push_stop_reply (stop_reply);
+}
+
+static int
+remote_notif_stop_can_get_pending_events (struct notif_client *self)
+{
+  /* We can't get pending events in remote_notif_process for
+     notification stop, and we have to do this in remote_wait_ns
+     instead.  If we fetch all queued events from stub, remote stub
+     may exit and we have no chance to process them back in
+     remote_wait_ns.  */
+  mark_async_event_handler (remote_async_inferior_event_token);
+  return 0;
+}
+
+static void
+stop_reply_dtr (struct notif_event *event)
+{
+  struct stop_reply *r = (struct stop_reply *) event;
+
+  VEC_free (cached_reg_t, r->regcache);
+}
+
+static struct notif_event *
+remote_notif_stop_alloc_reply (void)
+{
+  struct notif_event *r
+    = (struct notif_event *) XMALLOC (struct stop_reply);
+
+  r->dtr = stop_reply_dtr;
+
+  return r;
+}
+
+/* A client of notification Stop.  */
+
+struct notif_client notif_client_stop =
+{
+  "Stop",
+  "vStopped",
+  remote_notif_stop_parse,
+  remote_notif_stop_ack,
+  remote_notif_stop_can_get_pending_events,
+  remote_notif_stop_alloc_reply,
+  NULL,
+};
+
+/* A parameter to pass data in and out.  */
+
+struct queue_iter_param
+{
+  void *input;
+  struct stop_reply *output;
+};
+
+/* Remove all queue elements meet the condition it checks.  */
+
+static int
+remote_notif_remove_all (QUEUE (stop_reply_p) *q,
+                        QUEUE_ITER (stop_reply_p) *iter,
+                        stop_reply_p event,
+                        void *data)
+{
+  struct queue_iter_param *param = data;
+  struct inferior *inf = param->input;
+
+  if (inf == NULL || ptid_get_pid (event->ptid) == inf->pid)
+    {
+      stop_reply_xfree (event);
+      QUEUE_remove_elem (stop_reply_p, q, iter);
+    }
+
+  return 1;
+}
+
+/* Discard all pending stop replies of inferior INF.  If INF is NULL,
    discard everything.  */
 
 static void
-discard_pending_stop_replies (int pid)
+discard_pending_stop_replies (struct inferior *inf)
 {
-  struct stop_reply *prev = NULL, *reply, *next;
+  int i;
+  struct queue_iter_param param;
+  struct stop_reply *reply
+    = (struct stop_reply *) notif_client_stop.pending_event;
 
   /* Discard the in-flight notification.  */
-  if (pending_stop_reply != NULL
-      && (pid == -1
-         || ptid_get_pid (pending_stop_reply->ptid) == pid))
+  if (reply != NULL
+      && (inf == NULL
+         || ptid_get_pid (reply->ptid) == inf->pid))
     {
-      stop_reply_xfree (pending_stop_reply);
-      pending_stop_reply = NULL;
+      stop_reply_xfree (reply);
+      notif_client_stop.pending_event = NULL;
     }
 
+  param.input = inf;
+  param.output = NULL;
   /* Discard the stop replies we have already pulled with
      vStopped.  */
-  for (reply = stop_reply_queue; reply; reply = next)
-    {
-      next = reply->next;
-      if (pid == -1
-         || ptid_get_pid (reply->ptid) == pid)
-       {
-         if (reply == stop_reply_queue)
-           stop_reply_queue = reply->next;
-         else
-           prev->next = reply->next;
+  QUEUE_iterate (stop_reply_p, stop_reply_queue,
+                remote_notif_remove_all, &param);
+}
 
-         stop_reply_xfree (reply);
-       }
-      else
-       prev = reply;
+/* A parameter to pass data in and out.  */
+
+static int
+remote_notif_remove_once_on_match (QUEUE (stop_reply_p) *q,
+                                  QUEUE_ITER (stop_reply_p) *iter,
+                                  stop_reply_p event,
+                                  void *data)
+{
+  struct queue_iter_param *param = data;
+  ptid_t *ptid = param->input;
+
+  if (ptid_match (event->ptid, *ptid))
+    {
+      param->output = event;
+      QUEUE_remove_elem (stop_reply_p, q, iter);
+      return 0;
     }
+
+  return 1;
 }
 
-/* Cleanup wrapper.  */
+/* Remove the first reply in 'stop_reply_queue' which matches
+   PTID.  */
 
-static void
-do_stop_reply_xfree (void *arg)
+static struct stop_reply *
+remote_notif_remove_queued_reply (ptid_t ptid)
 {
-  struct stop_reply *r = arg;
+  struct queue_iter_param param;
+
+  param.input = &ptid;
+  param.output = NULL;
 
-  stop_reply_xfree (r);
+  QUEUE_iterate (stop_reply_p, stop_reply_queue,
+                remote_notif_remove_once_on_match, &param);
+  if (notif_debug)
+    fprintf_unfiltered (gdb_stdlog,
+                       "notif: discard queued event: 'Stop' in %s\n",
+                       target_pid_to_str (ptid));
+
+  return param.output;
 }
 
 /* Look for a queued stop reply belonging to PTID.  If one is found,
@@ -5214,29 +5317,13 @@ do_stop_reply_xfree (void *arg)
 static struct stop_reply *
 queued_stop_reply (ptid_t ptid)
 {
-  struct stop_reply *it;
-  struct stop_reply **it_link;
-
-  it = stop_reply_queue;
-  it_link = &stop_reply_queue;
-  while (it)
-    {
-      if (ptid_match (it->ptid, ptid))
-       {
-         *it_link = it->next;
-         it->next = NULL;
-         break;
-       }
+  struct stop_reply *r = remote_notif_remove_queued_reply (ptid);
 
-      it_link = &it->next;
-      it = *it_link;
-    }
-
-  if (stop_reply_queue)
+  if (!QUEUE_is_empty (stop_reply_p, stop_reply_queue))
     /* There's still at least an event left.  */
     mark_async_event_handler (remote_async_inferior_event_token);
 
-  return it;
+  return r;
 }
 
 /* Push a fully parsed stop reply in the stop reply queue.  Since we
@@ -5246,38 +5333,37 @@ queued_stop_reply (ptid_t ptid)
 static void
 push_stop_reply (struct stop_reply *new_event)
 {
-  struct stop_reply *event;
+  QUEUE_enque (stop_reply_p, stop_reply_queue, new_event);
 
-  if (stop_reply_queue)
-    {
-      for (event = stop_reply_queue;
-          event && event->next;
-          event = event->next)
-       ;
-
-      event->next = new_event;
-    }
-  else
-    stop_reply_queue = new_event;
+  if (notif_debug)
+    fprintf_unfiltered (gdb_stdlog,
+                       "notif: push 'Stop' %s to queue %d\n",
+                       target_pid_to_str (new_event->ptid),
+                       QUEUE_length (stop_reply_p,
+                                     stop_reply_queue));
 
   mark_async_event_handler (remote_async_inferior_event_token);
 }
 
+static int
+stop_reply_match_ptid_and_ws (QUEUE (stop_reply_p) *q,
+                             QUEUE_ITER (stop_reply_p) *iter,
+                             struct stop_reply *event,
+                             void *data)
+{
+  ptid_t *ptid = data;
+
+  return !(ptid_equal (*ptid, event->ptid)
+          && event->ws.kind == TARGET_WAITKIND_STOPPED);
+}
+
 /* Returns true if we have a stop reply for PTID.  */
 
 static int
 peek_stop_reply (ptid_t ptid)
 {
-  struct stop_reply *it;
-
-  for (it = stop_reply_queue; it; it = it->next)
-    if (ptid_equal (ptid, it->ptid))
-      {
-       if (it->ws.kind == TARGET_WAITKIND_STOPPED)
-         return 1;
-      }
-
-  return 0;
+  return !QUEUE_iterate (stop_reply_p, stop_reply_queue,
+                        stop_reply_match_ptid_and_ws, &ptid);
 }
 
 /* Parse the stop reply in BUF.  Either the function succeeds, and the
@@ -5407,10 +5493,10 @@ Packet: '%s'\n"),
              cached_reg.num = reg->regnum;
 
              fieldsize = hex2bin (p, cached_reg.data,
-                                  register_size (target_gdbarch,
+                                  register_size (target_gdbarch (),
                                                  reg->regnum));
              p += 2 * fieldsize;
-             if (fieldsize < register_size (target_gdbarch,
+             if (fieldsize < register_size (target_gdbarch (),
                                             reg->regnum))
                warning (_("Remote reply is too short: %s"), buf);
 
@@ -5493,13 +5579,14 @@ Packet: '%s'\n"),
     error (_("No process or thread specified in stop reply: %s"), buf);
 }
 
-/* When the stub wants to tell GDB about a new stop reply, it sends a
-   stop notification (%Stop).  Those can come it at any time, hence,
-   we have to make sure that any pending putpkt/getpkt sequence we're
-   making is finished, before querying the stub for more events with
-   vStopped.  E.g., if we started a vStopped sequence immediatelly
-   upon receiving the %Stop notification, something like this could
-   happen:
+/* When the stub wants to tell GDB about a new notification reply, it
+   sends a notification (%Stop, for example).  Those can come it at
+   any time, hence, we have to make sure that any pending
+   putpkt/getpkt sequence we're making is finished, before querying
+   the stub for more events with the corresponding ack command
+   (vStopped, for example).  E.g., if we started a vStopped sequence
+   immediately upon receiving the notification, something like this
+   could happen:
 
     1.1) --> Hg 1
     1.2) <-- OK
@@ -5534,19 +5621,21 @@ Packet: '%s'\n"),
     2.9) --> OK
 */
 
-static void
-remote_get_pending_stop_replies (void)
+void
+remote_notif_get_pending_events (struct notif_client *nc)
 {
   struct remote_state *rs = get_remote_state ();
 
-  if (pending_stop_reply)
+  if (nc->pending_event)
     {
-      /* acknowledge */
-      putpkt ("vStopped");
+      if (notif_debug)
+       fprintf_unfiltered (gdb_stdlog,
+                           "notif: process: '%s' ack pending event\n",
+                           nc->name);
 
-      /* Now we can rely on it.         */
-      push_stop_reply (pending_stop_reply);
-      pending_stop_reply = NULL;
+      /* acknowledge */
+      nc->ack (nc, rs->buf, nc->pending_event);
+      nc->pending_event = NULL;
 
       while (1)
        {
@@ -5554,31 +5643,18 @@ remote_get_pending_stop_replies (void)
          if (strcmp (rs->buf, "OK") == 0)
            break;
          else
-           {
-             struct cleanup *old_chain;
-             struct stop_reply *stop_reply = stop_reply_xmalloc ();
-
-             old_chain = make_cleanup (do_stop_reply_xfree, stop_reply);
-             remote_parse_stop_reply (rs->buf, stop_reply);
-
-             /* acknowledge */
-             putpkt ("vStopped");
-
-             if (stop_reply->ws.kind != TARGET_WAITKIND_IGNORE)
-               {
-                 /* Now we can rely on it.  */
-                 discard_cleanups (old_chain);
-                 push_stop_reply (stop_reply);
-               }
-             else
-               /* We got an unknown stop reply.  */
-               do_cleanups (old_chain);
-           }
+           remote_notif_ack (nc, rs->buf);
        }
     }
+  else
+    {
+      if (notif_debug)
+       fprintf_unfiltered (gdb_stdlog,
+                           "notif: process: '%s' no pending reply\n",
+                           nc->name);
+    }
 }
 
-
 /* Called when it is decided that STOP_REPLY holds the info of the
    event that is to be returned to the core.  This function always
    destroys STOP_REPLY.  */
@@ -5604,7 +5680,7 @@ process_stop_reply (struct stop_reply *stop_reply,
       if (stop_reply->regcache)
        {
          struct regcache *regcache
-           = get_thread_arch_regcache (ptid, target_gdbarch);
+           = get_thread_arch_regcache (ptid, target_gdbarch ());
          cached_reg_t *reg;
          int ix;
 
@@ -5634,15 +5710,16 @@ remote_wait_ns (ptid_t ptid, struct target_waitstatus *status, int options)
   struct remote_state *rs = get_remote_state ();
   struct stop_reply *stop_reply;
   int ret;
+  int is_notif = 0;
 
   /* If in non-stop mode, get out of getpkt even if a
      notification is received. */
 
   ret = getpkt_or_notif_sane (&rs->buf, &rs->buf_size,
-                             0 /* forever */);
+                             0 /* forever */, &is_notif);
   while (1)
     {
-      if (ret != -1)
+      if (ret != -1 && !is_notif)
        switch (rs->buf[0])
          {
          case 'E':             /* Error of some sort.  */
@@ -5661,8 +5738,8 @@ remote_wait_ns (ptid_t ptid, struct target_waitstatus *status, int options)
 
       /* Acknowledge a pending stop reply that may have arrived in the
         mean time.  */
-      if (pending_stop_reply != NULL)
-       remote_get_pending_stop_replies ();
+      if (notif_client_stop.pending_event != NULL)
+       remote_notif_get_pending_events (&notif_client_stop);
 
       /* If indeed we noticed a stop reply, we're done.  */
       stop_reply = queued_stop_reply (ptid);
@@ -5679,7 +5756,7 @@ remote_wait_ns (ptid_t ptid, struct target_waitstatus *status, int options)
 
       /* Otherwise do a blocking wait.  */
       ret = getpkt_or_notif_sane (&rs->buf, &rs->buf_size,
-                                 1 /* forever */);
+                                 1 /* forever */, &is_notif);
     }
 }
 
@@ -5709,6 +5786,7 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
   else
     {
       int ret;
+      int is_notif;
 
       if (!target_is_async_p ())
        {
@@ -5726,7 +5804,14 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
         _never_ wait for ever -> test on target_is_async_p().
         However, before we do that we need to ensure that the caller
         knows how to take the target into/out of async mode.  */
-      ret = getpkt_sane (&rs->buf, &rs->buf_size, wait_forever_enabled_p);
+      ret = getpkt_or_notif_sane (&rs->buf, &rs->buf_size,
+                                 wait_forever_enabled_p, &is_notif);
+
+      /* GDB gets a notification.  Return to core as this event is
+        not interesting.  */
+      if (ret != -1 && is_notif)
+       return minus_one_ptid;
+
       if (!target_is_async_p ())
        signal (SIGINT, ofunc);
     }
@@ -5758,13 +5843,10 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
       break;
     case 'T': case 'S': case 'X': case 'W':
       {
-       struct stop_reply *stop_reply;
-       struct cleanup *old_chain;
+       struct stop_reply *stop_reply
+         = (struct stop_reply *) remote_notif_parse (&notif_client_stop,
+                                                     rs->buf);
 
-       stop_reply = stop_reply_xmalloc ();
-       old_chain = make_cleanup (do_stop_reply_xfree, stop_reply);
-       remote_parse_stop_reply (buf, stop_reply);
-       discard_cleanups (old_chain);
        event_ptid = process_stop_reply (stop_reply, status);
        break;
       }
@@ -5845,7 +5927,7 @@ remote_wait (struct target_ops *ops,
     {
       /* If there are are events left in the queue tell the event loop
         to return here.  */
-      if (stop_reply_queue)
+      if (!QUEUE_is_empty (stop_reply_p, stop_reply_queue))
        mark_async_event_handler (remote_async_inferior_event_token);
     }
 
@@ -6318,7 +6400,7 @@ remote_address_masked (CORE_ADDR addr)
 
   /* If "remoteaddresssize" was not set, default to target address size.  */
   if (!address_size)
-    address_size = gdbarch_addr_bit (target_gdbarch);
+    address_size = gdbarch_addr_bit (target_gdbarch ());
 
   if (address_size > 0
       && address_size < (sizeof (ULONGEST) * 8))
@@ -6740,51 +6822,6 @@ remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
   /* Return what we have.  Let higher layers handle partial reads.  */
   return i;
 }
-\f
-
-/* Remote notification handler.  */
-
-static void
-handle_notification (char *buf)
-{
-  if (strncmp (buf, "Stop:", 5) == 0)
-    {
-      if (pending_stop_reply)
-       {
-         /* We've already parsed the in-flight stop-reply, but the
-            stub for some reason thought we didn't, possibly due to
-            timeout on its side.  Just ignore it.  */
-         if (remote_debug)
-           fprintf_unfiltered (gdb_stdlog, "ignoring resent notification\n");
-       }
-      else
-       {
-         struct cleanup *old_chain;
-         struct stop_reply *reply = stop_reply_xmalloc ();
-
-         old_chain = make_cleanup (do_stop_reply_xfree, reply);
-
-         remote_parse_stop_reply (buf + 5, reply);
-
-         discard_cleanups (old_chain);
-
-         /* Be careful to only set it after parsing, since an error
-            may be thrown then.  */
-         pending_stop_reply = reply;
-
-         /* Notify the event loop there's a stop reply to acknowledge
-            and that there may be more events to fetch.  */
-         mark_async_event_handler (remote_async_get_pending_events_token);
-
-         if (remote_debug)
-           fprintf_unfiltered (gdb_stdlog, "stop notification captured\n");
-       }
-    }
-  else
-    /* We ignore notifications we don't recognize, for compatibility
-       with newer stubs.  */
-    ;
-}
 
 \f
 /* Read or write LEN bytes from inferior memory at MEMADDR,
@@ -6853,7 +6890,7 @@ static void
 remote_flash_erase (struct target_ops *ops,
                     ULONGEST address, LONGEST length)
 {
-  int addr_size = gdbarch_addr_bit (target_gdbarch) / 8;
+  int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
   int saved_remote_timeout = remote_timeout;
   enum packet_result ret;
   struct cleanup *back_to = make_cleanup (restore_remote_timeout,
@@ -7026,6 +7063,7 @@ putpkt_binary (char *buf, int cnt)
   int ch;
   int tcount = 0;
   char *p;
+  char *message;
 
   /* Catch cases like trying to read memory or listing threads while
      we're waiting for a stop reply.  The remote server wouldn't be
@@ -7408,11 +7446,13 @@ getpkt (char **buf,
    0, this function is allowed to time out gracefully and return an
    indication of this to the caller.  Otherwise return the number of
    bytes read.  If EXPECTING_NOTIF, consider receiving a notification
-   enough reason to return to the caller.  */
+   enough reason to return to the caller.  *IS_NOTIF is an output
+   boolean that indicates whether *BUF holds a notification or not
+   (a regular packet).  */
 
 static int
 getpkt_or_notif_sane_1 (char **buf, long *sizeof_buf, int forever,
-                       int expecting_notif)
+                       int expecting_notif, int *is_notif)
 {
   struct remote_state *rs = get_remote_state ();
   int c;
@@ -7513,6 +7553,8 @@ getpkt_or_notif_sane_1 (char **buf, long *sizeof_buf, int forever,
          /* Skip the ack char if we're in no-ack mode.  */
          if (!rs->noack_mode)
            serial_write (remote_desc, "+", 1);
+         if (is_notif != NULL)
+           *is_notif = 0;
          return val;
        }
 
@@ -7534,13 +7576,15 @@ getpkt_or_notif_sane_1 (char **buf, long *sizeof_buf, int forever,
                                  str);
              do_cleanups (old_chain);
            }
+         if (is_notif != NULL)
+           *is_notif = 1;
 
          handle_notification (*buf);
 
          /* Notifications require no acknowledgement.  */
 
          if (expecting_notif)
-           return -1;
+           return val;
        }
     }
 }
@@ -7548,13 +7592,15 @@ getpkt_or_notif_sane_1 (char **buf, long *sizeof_buf, int forever,
 static int
 getpkt_sane (char **buf, long *sizeof_buf, int forever)
 {
-  return getpkt_or_notif_sane_1 (buf, sizeof_buf, forever, 0);
+  return getpkt_or_notif_sane_1 (buf, sizeof_buf, forever, 0, NULL);
 }
 
 static int
-getpkt_or_notif_sane (char **buf, long *sizeof_buf, int forever)
+getpkt_or_notif_sane (char **buf, long *sizeof_buf, int forever,
+                     int *is_notif)
 {
-  return getpkt_or_notif_sane_1 (buf, sizeof_buf, forever, 1);
+  return getpkt_or_notif_sane_1 (buf, sizeof_buf, forever, 1,
+                                is_notif);
 }
 
 \f
@@ -7654,9 +7700,6 @@ extended_remote_mourn_1 (struct target_ops *target)
      connected.  */
   rs->waiting_for_stop_reply = 0;
 
-  /* We're no longer interested in these events.  */
-  discard_pending_stop_replies (ptid_get_pid (inferior_ptid));
-
   /* If the current general thread belonged to the process we just
      detached from or has exited, the remote side current general
      thread becomes undefined.  Considering a case like this:
@@ -8181,6 +8224,7 @@ remote_insert_hw_breakpoint (struct gdbarch *gdbarch,
   CORE_ADDR addr;
   struct remote_state *rs;
   char *p, *endbuf;
+  char *message;
 
   /* The length field should be set to the size of a breakpoint
      instruction, even though we aren't inserting one ourselves.  */
@@ -8215,6 +8259,13 @@ remote_insert_hw_breakpoint (struct gdbarch *gdbarch,
   switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z1]))
     {
     case PACKET_ERROR:
+      if (rs->buf[1] == '.')
+        {
+          message = strchr (rs->buf + 2, '.');
+          if (message)
+            error (_("Remote failure reply: %s"), message + 1);
+        }
+      return -1;
     case PACKET_UNKNOWN:
       return -1;
     case PACKET_OK:
@@ -8368,12 +8419,12 @@ compare_sections_command (char *args, int from_tty)
 
       if (res == -1)
        error (_("target memory fault, section %s, range %s -- %s"), sectname,
-              paddress (target_gdbarch, lma),
-              paddress (target_gdbarch, lma + size));
+              paddress (target_gdbarch (), lma),
+              paddress (target_gdbarch (), lma + size));
 
       printf_filtered ("Section %s, range %s -- %s: ", sectname,
-                      paddress (target_gdbarch, lma),
-                      paddress (target_gdbarch, lma + size));
+                      paddress (target_gdbarch (), lma),
+                      paddress (target_gdbarch (), lma + size));
       if (res)
        printf_filtered ("matched.\n");
       else
@@ -8729,7 +8780,7 @@ remote_search_memory (struct target_ops* ops,
                      const gdb_byte *pattern, ULONGEST pattern_len,
                      CORE_ADDR *found_addrp)
 {
-  int addr_size = gdbarch_addr_bit (target_gdbarch) / 8;
+  int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
   struct remote_state *rs = get_remote_state ();
   int max_size = get_memory_write_packet_size ();
   struct packet_config *packet =
@@ -9263,7 +9314,7 @@ static int
 remote_read_description_p (struct target_ops *target)
 {
   struct remote_g_packet_data *data
-    = gdbarch_data (target_gdbarch, remote_g_packet_data_handle);
+    = gdbarch_data (target_gdbarch (), remote_g_packet_data_handle);
 
   if (!VEC_empty (remote_g_packet_guess_s, data->guesses))
     return 1;
@@ -9275,7 +9326,7 @@ static const struct target_desc *
 remote_read_description (struct target_ops *target)
 {
   struct remote_g_packet_data *data
-    = gdbarch_data (target_gdbarch, remote_g_packet_data_handle);
+    = gdbarch_data (target_gdbarch (), remote_g_packet_data_handle);
 
   /* Do not try this during initial connection, when we do not know
      whether there is a running but stopped thread.  */
@@ -10269,7 +10320,7 @@ remote_download_tracepoint (struct bp_location *loc)
        {
          int isize;
 
-         if (gdbarch_fast_tracepoint_valid_at (target_gdbarch,
+         if (gdbarch_fast_tracepoint_valid_at (target_gdbarch (),
                                                tpaddr, &isize, NULL))
            xsnprintf (buf + strlen (buf), BUF_SIZE - strlen (buf), ":F%x",
                       isize);
@@ -10579,15 +10630,11 @@ remote_get_trace_status (struct trace_status *ts)
   /* We're working with a live target.  */
   ts->from_file = 0;
 
-  /* Set some defaults.  */
-  ts->running_known = 0;
-  ts->stop_reason = trace_stop_reason_unknown;
-  ts->traceframe_count = -1;
-  ts->buffer_free = 0;
-
   if (*p++ != 'T')
     error (_("Bogus trace status reply from target: %s"), target_buf);
 
+  /* Function 'parse_trace_status' sets default value of each field of
+     'ts' at first, so we don't have to do it here.  */
   parse_trace_status (p, ts);
 
   return ts->running;
@@ -11182,12 +11229,6 @@ remote_async_inferior_event_handler (gdb_client_data data)
   inferior_event_handler (INF_REG_EVENT, NULL);
 }
 
-static void
-remote_async_get_pending_events_handler (gdb_client_data data)
-{
-  remote_get_pending_stop_replies ();
-}
-
 static void
 remote_async (void (*callback) (enum inferior_event_type event_type,
                                void *context), void *context)
@@ -11329,6 +11370,9 @@ _initialize_remote (void)
 
   /* Hook into new objfile notification.  */
   observer_attach_new_objfile (remote_new_objfile);
+  /* We're no longer interested in notification events of an inferior
+     when it exits.  */
+  observer_attach_inferior_exit (discard_pending_stop_replies);
 
   /* Set up signal handlers.  */
   sigint_remote_token =
@@ -11340,6 +11384,7 @@ _initialize_remote (void)
   init_remote_threadtests ();
 #endif
 
+  stop_reply_queue = QUEUE_alloc (stop_reply_p, stop_reply_xfree);
   /* set/show remote ...  */
 
   add_prefix_cmd ("remote", class_maintenance, set_remote_cmd, _("\
This page took 0.041259 seconds and 4 git commands to generate.