| OLD | NEW |
| 1 /* Command-line output logging for GDB, the GNU debugger. | 1 /* Command-line output logging for GDB, the GNU debugger. |
| 2 | 2 |
| 3 Copyright (c) 2003-2004, 2007-2012 Free Software Foundation, Inc. | 3 Copyright (c) 2003-2004, 2007-2012 Free Software Foundation, Inc. |
| 4 | 4 |
| 5 This file is part of GDB. | 5 This file is part of GDB. |
| 6 | 6 |
| 7 This program is free software; you can redistribute it and/or modify | 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 | 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 | 9 the Free Software Foundation; either version 3 of the License, or |
| 10 (at your option) any later version. | 10 (at your option) any later version. |
| 11 | 11 |
| 12 This program is distributed in the hope that it will be useful, | 12 This program is distributed in the hope that it will be useful, |
| 13 but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 GNU General Public License for more details. | 15 GNU General Public License for more details. |
| 16 | 16 |
| 17 You should have received a copy of the GNU General Public License | 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/>. */ | 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| 19 | 19 |
| 20 #include "defs.h" | 20 #include "defs.h" |
| 21 #include "gdbcmd.h" | 21 #include "gdbcmd.h" |
| 22 #include "ui-out.h" | 22 #include "ui-out.h" |
| 23 #include "interps.h" |
| 23 #include "gdb_assert.h" | 24 #include "gdb_assert.h" |
| 24 | 25 |
| 25 #include "gdb_string.h" | 26 #include "gdb_string.h" |
| 26 | 27 |
| 27 /* These hold the pushed copies of the gdb output files. | 28 /* These hold the pushed copies of the gdb output files. |
| 28 If NULL then nothing has yet been pushed. */ | 29 If NULL then nothing has yet been pushed. */ |
| 29 struct saved_output_files | 30 struct saved_output_files |
| 30 { | 31 { |
| 31 struct ui_file *out; | 32 struct ui_file *out; |
| 32 struct ui_file *err; | 33 struct ui_file *err; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 output = tee_file_new (saved_output.out, 0, gdb_stdout, 0); | 109 output = tee_file_new (saved_output.out, 0, gdb_stdout, 0); |
| 109 if (output == NULL) | 110 if (output == NULL) |
| 110 perror_with_name (_("set logging")); | 111 perror_with_name (_("set logging")); |
| 111 new_logging_no_redirect_file = gdb_stdout; | 112 new_logging_no_redirect_file = gdb_stdout; |
| 112 | 113 |
| 113 if (from_tty) | 114 if (from_tty) |
| 114 fprintf_unfiltered (saved_output.out, "Copying output to %s.\n", | 115 fprintf_unfiltered (saved_output.out, "Copying output to %s.\n", |
| 115 logging_filename); | 116 logging_filename); |
| 116 } | 117 } |
| 117 | 118 |
| 118 gdb_stdout = output; | 119 /* Give the current interpreter a chance to do anything special that |
| 119 gdb_stderr = output; | 120 it might need for logging, such as updating other channels. */ |
| 120 gdb_stdlog = output; | 121 if (current_interp_set_logging (1, output, NULL) == 0) |
| 121 gdb_stdtarg = output; | 122 { |
| 122 gdb_stdtargerr = output; | 123 gdb_stdout = output; |
| 124 gdb_stdlog = output; |
| 125 gdb_stderr = output; |
| 126 gdb_stdtarg = output; |
| 127 gdb_stdtargerr = output; |
| 128 } |
| 129 |
| 123 logging_no_redirect_file = new_logging_no_redirect_file; | 130 logging_no_redirect_file = new_logging_no_redirect_file; |
| 124 | 131 |
| 125 /* There is a former output pushed on the ui_out_redirect stack. We | 132 /* There is a former output pushed on the ui_out_redirect stack. We |
| 126 want to replace it by OUTPUT so we must pop the former value | 133 want to replace it by OUTPUT so we must pop the former value |
| 127 first. We should either do both the pop and push or to do | 134 first. We should either do both the pop and push or to do |
| 128 neither of it. At least do not try to push OUTPUT if the pop | 135 neither of it. At least do not try to push OUTPUT if the pop |
| 129 already failed. */ | 136 already failed. */ |
| 130 | 137 |
| 131 if (ui_out_redirect (uiout, NULL) < 0 | 138 if (ui_out_redirect (uiout, NULL) < 0 |
| 132 || ui_out_redirect (uiout, output) < 0) | 139 || ui_out_redirect (uiout, output) < 0) |
| 133 warning (_("Current output protocol does not support redirection")); | 140 warning (_("Current output protocol does not support redirection")); |
| 134 | 141 |
| 135 if (logging_redirect != 0) | 142 if (logging_redirect != 0) |
| 136 do_cleanups (cleanups); | 143 do_cleanups (cleanups); |
| 137 } | 144 } |
| 138 | 145 |
| 139 static void | 146 static void |
| 140 show_logging_redirect (struct ui_file *file, int from_tty, | 147 show_logging_redirect (struct ui_file *file, int from_tty, |
| 141 struct cmd_list_element *c, const char *value) | 148 struct cmd_list_element *c, const char *value) |
| 142 { | 149 { |
| 143 fprintf_filtered (file, _("The logging output mode is %s.\n"), value); | 150 fprintf_filtered (file, _("The logging output mode is %s.\n"), value); |
| 144 } | 151 } |
| 145 | 152 |
| 146 /* If we've pushed output files, close them and pop them. */ | 153 /* If we've pushed output files, close them and pop them. */ |
| 147 static void | 154 static void |
| 148 pop_output_files (void) | 155 pop_output_files (void) |
| 149 { | 156 { |
| 150 /* Only delete one of the files -- they are all set to the same | |
| 151 value. */ | |
| 152 ui_file_delete (gdb_stdout); | |
| 153 if (logging_no_redirect_file) | 157 if (logging_no_redirect_file) |
| 154 { | 158 { |
| 155 ui_file_delete (logging_no_redirect_file); | 159 ui_file_delete (logging_no_redirect_file); |
| 156 logging_no_redirect_file = NULL; | 160 logging_no_redirect_file = NULL; |
| 157 } | 161 } |
| 158 gdb_stdout = saved_output.out; | 162 |
| 159 gdb_stderr = saved_output.err; | 163 if (current_interp_set_logging (0, NULL, NULL) == 0) |
| 160 gdb_stdlog = saved_output.log; | 164 { |
| 161 gdb_stdtarg = saved_output.targ; | 165 /* Only delete one of the files -- they are all set to the same |
| 162 gdb_stdtargerr = saved_output.targ; | 166 » value. */ |
| 167 ui_file_delete (gdb_stdout); |
| 168 |
| 169 gdb_stdout = saved_output.out; |
| 170 gdb_stderr = saved_output.err; |
| 171 gdb_stdlog = saved_output.log; |
| 172 gdb_stdtarg = saved_output.targ; |
| 173 gdb_stdtargerr = saved_output.targ; |
| 174 } |
| 175 |
| 163 saved_output.out = NULL; | 176 saved_output.out = NULL; |
| 164 saved_output.err = NULL; | 177 saved_output.err = NULL; |
| 165 saved_output.log = NULL; | 178 saved_output.log = NULL; |
| 166 saved_output.targ = NULL; | 179 saved_output.targ = NULL; |
| 167 saved_output.targerr = NULL; | 180 saved_output.targerr = NULL; |
| 168 | 181 |
| 169 ui_out_redirect (current_uiout, NULL); | 182 ui_out_redirect (current_uiout, NULL); |
| 170 } | 183 } |
| 171 | 184 |
| 172 /* This is a helper for the `set logging' command. */ | 185 /* This is a helper for the `set logging' command. */ |
| 173 static void | 186 static void |
| 174 handle_redirections (int from_tty) | 187 handle_redirections (int from_tty) |
| 175 { | 188 { |
| 176 struct cleanup *cleanups; | 189 struct cleanup *cleanups; |
| 177 struct ui_file *output; | 190 struct ui_file *output; |
| 191 struct ui_file *no_redirect_file = NULL; |
| 178 | 192 |
| 179 if (saved_filename != NULL) | 193 if (saved_filename != NULL) |
| 180 { | 194 { |
| 181 fprintf_unfiltered (gdb_stdout, "Already logging to %s.\n", | 195 fprintf_unfiltered (gdb_stdout, "Already logging to %s.\n", |
| 182 saved_filename); | 196 saved_filename); |
| 183 return; | 197 return; |
| 184 } | 198 } |
| 185 | 199 |
| 186 output = gdb_fopen (logging_filename, logging_overwrite ? "w" : "a"); | 200 output = gdb_fopen (logging_filename, logging_overwrite ? "w" : "a"); |
| 187 if (output == NULL) | 201 if (output == NULL) |
| 188 perror_with_name (_("set logging")); | 202 perror_with_name (_("set logging")); |
| 189 cleanups = make_cleanup_ui_file_delete (output); | 203 cleanups = make_cleanup_ui_file_delete (output); |
| 190 | 204 |
| 191 /* Redirects everything to gdb_stdout while this is running. */ | 205 /* Redirects everything to gdb_stdout while this is running. */ |
| 192 if (!logging_redirect) | 206 if (!logging_redirect) |
| 193 { | 207 { |
| 194 struct ui_file *no_redirect_file = output; | 208 no_redirect_file = output; |
| 195 | 209 |
| 196 output = tee_file_new (gdb_stdout, 0, no_redirect_file, 0); | 210 output = tee_file_new (gdb_stdout, 0, no_redirect_file, 0); |
| 197 if (output == NULL) | 211 if (output == NULL) |
| 198 perror_with_name (_("set logging")); | 212 perror_with_name (_("set logging")); |
| 199 make_cleanup_ui_file_delete (output); | 213 make_cleanup_ui_file_delete (output); |
| 200 if (from_tty) | 214 if (from_tty) |
| 201 fprintf_unfiltered (gdb_stdout, "Copying output to %s.\n", | 215 fprintf_unfiltered (gdb_stdout, "Copying output to %s.\n", |
| 202 logging_filename); | 216 logging_filename); |
| 203 logging_no_redirect_file = no_redirect_file; | 217 logging_no_redirect_file = no_redirect_file; |
| 204 } | 218 } |
| 205 else | 219 else |
| 206 { | 220 { |
| 207 gdb_assert (logging_no_redirect_file == NULL); | 221 gdb_assert (logging_no_redirect_file == NULL); |
| 208 | 222 |
| 209 if (from_tty) | 223 if (from_tty) |
| 210 fprintf_unfiltered (gdb_stdout, "Redirecting output to %s.\n", | 224 fprintf_unfiltered (gdb_stdout, "Redirecting output to %s.\n", |
| 211 logging_filename); | 225 logging_filename); |
| 212 } | 226 } |
| 213 | 227 |
| 214 discard_cleanups (cleanups); | 228 discard_cleanups (cleanups); |
| 215 | 229 |
| 216 saved_filename = xstrdup (logging_filename); | 230 saved_filename = xstrdup (logging_filename); |
| 217 saved_output.out = gdb_stdout; | 231 saved_output.out = gdb_stdout; |
| 218 saved_output.err = gdb_stderr; | 232 saved_output.err = gdb_stderr; |
| 219 saved_output.log = gdb_stdlog; | 233 saved_output.log = gdb_stdlog; |
| 220 saved_output.targ = gdb_stdtarg; | 234 saved_output.targ = gdb_stdtarg; |
| 221 saved_output.targerr = gdb_stdtargerr; | 235 saved_output.targerr = gdb_stdtargerr; |
| 222 | 236 |
| 223 gdb_stdout = output; | 237 /* Let the interpreter do anything it needs. */ |
| 224 gdb_stderr = output; | 238 if (current_interp_set_logging (1, output, no_redirect_file) == 0) |
| 225 gdb_stdlog = output; | 239 { |
| 226 gdb_stdtarg = output; | 240 gdb_stdout = output; |
| 227 gdb_stdtargerr = output; | 241 gdb_stdlog = output; |
| 242 gdb_stderr = output; |
| 243 gdb_stdtarg = output; |
| 244 gdb_stdtargerr = output; |
| 245 } |
| 228 | 246 |
| 229 if (ui_out_redirect (current_uiout, output) < 0) | 247 /* Don't do the redirect for MI, it confuses MI's ui-out scheme. */ |
| 230 warning (_("Current output protocol does not support redirection")); | 248 if (!ui_out_is_mi_like_p (current_uiout)) |
| 249 { |
| 250 if (ui_out_redirect (current_uiout, output) < 0) |
| 251 » warning (_("Current output protocol does not support redirection")); |
| 252 } |
| 231 } | 253 } |
| 232 | 254 |
| 233 static void | 255 static void |
| 234 set_logging_on (char *args, int from_tty) | 256 set_logging_on (char *args, int from_tty) |
| 235 { | 257 { |
| 236 char *rest = args; | 258 char *rest = args; |
| 237 | 259 |
| 238 if (rest && *rest) | 260 if (rest && *rest) |
| 239 { | 261 { |
| 240 xfree (logging_filename); | 262 xfree (logging_filename); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 NULL, | 356 NULL, |
| 335 show_logging_filename, | 357 show_logging_filename, |
| 336 &set_logging_cmdlist, &show_logging_cmdlist); | 358 &set_logging_cmdlist, &show_logging_cmdlist); |
| 337 add_cmd ("on", class_support, set_logging_on, | 359 add_cmd ("on", class_support, set_logging_on, |
| 338 _("Enable logging."), &set_logging_cmdlist); | 360 _("Enable logging."), &set_logging_cmdlist); |
| 339 add_cmd ("off", class_support, set_logging_off, | 361 add_cmd ("off", class_support, set_logging_off, |
| 340 _("Disable logging."), &set_logging_cmdlist); | 362 _("Disable logging."), &set_logging_cmdlist); |
| 341 | 363 |
| 342 logging_filename = xstrdup ("gdb.txt"); | 364 logging_filename = xstrdup ("gdb.txt"); |
| 343 } | 365 } |
| OLD | NEW |