1 /* Remote notification in GDB protocol 2 3 Copyright (C) 1988-2019 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 "observable.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 { 50 ¬if_client_stop, 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 (remote_target *remote, 62 struct notif_client *nc, const char *buf) 63 { 64 struct notif_event *event = nc->alloc_event (); 65 struct cleanup *old_chain 66 = make_cleanup (do_notif_event_xfree, event); 67 68 if (notif_debug) 69 fprintf_unfiltered (gdb_stdlog, "notif: ack '%s'\n", 70 nc->ack_command); 71 72 nc->parse (remote, nc, buf, event); 73 nc->ack (remote, nc, buf, event); 74 75 discard_cleanups (old_chain); 76 } 77 78 /* Parse the BUF for the expected notification NC. */ 79 80 struct notif_event * 81 remote_notif_parse (remote_target *remote, 82 struct notif_client *nc, const char *buf) 83 { 84 struct notif_event *event = nc->alloc_event (); 85 struct cleanup *old_chain 86 = make_cleanup (do_notif_event_xfree, event); 87 88 if (notif_debug) 89 fprintf_unfiltered (gdb_stdlog, "notif: parse '%s'\n", nc->name); 90 91 nc->parse (remote, nc, buf, event); 92 93 discard_cleanups (old_chain); 94 return event; 95 } 96 97 DEFINE_QUEUE_P (notif_client_p); 98 99 /* Process notifications in STATE's notification queue one by one. 100 EXCEPT is not expected in the queue. */ 101 102 void 103 remote_notif_process (struct remote_notif_state *state, 104 struct notif_client *except) 105 { 106 while (!QUEUE_is_empty (notif_client_p, state->notif_queue)) 107 { 108 struct notif_client *nc = QUEUE_deque (notif_client_p, 109 state->notif_queue); 110 111 gdb_assert (nc != except); 112 113 if (nc->can_get_pending_events (state->remote, nc)) 114 remote_notif_get_pending_events (state->remote, nc); 115 } 116 } 117 118 static void 119 remote_async_get_pending_events_handler (gdb_client_data data) 120 { 121 gdb_assert (target_is_non_stop_p ()); 122 remote_notif_process ((struct remote_notif_state *) data, NULL); 123 } 124 125 /* Remote notification handler. Parse BUF, queue notification and 126 update STATE. */ 127 128 void 129 handle_notification (struct remote_notif_state *state, const char *buf) 130 { 131 struct notif_client *nc; 132 size_t i; 133 134 for (i = 0; i < ARRAY_SIZE (notifs); i++) 135 { 136 const char *name = notifs[i]->name; 137 138 if (startswith (buf, name) 139 && buf[strlen (name)] == ':') 140 break; 141 } 142 143 /* We ignore notifications we don't recognize, for compatibility 144 with newer stubs. */ 145 if (i == ARRAY_SIZE (notifs)) 146 return; 147 148 nc = notifs[i]; 149 150 if (state->pending_event[nc->id] != NULL) 151 { 152 /* We've already parsed the in-flight reply, but the stub for some 153 reason thought we didn't, possibly due to timeout on its side. 154 Just ignore it. */ 155 if (notif_debug) 156 fprintf_unfiltered (gdb_stdlog, 157 "notif: ignoring resent notification\n"); 158 } 159 else 160 { 161 struct notif_event *event 162 = remote_notif_parse (state->remote, nc, buf + strlen (nc->name) + 1); 163 164 /* Be careful to only set it after parsing, since an error 165 may be thrown then. */ 166 state->pending_event[nc->id] = event; 167 168 /* Notify the event loop there's a stop reply to acknowledge 169 and that there may be more events to fetch. */ 170 QUEUE_enque (notif_client_p, state->notif_queue, nc); 171 if (target_is_non_stop_p ()) 172 { 173 /* In non-stop, We mark REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN 174 in order to go on what we were doing and postpone 175 querying notification events to some point safe to do so. 176 See details in the function comment of 177 remote.c:remote_notif_get_pending_events. 178 179 In all-stop, GDB may be blocked to wait for the reply, we 180 shouldn't return to event loop until the expected reply 181 arrives. For example: 182 183 1.1) --> vCont;c 184 GDB expects getting stop reply 'T05 thread:2'. 185 1.2) <-- %Notif 186 <GDB marks the REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN> 187 188 After step #1.2, we return to the event loop, which 189 notices there is a new event on the 190 REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN and calls the 191 handler, which will send 'vNotif' packet. 192 1.3) --> vNotif 193 It is not safe to start a new sequence, because target 194 is still running and GDB is expecting the stop reply 195 from stub. 196 197 To solve this, whenever we parse a notification 198 successfully, we don't mark the 199 REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN and let GDB blocked 200 there as before to get the sequence done. 201 202 2.1) --> vCont;c 203 GDB expects getting stop reply 'T05 thread:2' 204 2.2) <-- %Notif 205 <Don't mark the REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN> 206 2.3) <-- T05 thread:2 207 208 These pending notifications can be processed later. */ 209 mark_async_event_handler (state->get_pending_events_token); 210 } 211 212 if (notif_debug) 213 fprintf_unfiltered (gdb_stdlog, 214 "notif: Notification '%s' captured\n", 215 nc->name); 216 } 217 } 218 219 /* Invoke destructor of EVENT and xfree it. */ 220 221 void 222 notif_event_xfree (struct notif_event *event) 223 { 224 if (event != NULL && event->dtr != NULL) 225 event->dtr (event); 226 227 xfree (event); 228 } 229 230 /* Cleanup wrapper. */ 231 232 static void 233 do_notif_event_xfree (void *arg) 234 { 235 notif_event_xfree ((struct notif_event *) arg); 236 } 237 238 /* Return an allocated remote_notif_state. */ 239 240 struct remote_notif_state * 241 remote_notif_state_allocate (remote_target *remote) 242 { 243 struct remote_notif_state *notif_state = XCNEW (struct remote_notif_state); 244 245 notif_state->remote = remote; 246 247 notif_state->notif_queue = QUEUE_alloc (notif_client_p, NULL); 248 249 /* Register async_event_handler for notification. */ 250 251 notif_state->get_pending_events_token 252 = create_async_event_handler (remote_async_get_pending_events_handler, 253 notif_state); 254 255 return notif_state; 256 } 257 258 /* Free STATE and its fields. */ 259 260 void 261 remote_notif_state_xfree (struct remote_notif_state *state) 262 { 263 int i; 264 265 QUEUE_free (notif_client_p, state->notif_queue); 266 267 /* Unregister async_event_handler for notification. */ 268 if (state->get_pending_events_token != NULL) 269 delete_async_event_handler (&state->get_pending_events_token); 270 271 for (i = 0; i < REMOTE_NOTIF_LAST; i++) 272 notif_event_xfree (state->pending_event[i]); 273 274 xfree (state); 275 } 276 277 void 278 _initialize_notif (void) 279 { 280 add_setshow_boolean_cmd ("notification", no_class, ¬if_debug, 281 _("\ 282 Set debugging of async remote notification."), _("\ 283 Show debugging of async remote notification."), _("\ 284 When non-zero, debugging output about async remote notifications" 285 " is enabled."), 286 NULL, 287 NULL, 288 &setdebuglist, &showdebuglist); 289 } 290