aboutsummaryrefslogtreecommitdiff
path: root/gdb/mi/mi-interp.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2017-02-02 22:00:43 +0000
committerPedro Alves <palves@redhat.com>2017-02-02 22:00:43 +0000
commit616268b639780e0819b51053c794037bcde3de16 (patch)
tree8d12ec88f6482a508d9410f9554cfc099b2d0ac6 /gdb/mi/mi-interp.c
parent5be5dbf0ce3d2eb20003fea3691eaa6bfa5710d2 (diff)
downloadgdb-616268b639780e0819b51053c794037bcde3de16.zip
gdb-616268b639780e0819b51053c794037bcde3de16.tar.gz
gdb-616268b639780e0819b51053c794037bcde3de16.tar.bz2
Move "tee" building down to interpreter::set_logging_proc
This patch gets rid of this hack in mi_set_logging: /* The tee created already is based on gdb_stdout, which for MI is a console and so we end up in an infinite loop of console writing to ui_file writing to console etc. So discard the existing tee (it hasn't been used yet, and MI won't ever use it), and create one based on raw_stdout instead. */ By pushing down responsibility for the tee creation to the interpreter. I.e., pushing the CLI bits out of handle_redirections down to the CLI interpreter's set_logging_proc method. This fixes a few leaks that I spotted, and then confirmed with "valgrind --leak-check=full": [...] ==21429== 56 (32 direct, 24 indirect) bytes in 1 blocks are definitely lost in loss record 30,243 of 34,980 ==21429== at 0x4C29216: operator new(unsigned long) (vg_replace_malloc.c:334) ==21429== by 0x62D9A9: mi_set_logging(interp*, int, ui_file*, ui_file*) (mi-interp.c:1395) ==21429== by 0x810B8A: current_interp_set_logging(int, ui_file*, ui_file*) (interps.c:360) ==21429== by 0x61C537: handle_redirections(int) (cli-logging.c:162) ==21429== by 0x61C6EC: set_logging_on(char*, int) (cli-logging.c:190) ==21429== by 0x6163BE: do_cfunc(cmd_list_element*, char*, int) (cli-decode.c:105) ==21429== by 0x6193C1: cmd_func(cmd_list_element*, char*, int) (cli-decode.c:1913) ==21429== by 0x8DB790: execute_command(char*, int) (top.c:674) ==21429== by 0x632AE6: mi_execute_cli_command(char const*, int, char const*) (mi-main.c:2343) ==21429== by 0x6329BA: mi_cmd_execute(mi_parse*) (mi-main.c:2306) ==21429== by 0x631E19: captured_mi_execute_command(ui_out*, mi_parse*) (mi-main.c:1998) ==21429== by 0x632389: mi_execute_command(char const*, int) (mi-main.c:2163) ==21429== [...] ==26635== 24 bytes in 1 blocks are definitely lost in loss record 20,740 of 34,995 ==26635== at 0x4C29216: operator new(unsigned long) (vg_replace_malloc.c:334) ==26635== by 0x61C355: handle_redirections(int) (cli-logging.c:131) ==26635== by 0x61C6EC: set_logging_on(char*, int) (cli-logging.c:190) ==26635== by 0x6163BE: do_cfunc(cmd_list_element*, char*, int) (cli-decode.c:105) ==26635== by 0x6193C1: cmd_func(cmd_list_element*, char*, int) (cli-decode.c:1913) ==26635== by 0x8DB7BC: execute_command(char*, int) (top.c:674) ==26635== by 0x7B9132: command_handler(char*) (event-top.c:590) ==26635== by 0x7B94F7: command_line_handler(char*) (event-top.c:780) ==26635== by 0x7B8ABB: gdb_rl_callback_handler(char*) (event-top.c:213) ==26635== by 0x933CE9: rl_callback_read_char (callback.c:220) ==26635== by 0x7B89ED: gdb_rl_callback_read_char_wrapper_noexcept() (event-top.c:175) ==26635== by 0x7B8A49: gdb_rl_callback_read_char_wrapper(void*) (event-top.c:192) One is fixed by transfering ownership of the log file to the tee. In pseudo-patch, since the code was moved at the same time: - out = new tee_file (curr_output, false, logfile.get (), false); + out = new tee_file (curr_output, false, logfile.get (), true); The other is this bit in mi_set_logging: else { + delete mi->raw_stdout; I tried to split the leak fixes to a smaller preparatory patch, but that was difficult exactly because of the tee hack in handle_redirections -> mi_set_logging. gdb/ChangeLog: 2017-02-02 Pedro Alves <palves@redhat.com> * cli/cli-interp.c (struct saved_output_files, saved_output): Moved from cli/cli-logging.c. (cli_set_logging): New function. (cli_interp_procs): Install cli_set_logging. * cli/cli-interp.h (make_logging_output, cli_set_logging): Declare. * cli/cli-logging.c (struct saved_output_files, saved_output): Moved to cli/cli-interp.c. (pop_output_files): Don't save outputs here. (make_logging_output): New function. (handle_redirections): Don't build tee nor save previous outputs here. * interps.c (current_interp_set_logging): Change prototype. Assume there's always a set_logging_proc method installed. * interps.h (interp_set_logging_ftype): Change prototype. (current_interp_set_logging): Change prototype and adjust comment. * mi/mi-interp.c (mi_set_logging): Change protototype. Adjust to use make_logging_output. * tui/tui-interp.c (tui_interp_procs): Install cli_set_logging.
Diffstat (limited to 'gdb/mi/mi-interp.c')
-rw-r--r--gdb/mi/mi-interp.c30
1 files changed, 10 insertions, 20 deletions
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index f167a53..aa76989 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -1373,33 +1373,25 @@ mi_ui_out (struct interp *interp)
/* Do MI-specific logging actions; save raw_stdout, and change all
the consoles to use the supplied ui-file(s). */
-static int
-mi_set_logging (struct interp *interp, int start_log,
- struct ui_file *out, struct ui_file *logfile)
+static void
+mi_set_logging (struct interp *interp,
+ ui_file_up logfile, bool logging_redirect)
{
struct mi_interp *mi = (struct mi_interp *) interp_data (interp);
- if (!mi)
- return 0;
+ gdb_assert (mi != NULL);
- if (start_log)
+ if (logfile != NULL)
{
- /* The tee created already is based on gdb_stdout, which for MI
- is a console and so we end up in an infinite loop of console
- writing to ui_file writing to console etc. So discard the
- existing tee (it hasn't been used yet, and MI won't ever use
- it), and create one based on raw_stdout instead. */
- if (logfile)
- {
- delete out;
- out = new tee_file (mi->raw_stdout, false, logfile, false);
- }
-
mi->saved_raw_stdout = mi->raw_stdout;
- mi->raw_stdout = out;
+ mi->raw_stdout = make_logging_output (mi->raw_stdout,
+ std::move (logfile),
+ logging_redirect);
+
}
else
{
+ delete mi->raw_stdout;
mi->raw_stdout = mi->saved_raw_stdout;
mi->saved_raw_stdout = NULL;
}
@@ -1409,8 +1401,6 @@ mi_set_logging (struct interp *interp, int start_log,
mi->log->set_raw (mi->raw_stdout);
mi->targ->set_raw (mi->raw_stdout);
mi->event_channel->set_raw (mi->raw_stdout);
-
- return 1;
}
/* The MI interpreter's vtable. */