aboutsummaryrefslogtreecommitdiff
path: root/gdb/interps.c
diff options
context:
space:
mode:
authorPeter Waller <p@pwaller.net>2020-12-21 09:38:07 -0500
committerSimon Marchi <simon.marchi@polymtl.ca>2020-12-21 09:38:22 -0500
commite1ff6226d8e36896edbdd651753a3e1292381ba0 (patch)
treec30ef5fba5cf64bd5d6ae951132b0b2880643623 /gdb/interps.c
parentca01f1bf3d9e5f5bcddf72bd83f574395e859d1c (diff)
downloadbinutils-e1ff6226d8e36896edbdd651753a3e1292381ba0.zip
binutils-e1ff6226d8e36896edbdd651753a3e1292381ba0.tar.gz
binutils-e1ff6226d8e36896edbdd651753a3e1292381ba0.tar.bz2
Preserve gdb_std{out, err, log, targ, targerr} across interpreter_exec_cmd
Calls through interpreter_exec_cmd can cause the output state to be modified in a way which doesn't get back after the execution. It looks like the intent is that interp::resume should put things back how they should be, however, mi_interp::resume modifies gdb_stdout and nothing currently restores it to the previous state. To see the broken behaviour: gdb -ex starti -ex bt -ex 'interpreter-exec mi echo' -ex bt -ex q echo <<<'' Prior to this patch, on a terminal environment, the first backtrace is coloured, and the second backtrace is not. The reason is that stdio_file::can_emit_style_escape becomes false, because the gdb_stdout gets overwritten in mi_interp::resume and not replaced. gdb/ChangeLog: * interps.c (interpreter_exec_cmd): Restore streams pointers. gdb/testsuite/ChangeLog: * gdb.base/style-interp-exec-mi.exp: New. * gdb.base/style-interp-exec-mi.c: New. Signed-off-by: Peter Waller <p@pwaller.net> Change-Id: Id87423b262d058857ea9dca5866ca6471741e512
Diffstat (limited to 'gdb/interps.c')
-rw-r--r--gdb/interps.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/gdb/interps.c b/gdb/interps.c
index 4b2e3fd..e186a73 100644
--- a/gdb/interps.c
+++ b/gdb/interps.c
@@ -370,6 +370,14 @@ interpreter_exec_cmd (const char *args, int from_tty)
unsigned int nrules;
unsigned int i;
+ /* Interpreters may clobber stdout/stderr (e.g. in mi_interp::resume at time
+ of writing), preserve their state here. */
+ scoped_restore save_stdout = make_scoped_restore (&gdb_stdout);
+ scoped_restore save_stderr = make_scoped_restore (&gdb_stderr);
+ scoped_restore save_stdlog = make_scoped_restore (&gdb_stdlog);
+ scoped_restore save_stdtarg = make_scoped_restore (&gdb_stdtarg);
+ scoped_restore save_stdtargerr = make_scoped_restore (&gdb_stdtargerr);
+
if (args == NULL)
error_no_arg (_("interpreter-exec command"));