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