1 /* CLI Definitions for GDB, the GNU debugger. 2 3 Copyright (C) 2002-2016 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 #include "defs.h" 21 #include "cli-interp.h" 22 #include "interps.h" 23 #include "event-top.h" 24 #include "ui-out.h" 25 #include "cli-out.h" 26 #include "top.h" /* for "execute_command" */ 27 #include "event-top.h" 28 #include "infrun.h" 29 #include "observer.h" 30 #include "gdbthread.h" 31 #include "thread-fsm.h" 32 33 /* The console interpreter. */ 34 struct cli_interp 35 { 36 /* The ui_out for the console interpreter. */ 37 struct ui_out *cli_uiout; 38 }; 39 40 /* Suppress notification struct. */ 41 struct cli_suppress_notification cli_suppress_notification = 42 { 43 0 /* user_selected_context_changed */ 44 }; 45 46 /* Returns the INTERP's data cast as cli_interp if INTERP is a CLI, 47 and returns NULL otherwise. */ 48 49 static struct cli_interp * 50 as_cli_interp (struct interp *interp) 51 { 52 if (strcmp (interp_name (interp), INTERP_CONSOLE) == 0) 53 return (struct cli_interp *) interp_data (interp); 54 return NULL; 55 } 56 57 /* Longjmp-safe wrapper for "execute_command". */ 58 static struct gdb_exception safe_execute_command (struct ui_out *uiout, 59 char *command, 60 int from_tty); 61 62 /* See cli-interp.h. 63 64 Breakpoint hits should always be mirrored to a console. Deciding 65 what to mirror to a console wrt to breakpoints and random stops 66 gets messy real fast. E.g., say "s" trips on a breakpoint. We'd 67 clearly want to mirror the event to the console in this case. But 68 what about more complicated cases like "s&; thread n; s&", and one 69 of those steps spawning a new thread, and that thread hitting a 70 breakpoint? It's impossible in general to track whether the thread 71 had any relation to the commands that had been executed. So we 72 just simplify and always mirror breakpoints and random events to 73 all consoles. 74 75 OTOH, we should print the source line to the console when stepping 76 or other similar commands, iff the step was started by that console 77 (or in MI's case, by a console command), but not if it was started 78 with MI's -exec-step or similar. */ 79 80 int 81 should_print_stop_to_console (struct interp *console_interp, 82 struct thread_info *tp) 83 { 84 if ((bpstat_what (tp->control.stop_bpstat).main_action 85 == BPSTAT_WHAT_STOP_NOISY) 86 || tp->thread_fsm == NULL 87 || tp->thread_fsm->command_interp == console_interp 88 || !thread_fsm_finished_p (tp->thread_fsm)) 89 return 1; 90 return 0; 91 } 92 93 /* Observers for several run control events. If the interpreter is 94 quiet (i.e., another interpreter is being run with 95 interpreter-exec), print nothing. */ 96 97 /* Observer for the normal_stop notification. */ 98 99 static void 100 cli_on_normal_stop (struct bpstats *bs, int print_frame) 101 { 102 struct switch_thru_all_uis state; 103 104 if (!print_frame) 105 return; 106 107 SWITCH_THRU_ALL_UIS (state) 108 { 109 struct interp *interp = top_level_interpreter (); 110 struct cli_interp *cli = as_cli_interp (interp); 111 struct thread_info *thread; 112 113 if (cli == NULL) 114 continue; 115 116 thread = inferior_thread (); 117 if (should_print_stop_to_console (interp, thread)) 118 print_stop_event (cli->cli_uiout); 119 } 120 } 121 122 /* Observer for the signal_received notification. */ 123 124 static void 125 cli_on_signal_received (enum gdb_signal siggnal) 126 { 127 struct switch_thru_all_uis state; 128 129 SWITCH_THRU_ALL_UIS (state) 130 { 131 struct cli_interp *cli = as_cli_interp (top_level_interpreter ()); 132 133 if (cli == NULL) 134 continue; 135 136 print_signal_received_reason (cli->cli_uiout, siggnal); 137 } 138 } 139 140 /* Observer for the end_stepping_range notification. */ 141 142 static void 143 cli_on_end_stepping_range (void) 144 { 145 struct switch_thru_all_uis state; 146 147 SWITCH_THRU_ALL_UIS (state) 148 { 149 struct cli_interp *cli = as_cli_interp (top_level_interpreter ()); 150 151 if (cli == NULL) 152 continue; 153 154 print_end_stepping_range_reason (cli->cli_uiout); 155 } 156 } 157 158 /* Observer for the signalled notification. */ 159 160 static void 161 cli_on_signal_exited (enum gdb_signal siggnal) 162 { 163 struct switch_thru_all_uis state; 164 165 SWITCH_THRU_ALL_UIS (state) 166 { 167 struct cli_interp *cli = as_cli_interp (top_level_interpreter ()); 168 169 if (cli == NULL) 170 continue; 171 172 print_signal_exited_reason (cli->cli_uiout, siggnal); 173 } 174 } 175 176 /* Observer for the exited notification. */ 177 178 static void 179 cli_on_exited (int exitstatus) 180 { 181 struct switch_thru_all_uis state; 182 183 SWITCH_THRU_ALL_UIS (state) 184 { 185 struct cli_interp *cli = as_cli_interp (top_level_interpreter ()); 186 187 if (cli == NULL) 188 continue; 189 190 print_exited_reason (cli->cli_uiout, exitstatus); 191 } 192 } 193 194 /* Observer for the no_history notification. */ 195 196 static void 197 cli_on_no_history (void) 198 { 199 struct switch_thru_all_uis state; 200 201 SWITCH_THRU_ALL_UIS (state) 202 { 203 struct cli_interp *cli = as_cli_interp (top_level_interpreter ()); 204 205 if (cli == NULL) 206 continue; 207 208 print_no_history_reason (cli->cli_uiout); 209 } 210 } 211 212 /* Observer for the sync_execution_done notification. */ 213 214 static void 215 cli_on_sync_execution_done (void) 216 { 217 struct cli_interp *cli = as_cli_interp (top_level_interpreter ()); 218 219 if (cli == NULL) 220 return; 221 222 display_gdb_prompt (NULL); 223 } 224 225 /* Observer for the command_error notification. */ 226 227 static void 228 cli_on_command_error (void) 229 { 230 struct cli_interp *cli = as_cli_interp (top_level_interpreter ()); 231 232 if (cli == NULL) 233 return; 234 235 display_gdb_prompt (NULL); 236 } 237 238 /* Observer for the user_selected_context_changed notification. */ 239 240 static void 241 cli_on_user_selected_context_changed (user_selected_what selection) 242 { 243 struct switch_thru_all_uis state; 244 struct thread_info *tp; 245 246 /* This event is suppressed. */ 247 if (cli_suppress_notification.user_selected_context) 248 return; 249 250 tp = find_thread_ptid (inferior_ptid); 251 252 SWITCH_THRU_ALL_UIS (state) 253 { 254 struct cli_interp *cli = as_cli_interp (top_level_interpreter ()); 255 256 if (cli == NULL) 257 continue; 258 259 if (selection & USER_SELECTED_INFERIOR) 260 print_selected_inferior (cli->cli_uiout); 261 262 if (tp != NULL 263 && ((selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME)))) 264 print_selected_thread_frame (cli->cli_uiout, selection); 265 } 266 } 267 268 /* pre_command_loop implementation. */ 269 270 void 271 cli_interpreter_pre_command_loop (struct interp *self) 272 { 273 display_gdb_prompt (0); 274 } 275 276 /* These implement the cli out interpreter: */ 277 278 static void * 279 cli_interpreter_init (struct interp *self, int top_level) 280 { 281 return interp_data (self); 282 } 283 284 static int 285 cli_interpreter_resume (void *data) 286 { 287 struct ui *ui = current_ui; 288 struct cli_interp *cli = (struct cli_interp *) data; 289 struct ui_file *stream; 290 291 /*sync_execution = 1; */ 292 293 /* gdb_setup_readline will change gdb_stdout. If the CLI was 294 previously writing to gdb_stdout, then set it to the new 295 gdb_stdout afterwards. */ 296 297 stream = cli_out_set_stream (cli->cli_uiout, gdb_stdout); 298 if (stream != gdb_stdout) 299 { 300 cli_out_set_stream (cli->cli_uiout, stream); 301 stream = NULL; 302 } 303 304 gdb_setup_readline (1); 305 306 ui->input_handler = command_line_handler; 307 308 if (stream != NULL) 309 cli_out_set_stream (cli->cli_uiout, gdb_stdout); 310 311 return 1; 312 } 313 314 static int 315 cli_interpreter_suspend (void *data) 316 { 317 gdb_disable_readline (); 318 return 1; 319 } 320 321 static struct gdb_exception 322 cli_interpreter_exec (void *data, const char *command_str) 323 { 324 struct cli_interp *cli = (struct cli_interp *) data; 325 struct ui_file *old_stream; 326 struct gdb_exception result; 327 328 /* FIXME: cagney/2003-02-01: Need to const char *propogate 329 safe_execute_command. */ 330 char *str = (char *) alloca (strlen (command_str) + 1); 331 strcpy (str, command_str); 332 333 /* gdb_stdout could change between the time cli_uiout was 334 initialized and now. Since we're probably using a different 335 interpreter which has a new ui_file for gdb_stdout, use that one 336 instead of the default. 337 338 It is important that it gets reset everytime, since the user 339 could set gdb to use a different interpreter. */ 340 old_stream = cli_out_set_stream (cli->cli_uiout, gdb_stdout); 341 result = safe_execute_command (cli->cli_uiout, str, 1); 342 cli_out_set_stream (cli->cli_uiout, old_stream); 343 return result; 344 } 345 346 int 347 cli_interpreter_supports_command_editing (struct interp *interp) 348 { 349 return 1; 350 } 351 352 static struct gdb_exception 353 safe_execute_command (struct ui_out *command_uiout, char *command, int from_tty) 354 { 355 struct gdb_exception e = exception_none; 356 struct ui_out *saved_uiout; 357 358 /* Save and override the global ``struct ui_out'' builder. */ 359 saved_uiout = current_uiout; 360 current_uiout = command_uiout; 361 362 TRY 363 { 364 execute_command (command, from_tty); 365 } 366 CATCH (exception, RETURN_MASK_ALL) 367 { 368 e = exception; 369 } 370 END_CATCH 371 372 /* Restore the global builder. */ 373 current_uiout = saved_uiout; 374 375 /* FIXME: cagney/2005-01-13: This shouldn't be needed. Instead the 376 caller should print the exception. */ 377 exception_print (gdb_stderr, e); 378 return e; 379 } 380 381 static struct ui_out * 382 cli_ui_out (struct interp *self) 383 { 384 struct cli_interp *cli = (struct cli_interp *) interp_data (self); 385 386 return cli->cli_uiout; 387 } 388 389 /* The CLI interpreter's vtable. */ 390 391 static const struct interp_procs cli_interp_procs = { 392 cli_interpreter_init, /* init_proc */ 393 cli_interpreter_resume, /* resume_proc */ 394 cli_interpreter_suspend, /* suspend_proc */ 395 cli_interpreter_exec, /* exec_proc */ 396 cli_ui_out, /* ui_out_proc */ 397 NULL, /* set_logging_proc */ 398 cli_interpreter_pre_command_loop, /* pre_command_loop_proc */ 399 cli_interpreter_supports_command_editing, /* supports_command_editing_proc */ 400 }; 401 402 /* Factory for CLI interpreters. */ 403 404 static struct interp * 405 cli_interp_factory (const char *name) 406 { 407 struct cli_interp *cli = XNEW (struct cli_interp); 408 409 /* Create a default uiout builder for the CLI. */ 410 cli->cli_uiout = cli_out_new (gdb_stdout); 411 412 return interp_new (name, &cli_interp_procs, cli); 413 } 414 415 /* Standard gdb initialization hook. */ 416 extern initialize_file_ftype _initialize_cli_interp; /* -Wmissing-prototypes */ 417 418 void 419 _initialize_cli_interp (void) 420 { 421 interp_factory_register (INTERP_CONSOLE, cli_interp_factory); 422 423 /* If changing this, remember to update tui-interp.c as well. */ 424 observer_attach_normal_stop (cli_on_normal_stop); 425 observer_attach_end_stepping_range (cli_on_end_stepping_range); 426 observer_attach_signal_received (cli_on_signal_received); 427 observer_attach_signal_exited (cli_on_signal_exited); 428 observer_attach_exited (cli_on_exited); 429 observer_attach_no_history (cli_on_no_history); 430 observer_attach_sync_execution_done (cli_on_sync_execution_done); 431 observer_attach_command_error (cli_on_command_error); 432 observer_attach_user_selected_context_changed 433 (cli_on_user_selected_context_changed); 434 } 435