GDB (xrefs)
Loading...
Searching...
No Matches
cli-interp.c
Go to the documentation of this file.
1/* CLI Definitions for GDB, the GNU debugger.
2
3 Copyright (C) 2002-2023 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"
27#include "ui.h"
28#include "infrun.h"
29#include "observable.h"
30#include "gdbthread.h"
31#include "thread-fsm.h"
32#include "inferior.h"
33
37
40
41/* The console interpreter. */
42
43class cli_interp final : public cli_interp_base
44{
45 public:
46 explicit cli_interp (const char *name);
47 ~cli_interp () = default;
48
49 void init (bool top_level) override;
50 void resume () override;
51 void suspend () override;
52 void exec (const char *command_str) override;
53 ui_out *interp_ui_out () override;
54
55private:
56
57 /* The ui_out for the console interpreter. */
58 std::unique_ptr<cli_ui_out> m_cli_uiout;
59};
60
63 m_cli_uiout (new cli_ui_out (gdb_stdout))
64{
65}
66
67/* Suppress notification struct. */
69
70/* See cli-interp.h.
71
72 Breakpoint hits should always be mirrored to a console. Deciding
73 what to mirror to a console wrt to breakpoints and random stops
74 gets messy real fast. E.g., say "s" trips on a breakpoint. We'd
75 clearly want to mirror the event to the console in this case. But
76 what about more complicated cases like "s&; thread n; s&", and one
77 of those steps spawning a new thread, and that thread hitting a
78 breakpoint? It's impossible in general to track whether the thread
79 had any relation to the commands that had been executed. So we
80 just simplify and always mirror breakpoints and random events to
81 all consoles.
82
83 OTOH, we should print the source line to the console when stepping
84 or other similar commands, iff the step was started by that console
85 (or in MI's case, by a console command), but not if it was started
86 with MI's -exec-step or similar. */
87
88int
89should_print_stop_to_console (struct interp *console_interp,
90 struct thread_info *tp)
91{
94 || tp->thread_fsm () == nullptr
95 || tp->thread_fsm ()->command_interp == console_interp
96 || !tp->thread_fsm ()->finished_p ())
97 return 1;
98 return 0;
99}
100
101/* Observers for several run control events. If the interpreter is
102 quiet (i.e., another interpreter is being run with
103 interpreter-exec), print nothing. These are named "cli_base" as
104 they print to both CLI interpreters and TUI interpreters. */
105
106void
108{
109 if (!print_frame)
110 return;
111
112 /* This event is suppressed. */
114 return;
115
116 thread_info *thread = inferior_thread ();
117 if (should_print_stop_to_console (this, thread))
119
120}
121
122void
123cli_interp_base::on_signal_received (enum gdb_signal siggnal)
124{
126}
127
128void
130{
132}
133
134void
139
140void
145
146void
151
152void
157
158void
160{
161 /* This event is suppressed. */
163 return;
164
165 thread_info *tp = inferior_ptid != null_ptid ? inferior_thread () : nullptr;
166
167 if (selection & USER_SELECTED_INFERIOR)
169
170 if (tp != nullptr
171 && ((selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME))))
172 print_selected_thread_frame (this->interp_ui_out (), selection);
173}
174
175/* pre_command_loop implementation. */
176
177void
182
183/* These implement the cli out interpreter: */
184
185void
186cli_interp::init (bool top_level)
187{
188}
189
190void
192{
193 struct ui *ui = current_ui;
194 struct ui_file *stream;
195
196 /*sync_execution = 1; */
197
198 /* gdb_setup_readline will change gdb_stdout. If the CLI was
199 previously writing to gdb_stdout, then set it to the new
200 gdb_stdout afterwards. */
201
202 stream = m_cli_uiout->set_stream (gdb_stdout);
203 if (stream != gdb_stdout)
204 {
205 m_cli_uiout->set_stream (stream);
206 stream = NULL;
207 }
208
210
212
213 if (stream != NULL)
214 m_cli_uiout->set_stream (gdb_stdout);
215}
216
217void
222
223void
224cli_interp::exec (const char *command_str)
225{
226 /* gdb_stdout could change between the time m_cli_uiout was
227 initialized and now. Since we're probably using a different
228 interpreter which has a new ui_file for gdb_stdout, use that one
229 instead of the default.
230
231 It is important that it gets reset everytime, since the user
232 could set gdb to use a different interpreter. */
233 ui_file *old_stream = m_cli_uiout->set_stream (gdb_stdout);
234 SCOPE_EXIT { m_cli_uiout->set_stream (old_stream); };
235
236 /* Save and override the global ``struct ui_out'' builder. */
237 scoped_restore saved_uiout = make_scoped_restore (&current_uiout,
238 m_cli_uiout.get ());
239
240 try
241 {
242 execute_command (command_str, 1);
243 }
244 catch (const gdb_exception_error &ex)
245 {
247 throw;
248 }
249}
250
251bool
253{
254 return true;
255}
256
257ui_out *
259{
260 return m_cli_uiout.get ();
261}
262
263/* See cli-interp.h. */
264
265void
267 bool debug_redirect)
268{
269 if (logfile != nullptr)
270 {
271 gdb_assert (m_saved_output == nullptr);
278
279 ui_file *logfile_p = logfile.get ();
280 m_saved_output->logfile_holder = std::move (logfile);
281
282 /* The new stdout and stderr only depend on whether logging
283 redirection is being done. */
284 ui_file *new_stdout = logfile_p;
285 ui_file *new_stderr = logfile_p;
286 if (!logging_redirect)
287 {
288 m_saved_output->stdout_holder.reset
289 (new tee_file (gdb_stdout, logfile_p));
290 new_stdout = m_saved_output->stdout_holder.get ();
291 m_saved_output->stderr_holder.reset
292 (new tee_file (gdb_stderr, logfile_p));
293 new_stderr = m_saved_output->stderr_holder.get ();
294 }
295
296 m_saved_output->stdlog_holder.reset
297 (new timestamped_file (debug_redirect ? logfile_p : new_stderr));
298
299 gdb_stdout = new_stdout;
300 gdb_stdlog = m_saved_output->stdlog_holder.get ();
301 gdb_stderr = new_stderr;
302 gdb_stdtarg = new_stderr;
303 gdb_stdtargerr = new_stderr;
304 }
305 else
306 {
312
313 m_saved_output.reset (nullptr);
314 }
315}
316
317/* Factory for CLI interpreters. */
318
319static struct interp *
321{
322 return new cli_interp (name);
323}
324
325/* Standard gdb initialization hook. */
326
328void
const char *const name
@ BPSTAT_WHAT_STOP_NOISY
void pre_command_loop() override
Definition cli-interp.c:178
void set_logging(ui_file_up logfile, bool logging_redirect, bool debug_redirect) override
Definition cli-interp.c:266
void on_normal_stop(bpstat *bs, int print_frame) override
Definition cli-interp.c:107
void on_exited(int status) override
Definition cli-interp.c:135
bool supports_command_editing() override
Definition cli-interp.c:252
void on_user_selected_context_changed(user_selected_what selection) override
Definition cli-interp.c:159
void on_no_history() override
Definition cli-interp.c:141
void on_signal_exited(gdb_signal sig) override
Definition cli-interp.c:129
cli_interp_base(const char *name)
Definition cli-interp.c:34
virtual ~cli_interp_base()=0
Definition cli-interp.c:38
void on_signal_received(gdb_signal sig) override
Definition cli-interp.c:123
void on_command_error() override
Definition cli-interp.c:153
void on_sync_execution_done() override
Definition cli-interp.c:147
std::unique_ptr< saved_output_files > m_saved_output
Definition cli-interp.h:64
void resume() override
Definition cli-interp.c:191
void exec(const char *command_str) override
Definition cli-interp.c:224
void suspend() override
Definition cli-interp.c:218
ui_out * interp_ui_out() override
Definition cli-interp.c:258
~cli_interp()=default
void init(bool top_level) override
Definition cli-interp.c:186
cli_interp(const char *name)
Definition cli-interp.c:61
std::unique_ptr< cli_ui_out > m_cli_uiout
Definition cli-interp.c:58
virtual ui_out * interp_ui_out()=0
const char * name() const
Definition interps.h:87
struct thread_fsm * thread_fsm() const
Definition gdbthread.h:452
thread_control_state control
Definition gdbthread.h:343
void _initialize_cli_interp()
Definition cli-interp.c:329
int should_print_stop_to_console(struct interp *console_interp, struct thread_info *tp)
Definition cli-interp.c:89
static struct interp * cli_interp_factory(const char *name)
Definition cli-interp.c:320
int should_print_stop_to_console(struct interp *interp, struct thread_info *tp)
Definition cli-interp.c:89
static bool debug_redirect
Definition cli-logging.c:67
static bool logging_redirect
Definition cli-logging.c:66
@ USER_SELECTED_THREAD
Definition defs.h:598
@ USER_SELECTED_FRAME
Definition defs.h:601
@ USER_SELECTED_INFERIOR
Definition defs.h:595
void display_gdb_prompt(const char *new_prompt)
Definition event-top.c:398
void gdb_setup_readline(int editing)
Definition event-top.c:1278
void gdb_disable_readline(void)
Definition event-top.c:1319
void command_line_handler(gdb::unique_xmalloc_ptr< char > &&rl)
Definition event-top.c:717
void exception_print(struct ui_file *file, const struct gdb_exception &e)
Definition exceptions.c:106
void execute_command(const char *, int)
Definition top.c:459
void print_selected_thread_frame(struct ui_out *uiout, user_selected_what selection)
Definition thread.c:2009
struct thread_info * inferior_thread(void)
Definition thread.c:85
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int status
Definition gnu-nat.c:1790
ptid_t inferior_ptid
Definition infcmd.c:74
void print_selected_inferior(struct ui_out *uiout)
Definition inferior.c:508
void print_no_history_reason(struct ui_out *uiout)
Definition infrun.c:8720
void print_stop_event(struct ui_out *uiout, bool displays)
Definition infrun.c:8791
void print_signal_exited_reason(struct ui_out *uiout, enum gdb_signal siggnal)
Definition infrun.c:8620
void print_exited_reason(struct ui_out *uiout, int exitstatus)
Definition infrun.c:8641
void print_signal_received_reason(struct ui_out *uiout, enum gdb_signal siggnal)
Definition infrun.c:8668
void interp_factory_register(const char *name, interp_factory_func func)
Definition interps.c:78
#define INTERP_CONSOLE
Definition interps.h:367
struct ui_file * gdb_stdtarg
Definition main.c:80
struct ui_file * gdb_stdtargerr
Definition main.c:81
static void print_frame(const frame_print_options &opts, frame_info_ptr frame, int print_level, enum print_what print_what, int print_args, struct symtab_and_line sal)
enum bpstat_what_main_action main_action
bool finished_p() const
Definition thread-fsm.h:87
struct interp * command_interp
Definition thread-fsm.h:98
Definition ui.h:55
void(* input_handler)(gdb::unique_xmalloc_ptr< char > &&)
Definition ui.h:82
std::unique_ptr< ui_file > ui_file_up
Definition ui-file.h:150
#define current_uiout
Definition ui-out.h:40
struct ui * current_ui
Definition ui.c:35
#define gdb_stderr
Definition utils.h:187
#define gdb_stdlog
Definition utils.h:190
#define gdb_stdout
Definition utils.h:182