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