GDB (xrefs)
cli-interp.c
Go to the documentation of this file.
1 /* CLI Definitions for GDB, the GNU debugger.
2 
3  Copyright (C) 2002-2018 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 
34  : interp (name)
35 {}
36 
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. */
55 };
56 
59 {
60  /* Create a default uiout builder for the CLI. */
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 *
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  const 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 {
110  || tp->thread_fsm == NULL
111  || tp->thread_fsm->command_interp == console_interp
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
125 {
126  if (!print_frame)
127  return;
128 
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))
141  }
142 }
143 
144 /* Observer for the signal_received notification. */
145 
146 static void
147 cli_on_signal_received (enum gdb_signal siggnal)
148 {
150  {
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
164 {
166  {
168 
169  if (cli == NULL)
170  continue;
171 
173  }
174 }
175 
176 /* Observer for the signalled notification. */
177 
178 static void
179 cli_on_signal_exited (enum gdb_signal siggnal)
180 {
182  {
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 {
198  {
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
212 {
214  {
216 
217  if (cli == NULL)
218  continue;
219 
221  }
222 }
223 
224 /* Observer for the sync_execution_done notification. */
225 
226 static void
228 {
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
241 {
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. */
259  return;
260 
262 
264  {
266 
267  if (cli == NULL)
268  continue;
269 
270  if (selection & USER_SELECTED_INFERIOR)
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
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
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 
317 
318  if (stream != NULL)
320 }
321 
322 void
324 {
326 }
327 
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  /* gdb_stdout could change between the time cli_uiout was
336  initialized and now. Since we're probably using a different
337  interpreter which has a new ui_file for gdb_stdout, use that one
338  instead of the default.
339 
340  It is important that it gets reset everytime, since the user
341  could set gdb to use a different interpreter. */
342  old_stream = cli->cli_uiout->set_stream (gdb_stdout);
343  result = safe_execute_command (cli->cli_uiout, command_str, 1);
344  cli->cli_uiout->set_stream (old_stream);
345  return result;
346 }
347 
348 bool
350 {
351  return true;
352 }
353 
354 static struct gdb_exception
355 safe_execute_command (struct ui_out *command_uiout, const char *command,
356  int from_tty)
357 {
358  struct gdb_exception e = exception_none;
359  struct ui_out *saved_uiout;
360 
361  /* Save and override the global ``struct ui_out'' builder. */
362  saved_uiout = current_uiout;
363  current_uiout = command_uiout;
364 
365  TRY
366  {
367  execute_command (command, from_tty);
368  }
369  CATCH (exception, RETURN_MASK_ALL)
370  {
371  e = exception;
372  }
373  END_CATCH
374 
375  /* Restore the global builder. */
376  current_uiout = saved_uiout;
377 
378  /* FIXME: cagney/2005-01-13: This shouldn't be needed. Instead the
379  caller should print the exception. */
381  return e;
382 }
383 
384 ui_out *
386 {
387  struct cli_interp *cli = (struct cli_interp *) this;
388 
389  return cli->cli_uiout;
390 }
391 
392 /* These hold the pushed copies of the gdb output files.
393  If NULL then nothing has yet been pushed. */
395 {
401 };
403 
404 /* See cli-interp.h. */
405 
406 void
408 {
409  if (logfile != NULL)
410  {
416 
417  /* A raw pointer since ownership is transferred to
418  gdb_stdout. */
420  std::move (logfile),
422  gdb_stdout = output;
423  gdb_stdlog = output;
424  gdb_stderr = output;
425  gdb_stdtarg = output;
426  gdb_stdtargerr = output;
427  }
428  else
429  {
430  /* Only delete one of the files -- they are all set to the same
431  value. */
432  delete gdb_stdout;
433 
439 
440  saved_output.out = NULL;
441  saved_output.err = NULL;
442  saved_output.log = NULL;
443  saved_output.targ = NULL;
444  saved_output.targerr = NULL;
445  }
446 }
447 
448 /* Factory for CLI interpreters. */
449 
450 static struct interp *
452 {
453  return new cli_interp (name);
454 }
455 
456 /* Standard gdb initialization hook. */
457 
458 void
460 {
462 
463  /* If changing this, remember to update tui-interp.c as well. */
474 }
static void cli_on_end_stepping_range(void)
Definition: cli-interp.c:163
static struct interp * cli_interp_factory(const char *name)
Definition: cli-interp.c:451
struct thread_info * find_thread_ptid(ptid_t ptid)
Definition: thread.c:514
struct ui * current_ui
Definition: event-top.c:453
int should_print_stop_to_console(struct interp *console_interp, struct thread_info *tp)
Definition: cli-interp.c:105
void print_signal_received_reason(struct ui_out *uiout, enum gdb_signal siggnal)
Definition: infrun.c:7927
static void cli_on_sync_execution_done(void)
Definition: cli-interp.c:227
void _initialize_cli_interp(void)
Definition: cli-interp.c:459
void print_no_history_reason(struct ui_out *uiout)
Definition: infrun.c:7977
std::unique_ptr< ui_file > ui_file_up
Definition: ui-file.h:76
cli_interp_base(const char *name)
Definition: cli-interp.c:33
Definition: interps.h:41
struct thread_info * inferior_thread(void)
Definition: thread.c:90
struct observer * observer_attach_signal_exited(observer_signal_exited_ftype *f)
void print_exited_reason(struct ui_out *uiout, int exitstatus)
Definition: infrun.c:7881
const struct gdb_exception exception_none
interp(const char *name)
Definition: interps.c:80
void init(bool top_level) override
Definition: cli-interp.c:290
void gdb_setup_readline(int editing)
Definition: event-top.c:1176
static saved_output_files saved_output
Definition: cli-interp.c:402
#define INTERP_CONSOLE
Definition: interps.h:170
cli_interp(const char *name)
Definition: cli-interp.c:57
static void cli_on_command_error(void)
Definition: cli-interp.c:240
void resume() override
Definition: cli-interp.c:295
cli_ui_out * cli_uiout
Definition: cli-interp.c:54
struct interp * command_interp
Definition: thread-fsm.h:45
void gdb_disable_readline(void)
Definition: event-top.c:1226
struct observer * observer_attach_signal_received(observer_signal_received_ftype *f)
#define END_CATCH
void command_line_handler(char *rl)
Definition: event-top.c:749
ui_out * interp_ui_out() override
Definition: cli-interp.c:385
static struct gdb_exception safe_execute_command(struct ui_out *uiout, const char *command, int from_tty)
Definition: cli-interp.c:355
void(* input_handler)(char *)
Definition: top.h:84
void execute_command(const char *, int)
Definition: top.c:540
#define TRY
ui_file * make_logging_output(ui_file *curr_output, ui_file_up logfile, bool logging_redirect)
Definition: cli-logging.c:94
struct observer * observer_attach_no_history(observer_no_history_ftype *f)
void print_signal_exited_reason(struct ui_out *uiout, enum gdb_signal siggnal)
Definition: infrun.c:7860
const char *const name
Definition: aarch64-tdep.c:76
#define CATCH(EXCEPTION, MASK)
static int logging_redirect
Definition: cli-logging.c:64
void print_stop_event(struct ui_out *uiout)
Definition: infrun.c:8044
void print_selected_thread_frame(struct ui_out *uiout, user_selected_what selection)
Definition: thread.c:1942
void interp_factory_register(const char *name, interp_factory_func func)
Definition: interps.c:111
void exception_print(struct ui_file *file, struct gdb_exception e)
Definition: exceptions.c:109
static void cli_on_exited(int exitstatus)
Definition: cli-interp.c:195
virtual ~cli_interp_base()=0
Definition: cli-interp.c:37
#define current_uiout
Definition: ui-out.h:39
struct observer * observer_attach_command_error(observer_command_error_ftype *f)
Definition: top.h:56
struct observer * observer_attach_exited(observer_exited_ftype *f)
struct thread_fsm * thread_fsm
Definition: gdbthread.h:337
int thread_fsm_finished_p(struct thread_fsm *self)
Definition: thread-fsm.c:84
static struct cli_interp * as_cli_interp(struct interp *interp)
Definition: cli-interp.c:74
const char * name
Definition: interps.h:78
static void cli_on_signal_exited(enum gdb_signal siggnal)
Definition: cli-interp.c:179
void set_logging(ui_file_up logfile, bool logging_redirect) override
Definition: cli-interp.c:407
static void cli_on_normal_stop(struct bpstats *bs, int print_frame)
Definition: cli-interp.c:124
bool supports_command_editing() override
Definition: cli-interp.c:349
void print_selected_inferior(struct ui_out *uiout)
Definition: inferior.c:512
#define SWITCH_THRU_ALL_UIS()
Definition: top.h:206
Definition: ui-out.h:77
const char * interp_name(struct interp *interp)
Definition: interps.c:292
static void cli_on_no_history(void)
Definition: cli-interp.c:211
void suspend() override
Definition: cli-interp.c:323
struct observer * observer_attach_user_selected_context_changed(observer_user_selected_context_changed_ftype *f)
static void print_frame(struct frame_info *frame, int print_level, enum print_what print_what, int print_args, struct symtab_and_line sal)
void print_end_stepping_range_reason(struct ui_out *uiout)
Definition: infrun.c:7848
#define gdb_stderr
Definition: utils.h:344
thread_control_state control
Definition: gdbthread.h:291
ptid_t inferior_ptid
Definition: infcmd.c:94
void pre_command_loop() override
Definition: cli-interp.c:282
ui_file * set_stream(ui_file *stream)
Definition: cli-out.c:287
gdb_exception exec(const char *command_str) override
Definition: cli-interp.c:329
struct ui_file * gdb_stdtarg
Definition: main.c:75
static void cli_on_signal_received(enum gdb_signal siggnal)
Definition: cli-interp.c:147
void display_gdb_prompt(const char *new_prompt)
Definition: event-top.c:353
struct observer * observer_attach_normal_stop(observer_normal_stop_ftype *f)
struct interp * top_level_interpreter(void)
Definition: interps.c:449
#define gdb_stdlog
Definition: utils.h:349
struct ui_file * gdb_stdtargerr
Definition: main.c:76
static void cli_on_user_selected_context_changed(user_selected_what selection)
Definition: cli-interp.c:253
struct observer * observer_attach_sync_execution_done(observer_sync_execution_done_ftype *f)
struct observer * observer_attach_end_stepping_range(observer_end_stepping_range_ftype *f)
cli_ui_out * cli_out_new(struct ui_file *stream)
Definition: cli-out.c:281
ui_file * targerr
Definition: cli-interp.c:400
#define gdb_stdout
Definition: utils.h:340
enum bpstat_what_main_action main_action
Definition: breakpoint.h:1005