1 /* Command-line output logging for GDB, the GNU debugger.
3 Copyright (C) 2003-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
20 #include "cli/cli-cmds.h"
23 #include "cli/cli-style.h"
24 #include "cli/cli-decode.h"
26 static std::string saved_filename
;
28 static std::string logging_filename
= "gdb.txt";
30 show_logging_filename (struct ui_file
*file
, int from_tty
,
31 struct cmd_list_element
*c
, const char *value
)
33 gdb_printf (file
, _("The current logfile is \"%ps\".\n"),
34 styled_string (file_name_style
.style (), value
));
37 static bool logging_overwrite
;
40 maybe_warn_already_logging ()
42 if (!saved_filename
.empty ())
43 warning (_("Currently logging to %s. Turn the logging off and on to "
44 "make the new setting effective."), saved_filename
.c_str ());
48 set_logging_overwrite (const char *args
,
49 int from_tty
, struct cmd_list_element
*c
)
51 maybe_warn_already_logging ();
55 show_logging_overwrite (struct ui_file
*file
, int from_tty
,
56 struct cmd_list_element
*c
, const char *value
)
58 if (logging_overwrite
)
59 gdb_printf (file
, _("on: Logging overwrites the log file.\n"));
61 gdb_printf (file
, _("off: Logging appends to the log file.\n"));
64 /* Value as configured by the user. */
65 static bool logging_redirect
;
66 static bool debug_redirect
;
69 set_logging_redirect (const char *args
,
70 int from_tty
, struct cmd_list_element
*c
)
72 maybe_warn_already_logging ();
76 show_logging_redirect (struct ui_file
*file
, int from_tty
,
77 struct cmd_list_element
*c
, const char *value
)
80 gdb_printf (file
, _("on: Output will go only to the log file.\n"));
84 _("off: Output will go to both the screen and the log file.\n"));
88 show_logging_debug_redirect (struct ui_file
*file
, int from_tty
,
89 struct cmd_list_element
*c
, const char *value
)
92 gdb_printf (file
, _("on: Debug output will go only to the log file.\n"));
96 _("off: Debug output will go to both the screen and the log file.\n"));
99 /* If we've pushed output files, close them and pop them. */
101 pop_output_files (void)
103 current_interp_set_logging (NULL
, false, false);
105 /* Stay consistent with handle_redirections. */
106 if (!current_uiout
->is_mi_like_p ())
107 current_uiout
->redirect (NULL
);
110 /* This is a helper for the `set logging' command. */
112 handle_redirections (int from_tty
)
114 if (!saved_filename
.empty ())
116 gdb_printf ("Already logging to %s.\n",
117 saved_filename
.c_str ());
121 stdio_file_up
log (new no_terminal_escape_file ());
122 if (!log
->open (logging_filename
.c_str (), logging_overwrite
? "w" : "a"))
123 perror_with_name (_("set logging"));
125 /* Redirects everything to gdb_stdout while this is running. */
128 if (!logging_redirect
)
129 gdb_printf ("Copying output to %s.\n",
130 logging_filename
.c_str ());
132 gdb_printf ("Redirecting output to %s.\n",
133 logging_filename
.c_str ());
136 gdb_printf ("Copying debug output to %s.\n",
137 logging_filename
.c_str ());
139 gdb_printf ("Redirecting debug output to %s.\n",
140 logging_filename
.c_str ());
143 saved_filename
= logging_filename
;
145 /* Let the interpreter do anything it needs. */
146 current_interp_set_logging (std::move (log
), logging_redirect
,
149 /* Redirect the current ui-out object's output to the log. Use
150 gdb_stdout, not log, since the interpreter may have created a tee
151 that wraps the log. Don't do the redirect for MI, it confuses
152 MI's ui-out scheme. Note that we may get here with MI as current
153 interpreter, but with the current ui_out as a CLI ui_out, with
154 '-interpreter-exec console "set logging on"'. */
155 if (!current_uiout
->is_mi_like_p ())
156 current_uiout
->redirect (gdb_stdout
);
160 set_logging_on (const char *args
, int from_tty
)
162 const char *rest
= args
;
165 logging_filename
= rest
;
167 handle_redirections (from_tty
);
171 set_logging_off (const char *args
, int from_tty
)
173 if (saved_filename
.empty ())
178 gdb_printf ("Done logging to %s.\n",
179 saved_filename
.c_str ());
180 saved_filename
.clear ();
183 static bool logging_enabled
;
186 set_logging_enabled (const char *args
,
187 int from_tty
, struct cmd_list_element
*c
)
190 set_logging_on (args
, from_tty
);
192 set_logging_off (args
, from_tty
);
196 show_logging_enabled (struct ui_file
*file
, int from_tty
,
197 struct cmd_list_element
*c
, const char *value
)
200 gdb_printf (file
, _("on: Logging is enabled.\n"));
202 gdb_printf (file
, _("off: Logging is disabled.\n"));
205 void _initialize_cli_logging ();
207 _initialize_cli_logging ()
209 static struct cmd_list_element
*set_logging_cmdlist
, *show_logging_cmdlist
;
211 /* Set/show logging. */
212 add_setshow_prefix_cmd ("logging", class_support
,
213 _("Set logging options."),
214 _("Show logging options."),
215 &set_logging_cmdlist
, &show_logging_cmdlist
,
216 &setlist
, &showlist
);
218 /* Set/show logging overwrite. */
219 add_setshow_boolean_cmd ("overwrite", class_support
, &logging_overwrite
, _("\
220 Set whether logging overwrites or appends to the log file."), _("\
221 Show whether logging overwrites or appends to the log file."), _("\
222 If set, logging overwrites the log file."),
223 set_logging_overwrite
,
224 show_logging_overwrite
,
225 &set_logging_cmdlist
, &show_logging_cmdlist
);
227 /* Set/show logging redirect. */
228 add_setshow_boolean_cmd ("redirect", class_support
, &logging_redirect
, _("\
229 Set the logging output mode."), _("\
230 Show the logging output mode."), _("\
231 If redirect is off, output will go to both the screen and the log file.\n\
232 If redirect is on, output will go only to the log file."),
233 set_logging_redirect
,
234 show_logging_redirect
,
235 &set_logging_cmdlist
, &show_logging_cmdlist
);
237 /* Set/show logging debugredirect. */
238 add_setshow_boolean_cmd ("debugredirect", class_support
,
239 &debug_redirect
, _("\
240 Set the logging debug output mode."), _("\
241 Show the logging debug output mode."), _("\
242 If debug redirect is off, debug will go to both the screen and the log file.\n\
243 If debug redirect is on, debug will go only to the log file."),
244 set_logging_redirect
,
245 show_logging_debug_redirect
,
246 &set_logging_cmdlist
, &show_logging_cmdlist
);
248 /* Set/show logging file. */
249 add_setshow_filename_cmd ("file", class_support
, &logging_filename
, _("\
250 Set the current logfile."), _("\
251 Show the current logfile."), _("\
252 The logfile is used when directing GDB's output."),
254 show_logging_filename
,
255 &set_logging_cmdlist
, &show_logging_cmdlist
);
257 /* Set/show logging enabled. */
258 set_show_commands setshow_logging_enabled_cmds
259 = add_setshow_boolean_cmd ("enabled", class_support
, &logging_enabled
,
260 _("Enable logging."),
261 _("Show whether logging is enabled."),
262 _("When on, enable logging."),
264 show_logging_enabled
,
265 &set_logging_cmdlist
, &show_logging_cmdlist
);
267 /* Set logging on, deprecated alias. */
268 cmd_list_element
*set_logging_on_cmd
269 = add_alias_cmd ("on", setshow_logging_enabled_cmds
.set
, class_support
,
270 false, &set_logging_cmdlist
);
271 deprecate_cmd (set_logging_on_cmd
, "set logging enabled on");
272 set_logging_on_cmd
->default_args
= "on";
274 /* Set logging off, deprecated alias. */
275 cmd_list_element
*set_logging_off_cmd
276 = add_alias_cmd ("off", setshow_logging_enabled_cmds
.set
, class_support
,
277 false, &set_logging_cmdlist
);
278 deprecate_cmd (set_logging_off_cmd
, "set logging enabled off");
279 set_logging_off_cmd
->default_args
= "off";