GDB (xrefs)
/tmp/gdb-7.10/gdb/remote-notif.c
Go to the documentation of this file.
1 /* Remote notification in GDB protocol
2 
3  Copyright (C) 1988-2015 Free Software Foundation, Inc.
4 
5  This file is part of GDB.
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 
20 /* Remote async notification is sent from remote target over RSP.
21  Each type of notification is represented by an object of
22  'struct notif', which has a field 'pending_reply'. It is not
23  NULL when GDB receives a notification from GDBserver, but hasn't
24  acknowledge yet. Before GDB acknowledges the notification,
25  GDBserver shouldn't send notification again (see the header comments
26  in gdbserver/notif.c).
27 
28  Notifications are processed in an almost-unified approach for both
29  all-stop mode and non-stop mode, except the timing to process them.
30  In non-stop mode, notifications are processed in
31  remote_async_get_pending_events_handler, while in all-stop mode,
32  they are processed in remote_resume. */
33 
34 #include "defs.h"
35 #include "remote.h"
36 #include "remote-notif.h"
37 #include "observer.h"
38 #include "event-loop.h"
39 #include "target.h"
40 #include "inferior.h"
41 #include "infrun.h"
42 #include "gdbcmd.h"
43 
44 int notif_debug = 0;
45 
46 /* Supported clients of notifications. */
47 
48 static struct notif_client *notifs[] =
49 {
51 };
52 
53 gdb_static_assert (ARRAY_SIZE (notifs) == REMOTE_NOTIF_LAST);
54 
55 static void do_notif_event_xfree (void *arg);
56 
57 /* Parse the BUF for the expected notification NC, and send packet to
58  acknowledge. */
59 
60 void
61 remote_notif_ack (struct notif_client *nc, char *buf)
62 {
63  struct notif_event *event = nc->alloc_event ();
64  struct cleanup *old_chain
66 
67  if (notif_debug)
68  fprintf_unfiltered (gdb_stdlog, "notif: ack '%s'\n",
69  nc->ack_command);
70 
71  nc->parse (nc, buf, event);
72  nc->ack (nc, buf, event);
73 
74  discard_cleanups (old_chain);
75 }
76 
77 /* Parse the BUF for the expected notification NC. */
78 
79 struct notif_event *
80 remote_notif_parse (struct notif_client *nc, char *buf)
81 {
82  struct notif_event *event = nc->alloc_event ();
83  struct cleanup *old_chain
85 
86  if (notif_debug)
87  fprintf_unfiltered (gdb_stdlog, "notif: parse '%s'\n", nc->name);
88 
89  nc->parse (nc, buf, event);
90 
91  discard_cleanups (old_chain);
92  return event;
93 }
94 
96 
97 /* Process notifications in STATE's notification queue one by one.
98  EXCEPT is not expected in the queue. */
99 
100 void
102  struct notif_client *except)
103 {
104  while (!QUEUE_is_empty (notif_client_p, state->notif_queue))
105  {
107  state->notif_queue);
108 
109  gdb_assert (nc != except);
110 
111  if (nc->can_get_pending_events (nc))
113  }
114 }
115 
116 static void
118 {
120  remote_notif_process (data, NULL);
121 }
122 
123 /* Remote notification handler. Parse BUF, queue notification and
124  update STATE. */
125 
126 void
127 handle_notification (struct remote_notif_state *state, char *buf)
128 {
129  struct notif_client *nc;
130  size_t i;
131 
132  for (i = 0; i < ARRAY_SIZE (notifs); i++)
133  {
134  const char *name = notifs[i]->name;
135 
136  if (startswith (buf, name)
137  && buf[strlen (name)] == ':')
138  break;
139  }
140 
141  /* We ignore notifications we don't recognize, for compatibility
142  with newer stubs. */
143  if (i == ARRAY_SIZE (notifs))
144  return;
145 
146  nc = notifs[i];
147 
148  if (state->pending_event[nc->id] != NULL)
149  {
150  /* We've already parsed the in-flight reply, but the stub for some
151  reason thought we didn't, possibly due to timeout on its side.
152  Just ignore it. */
153  if (notif_debug)
155  "notif: ignoring resent notification\n");
156  }
157  else
158  {
159  struct notif_event *event
160  = remote_notif_parse (nc, buf + strlen (nc->name) + 1);
161 
162  /* Be careful to only set it after parsing, since an error
163  may be thrown then. */
164  state->pending_event[nc->id] = event;
165 
166  /* Notify the event loop there's a stop reply to acknowledge
167  and that there may be more events to fetch. */
168  QUEUE_enque (notif_client_p, state->notif_queue, nc);
169  if (non_stop)
170  {
171  /* In non-stop, We mark REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN
172  in order to go on what we were doing and postpone
173  querying notification events to some point safe to do so.
174  See details in the function comment of
175  remote.c:remote_notif_get_pending_events.
176 
177  In all-stop, GDB may be blocked to wait for the reply, we
178  shouldn't return to event loop until the expected reply
179  arrives. For example:
180 
181  1.1) --> vCont;c
182  GDB expects getting stop reply 'T05 thread:2'.
183  1.2) <-- %Notif
184  <GDB marks the REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN>
185 
186  After step #1.2, we return to the event loop, which
187  notices there is a new event on the
188  REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN and calls the
189  handler, which will send 'vNotif' packet.
190  1.3) --> vNotif
191  It is not safe to start a new sequence, because target
192  is still running and GDB is expecting the stop reply
193  from stub.
194 
195  To solve this, whenever we parse a notification
196  successfully, we don't mark the
197  REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN and let GDB blocked
198  there as before to get the sequence done.
199 
200  2.1) --> vCont;c
201  GDB expects getting stop reply 'T05 thread:2'
202  2.2) <-- %Notif
203  <Don't mark the REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN>
204  2.3) <-- T05 thread:2
205 
206  These pending notifications can be processed later. */
208  }
209 
210  if (notif_debug)
212  "notif: Notification '%s' captured\n",
213  nc->name);
214  }
215 }
216 
217 /* Invoke destructor of EVENT and xfree it. */
218 
219 void
221 {
222  if (event != NULL && event->dtr != NULL)
223  event->dtr (event);
224 
225  xfree (event);
226 }
227 
228 /* Cleanup wrapper. */
229 
230 static void
232 {
233  notif_event_xfree (arg);
234 }
235 
236 /* Return an allocated remote_notif_state. */
237 
238 struct remote_notif_state *
240 {
241  struct remote_notif_state *notif_state = xzalloc (sizeof (*notif_state));
242 
243  notif_state->notif_queue = QUEUE_alloc (notif_client_p, NULL);
244 
245  /* Register async_event_handler for notification. */
246 
247  notif_state->get_pending_events_token
249  notif_state);
250 
251  return notif_state;
252 }
253 
254 /* Free STATE and its fields. */
255 
256 void
258 {
259  int i;
260 
261  QUEUE_free (notif_client_p, state->notif_queue);
262 
263  /* Unregister async_event_handler for notification. */
264  if (state->get_pending_events_token != NULL)
266 
267  for (i = 0; i < REMOTE_NOTIF_LAST; i++)
268  notif_event_xfree (state->pending_event[i]);
269 
270  xfree (state);
271 }
272 
273 /* -Wmissing-prototypes */
275 
276 void
278 {
279  add_setshow_boolean_cmd ("notification", no_class, &notif_debug,
280  _("\
281 Set debugging of async remote notification."), _("\
282 Show debugging of async remote notification."), _("\
283 When non-zero, debugging output about async remote notifications"
284 " is enabled."),
285  NULL,
286  NULL,
288 }
static void remote_async_get_pending_events_handler(gdb_client_data data)
Definition: remote-notif.c:117
void remote_notif_process(struct remote_notif_state *state, struct notif_client *except)
Definition: remote-notif.c:101
static void do_notif_event_xfree(void *arg)
Definition: remote-notif.c:231
void xfree(void *)
Definition: common-utils.c:97
#define QUEUE_enque(TYPE, Q, V)
Definition: queue.h:55
#define QUEUE_is_empty(TYPE, Q)
Definition: queue.h:66
void delete_async_event_handler(async_event_handler **async_handler_ptr)
Definition: event-loop.c:1050
void mark_async_event_handler(async_event_handler *async_handler_ptr)
Definition: event-loop.c:1011
struct notif_event * pending_event[REMOTE_NOTIF_LAST]
Definition: remote-notif.h:98
void remote_notif_get_pending_events(struct notif_client *nc)
Definition: remote.c:6144
initialize_file_ftype _initialize_notif
#define _(String)
Definition: gdb_locale.h:40
int(* can_get_pending_events)(struct notif_client *self)
Definition: remote-notif.h:65
struct notif_event *(* alloc_event)(void)
Definition: remote-notif.h:68
const char *const name
Definition: aarch64-tdep.c:68
struct notif_event * remote_notif_parse(struct notif_client *nc, char *buf)
Definition: remote-notif.c:80
void initialize_file_ftype(void)
Definition: defs.h:281
void * xzalloc(size_t size)
Definition: common-utils.c:91
void fprintf_unfiltered(struct ui_file *stream, const char *format,...)
Definition: utils.c:2361
async_event_handler * create_async_event_handler(async_event_handler_func *proc, gdb_client_data client_data)
Definition: event-loop.c:988
void remote_notif_state_xfree(struct remote_notif_state *state)
Definition: remote-notif.c:257
struct cleanup * make_cleanup(make_cleanup_ftype *function, void *arg)
Definition: cleanups.c:117
#define gdb_assert(expr)
Definition: gdb_assert.h:33
static int startswith(const char *string, const char *pattern)
Definition: common-utils.h:75
#define QUEUE_deque(TYPE, Q)
Definition: queue.h:59
struct cmd_list_element * setdebuglist
Definition: cli-cmds.c:173
const char * ack_command
Definition: remote-notif.h:50
struct ui_file * gdb_stdlog
Definition: main.c:73
void * gdb_client_data
Definition: event-loop.h:70
#define QUEUE_free(TYPE, Q)
Definition: queue.h:76
struct notif_client notif_client_stop
Definition: remote.c:5552
#define QUEUE_alloc(TYPE, FREE_FUNC)
Definition: queue.h:70
void remote_notif_ack(struct notif_client *nc, char *buf)
Definition: remote-notif.c:61
gdb_static_assert(ARRAY_SIZE(notifs)==REMOTE_NOTIF_LAST)
void discard_cleanups(struct cleanup *old_chain)
Definition: cleanups.c:213
int non_stop
Definition: infrun.c:180
DEFINE_QUEUE_P(notif_client_p)
struct remote_notif_state * remote_notif_state_allocate(void)
Definition: remote-notif.c:239
void notif_event_xfree(struct notif_event *event)
Definition: remote-notif.c:220
enum REMOTE_NOTIF_ID id
Definition: remote-notif.h:71
int notif_debug
Definition: remote-notif.c:44
void(* ack)(struct notif_client *self, char *buf, struct notif_event *event)
Definition: remote-notif.h:60
void handle_notification(struct remote_notif_state *state, char *buf)
Definition: remote-notif.c:127
struct cmd_list_element * showdebuglist
Definition: cli-cmds.c:175
void(* dtr)(struct notif_event *self)
Definition: remote-notif.h:31
void(* parse)(struct notif_client *self, char *buf, struct notif_event *event)
Definition: remote-notif.h:55
struct async_event_handler * get_pending_events_token
Definition: remote-notif.h:89
const char * name
Definition: remote-notif.h:47
void add_setshow_boolean_cmd(const char *name, enum command_class theclass, int *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_sfunc_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
Definition: cli-decode.c:541