1/* User Interface Events. 2 3 Copyright 1999, 2001, 2002 Free Software Foundation, Inc. 4 5 Contributed by Cygnus Solutions. 6 7 This file is part of GDB. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 22 23/* Work in progress */ 24 25/* This file was created with the aid of ``gdb-events.sh''. 26 27 The bourn shell script ``gdb-events.sh'' creates the files 28 ``new-gdb-events.c'' and ``new-gdb-events.h and then compares 29 them against the existing ``gdb-events.[hc]''. Any differences 30 found being reported. 31 32 If editing this file, please also run gdb-events.sh and merge any 33 changes into that script. Conversely, when making sweeping changes 34 to this file, modifying gdb-events.sh and using its output may 35 prove easier. */ 36 37 38#include "defs.h" 39#include "gdb-events.h" 40#include "gdbcmd.h" 41 42#if WITH_GDB_EVENTS 43static struct gdb_events null_event_hooks; 44static struct gdb_events queue_event_hooks; 45static struct gdb_events *current_event_hooks = &null_event_hooks; 46#endif 47 48int gdb_events_debug; 49 50#if WITH_GDB_EVENTS 51 52void 53breakpoint_create_event (int b) 54{ 55 if (gdb_events_debug) 56 fprintf_unfiltered (gdb_stdlog, "breakpoint_create_event\n"); 57 if (!current_event_hooks->breakpoint_create) 58 return; 59 current_event_hooks->breakpoint_create (b); 60} 61 62void 63breakpoint_delete_event (int b) 64{ 65 if (gdb_events_debug) 66 fprintf_unfiltered (gdb_stdlog, "breakpoint_delete_event\n"); 67 if (!current_event_hooks->breakpoint_delete) 68 return; 69 current_event_hooks->breakpoint_delete (b); 70} 71 72void 73breakpoint_modify_event (int b) 74{ 75 if (gdb_events_debug) 76 fprintf_unfiltered (gdb_stdlog, "breakpoint_modify_event\n"); 77 if (!current_event_hooks->breakpoint_modify) 78 return; 79 current_event_hooks->breakpoint_modify (b); 80} 81 82void 83tracepoint_create_event (int number) 84{ 85 if (gdb_events_debug) 86 fprintf_unfiltered (gdb_stdlog, "tracepoint_create_event\n"); 87 if (!current_event_hooks->tracepoint_create) 88 return; 89 current_event_hooks->tracepoint_create (number); 90} 91 92void 93tracepoint_delete_event (int number) 94{ 95 if (gdb_events_debug) 96 fprintf_unfiltered (gdb_stdlog, "tracepoint_delete_event\n"); 97 if (!current_event_hooks->tracepoint_delete) 98 return; 99 current_event_hooks->tracepoint_delete (number); 100} 101 102void 103tracepoint_modify_event (int number) 104{ 105 if (gdb_events_debug) 106 fprintf_unfiltered (gdb_stdlog, "tracepoint_modify_event\n"); 107 if (!current_event_hooks->tracepoint_modify) 108 return; 109 current_event_hooks->tracepoint_modify (number); 110} 111 112void 113architecture_changed_event (void) 114{ 115 if (gdb_events_debug) 116 fprintf_unfiltered (gdb_stdlog, "architecture_changed_event\n"); 117 if (!current_event_hooks->architecture_changed) 118 return; 119 current_event_hooks->architecture_changed (); 120} 121 122void 123target_changed_event (void) 124{ 125 if (gdb_events_debug) 126 fprintf_unfiltered (gdb_stdlog, "target_changed_event\n"); 127 if (!current_event_hooks->target_changed) 128 return; 129 current_event_hooks->target_changed (); 130} 131 132void 133selected_frame_level_changed_event (int level) 134{ 135 if (gdb_events_debug) 136 fprintf_unfiltered (gdb_stdlog, "selected_frame_level_changed_event\n"); 137 if (!current_event_hooks->selected_frame_level_changed) 138 return; 139 current_event_hooks->selected_frame_level_changed (level); 140} 141 142void 143selected_thread_changed_event (int thread_num) 144{ 145 if (gdb_events_debug) 146 fprintf_unfiltered (gdb_stdlog, "selected_thread_changed_event\n"); 147 if (!current_event_hooks->selected_thread_changed) 148 return; 149 current_event_hooks->selected_thread_changed (thread_num); 150} 151 152#endif 153 154#if WITH_GDB_EVENTS 155struct gdb_events * 156set_gdb_event_hooks (struct gdb_events *vector) 157{ 158 struct gdb_events *old_events = current_event_hooks; 159 if (vector == NULL) 160 current_event_hooks = &queue_event_hooks; 161 else 162 current_event_hooks = vector; 163 return old_events; 164} 165#endif 166 167#if WITH_GDB_EVENTS 168void 169clear_gdb_event_hooks (void) 170{ 171 set_gdb_event_hooks (&null_event_hooks); 172} 173#endif 174 175enum gdb_event 176{ 177 breakpoint_create, 178 breakpoint_delete, 179 breakpoint_modify, 180 tracepoint_create, 181 tracepoint_delete, 182 tracepoint_modify, 183 architecture_changed, 184 target_changed, 185 selected_frame_level_changed, 186 selected_thread_changed, 187 nr_gdb_events 188}; 189 190struct breakpoint_create 191 { 192 int b; 193 }; 194 195struct breakpoint_delete 196 { 197 int b; 198 }; 199 200struct breakpoint_modify 201 { 202 int b; 203 }; 204 205struct tracepoint_create 206 { 207 int number; 208 }; 209 210struct tracepoint_delete 211 { 212 int number; 213 }; 214 215struct tracepoint_modify 216 { 217 int number; 218 }; 219 220struct selected_frame_level_changed 221 { 222 int level; 223 }; 224 225struct selected_thread_changed 226 { 227 int thread_num; 228 }; 229 230struct event 231 { 232 enum gdb_event type; 233 struct event *next; 234 union 235 { 236 struct breakpoint_create breakpoint_create; 237 struct breakpoint_delete breakpoint_delete; 238 struct breakpoint_modify breakpoint_modify; 239 struct tracepoint_create tracepoint_create; 240 struct tracepoint_delete tracepoint_delete; 241 struct tracepoint_modify tracepoint_modify; 242 struct selected_frame_level_changed selected_frame_level_changed; 243 struct selected_thread_changed selected_thread_changed; 244 } 245 data; 246 }; 247struct event *pending_events; 248struct event *delivering_events; 249 250static void 251append (struct event *new_event) 252{ 253 struct event **event = &pending_events; 254 while ((*event) != NULL) 255 event = &((*event)->next); 256 (*event) = new_event; 257 (*event)->next = NULL; 258} 259 260static void 261queue_breakpoint_create (int b) 262{ 263 struct event *event = XMALLOC (struct event); 264 event->type = breakpoint_create; 265 event->data.breakpoint_create.b = b; 266 append (event); 267} 268 269static void 270queue_breakpoint_delete (int b) 271{ 272 struct event *event = XMALLOC (struct event); 273 event->type = breakpoint_delete; 274 event->data.breakpoint_delete.b = b; 275 append (event); 276} 277 278static void 279queue_breakpoint_modify (int b) 280{ 281 struct event *event = XMALLOC (struct event); 282 event->type = breakpoint_modify; 283 event->data.breakpoint_modify.b = b; 284 append (event); 285} 286 287static void 288queue_tracepoint_create (int number) 289{ 290 struct event *event = XMALLOC (struct event); 291 event->type = tracepoint_create; 292 event->data.tracepoint_create.number = number; 293 append (event); 294} 295 296static void 297queue_tracepoint_delete (int number) 298{ 299 struct event *event = XMALLOC (struct event); 300 event->type = tracepoint_delete; 301 event->data.tracepoint_delete.number = number; 302 append (event); 303} 304 305static void 306queue_tracepoint_modify (int number) 307{ 308 struct event *event = XMALLOC (struct event); 309 event->type = tracepoint_modify; 310 event->data.tracepoint_modify.number = number; 311 append (event); 312} 313 314static void 315queue_architecture_changed (void) 316{ 317 struct event *event = XMALLOC (struct event); 318 event->type = architecture_changed; 319 append (event); 320} 321 322static void 323queue_target_changed (void) 324{ 325 struct event *event = XMALLOC (struct event); 326 event->type = target_changed; 327 append (event); 328} 329 330static void 331queue_selected_frame_level_changed (int level) 332{ 333 struct event *event = XMALLOC (struct event); 334 event->type = selected_frame_level_changed; 335 event->data.selected_frame_level_changed.level = level; 336 append (event); 337} 338 339static void 340queue_selected_thread_changed (int thread_num) 341{ 342 struct event *event = XMALLOC (struct event); 343 event->type = selected_thread_changed; 344 event->data.selected_thread_changed.thread_num = thread_num; 345 append (event); 346} 347 348void 349gdb_events_deliver (struct gdb_events *vector) 350{ 351 /* Just zap any events left around from last time. */ 352 while (delivering_events != NULL) 353 { 354 struct event *event = delivering_events; 355 delivering_events = event->next; 356 xfree (event); 357 } 358 /* Process any pending events. Because one of the deliveries could 359 bail out we move everything off of the pending queue onto an 360 in-progress queue where it can, later, be cleaned up if 361 necessary. */ 362 delivering_events = pending_events; 363 pending_events = NULL; 364 while (delivering_events != NULL) 365 { 366 struct event *event = delivering_events; 367 switch (event->type) 368 { 369 case breakpoint_create: 370 vector->breakpoint_create 371 (event->data.breakpoint_create.b); 372 break; 373 case breakpoint_delete: 374 vector->breakpoint_delete 375 (event->data.breakpoint_delete.b); 376 break; 377 case breakpoint_modify: 378 vector->breakpoint_modify 379 (event->data.breakpoint_modify.b); 380 break; 381 case tracepoint_create: 382 vector->tracepoint_create 383 (event->data.tracepoint_create.number); 384 break; 385 case tracepoint_delete: 386 vector->tracepoint_delete 387 (event->data.tracepoint_delete.number); 388 break; 389 case tracepoint_modify: 390 vector->tracepoint_modify 391 (event->data.tracepoint_modify.number); 392 break; 393 case architecture_changed: 394 vector->architecture_changed (); 395 break; 396 case target_changed: 397 vector->target_changed (); 398 break; 399 case selected_frame_level_changed: 400 vector->selected_frame_level_changed 401 (event->data.selected_frame_level_changed.level); 402 break; 403 case selected_thread_changed: 404 vector->selected_thread_changed 405 (event->data.selected_thread_changed.thread_num); 406 break; 407 } 408 delivering_events = event->next; 409 xfree (event); 410 } 411} 412 413void _initialize_gdb_events (void); 414void 415_initialize_gdb_events (void) 416{ 417 struct cmd_list_element *c; 418#if WITH_GDB_EVENTS 419 queue_event_hooks.breakpoint_create = queue_breakpoint_create; 420 queue_event_hooks.breakpoint_delete = queue_breakpoint_delete; 421 queue_event_hooks.breakpoint_modify = queue_breakpoint_modify; 422 queue_event_hooks.tracepoint_create = queue_tracepoint_create; 423 queue_event_hooks.tracepoint_delete = queue_tracepoint_delete; 424 queue_event_hooks.tracepoint_modify = queue_tracepoint_modify; 425 queue_event_hooks.architecture_changed = queue_architecture_changed; 426 queue_event_hooks.target_changed = queue_target_changed; 427 queue_event_hooks.selected_frame_level_changed = queue_selected_frame_level_changed; 428 queue_event_hooks.selected_thread_changed = queue_selected_thread_changed; 429#endif 430 431 c = add_set_cmd ("eventdebug", class_maintenance, var_zinteger, 432 (char *) (&gdb_events_debug), "Set event debugging.\n\ 433When non-zero, event/notify debugging is enabled.", &setlist); 434 deprecate_cmd (c, "set debug event"); 435 deprecate_cmd (add_show_from_set (c, &showlist), "show debug event"); 436 437 add_show_from_set (add_set_cmd ("event", 438 class_maintenance, 439 var_zinteger, 440 (char *) (&gdb_events_debug), 441 "Set event debugging.\n\ 442When non-zero, event/notify debugging is enabled.", &setdebuglist), 443 &showdebuglist); 444} 445