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