diff options
author | Pedro Alves <palves@redhat.com> | 2017-02-02 22:00:43 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2017-02-02 22:00:43 +0000 |
commit | 616268b639780e0819b51053c794037bcde3de16 (patch) | |
tree | 8d12ec88f6482a508d9410f9554cfc099b2d0ac6 /gdb/mi/mi-interp.c | |
parent | 5be5dbf0ce3d2eb20003fea3691eaa6bfa5710d2 (diff) | |
download | gdb-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.c | 30 |
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. */ |