* [PATCH 2/4] GDB/MI: fix and simplify mi_valid_noargs utility function
2015-10-05 11:47 [PATCH 0/4]: GDB: inferior standard I/O redirection Cleber Rosa
2015-10-05 11:47 ` [PATCH 1/4] " Cleber Rosa
2015-10-05 11:47 ` [PATCH 3/4] GDB/MI: add test for command -inferior-tty-show Cleber Rosa
@ 2015-10-05 11:47 ` Cleber Rosa
2015-10-21 11:19 ` Pedro Alves
2015-10-05 11:54 ` [PATCH 4/4] GDB/MI: inferior standard I/O redirection Cleber Rosa
3 siblings, 1 reply; 12+ messages in thread
From: Cleber Rosa @ 2015-10-05 11:47 UTC (permalink / raw)
To: gdb-patches; +Cc: areis, palves, Cleber Rosa
This function was supposed to check if a command that takes no
arguments was called appropriately, that is, without any arguments.
Turns out that the implementation, relying on mi_getopt, would always
return -1, either because:
* no argument was given, then the option index (*oind) would be equal
to the argument count (argc)
* the argument given did not start with a dash (arg[0] != '-')
If the command should take no arguments, then it should be OK to just
check the given argument count.
gdb/ChangeLog:
2015-10-05 Cleber Rosa <crosa@redhat.com>
* mi/mi-getopt.c (mi_valid_noargs): Simplify/fix the function by
looking at the argument count.
---
gdb/mi/mi-getopt.c | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/gdb/mi/mi-getopt.c b/gdb/mi/mi-getopt.c
index 0a07a39..574ccd2 100644
--- a/gdb/mi/mi-getopt.c
+++ b/gdb/mi/mi-getopt.c
@@ -95,18 +95,14 @@ mi_getopt_allow_unknown (const char *prefix, int argc, char **argv,
return mi_getopt_1 (prefix, argc, argv, opts, oind, oarg, 0);
}
+/* Tests if a command that takes no arguments was properly used.
+ Returns 1 if no options were given, otherwise return 0. */
+
int
mi_valid_noargs (const char *prefix, int argc, char **argv)
{
- int oind = 0;
- char *oarg;
- static const struct mi_opt opts[] =
- {
- { 0, 0, 0 }
- };
-
- if (mi_getopt (prefix, argc, argv, opts, &oind, &oarg) == -1)
- return 1;
- else
+ if (argc > 0)
return 0;
+
+ return 1;
}
--
2.4.3
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 3/4] GDB/MI: add test for command -inferior-tty-show
2015-10-05 11:47 [PATCH 0/4]: GDB: inferior standard I/O redirection Cleber Rosa
2015-10-05 11:47 ` [PATCH 1/4] " Cleber Rosa
@ 2015-10-05 11:47 ` Cleber Rosa
2015-10-21 11:19 ` Pedro Alves
2015-10-05 11:47 ` [PATCH 2/4] GDB/MI: fix and simplify mi_valid_noargs utility function Cleber Rosa
2015-10-05 11:54 ` [PATCH 4/4] GDB/MI: inferior standard I/O redirection Cleber Rosa
3 siblings, 1 reply; 12+ messages in thread
From: Cleber Rosa @ 2015-10-05 11:47 UTC (permalink / raw)
To: gdb-patches; +Cc: areis, palves, Cleber Rosa
Simple test that gives arguments to a command that should take none.
gdb/testsuite/ChangeLog:
2015-10-05 Cleber Rosa <crosa@redhat.com>
* gdb.mi/mi-basics.exp: Added test for inferior-tty-show with
arguments when it should take none.
---
gdb/testsuite/gdb.mi/mi-basics.exp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/gdb/testsuite/gdb.mi/mi-basics.exp b/gdb/testsuite/gdb.mi/mi-basics.exp
index 0cc24ac..476dbdc 100644
--- a/gdb/testsuite/gdb.mi/mi-basics.exp
+++ b/gdb/testsuite/gdb.mi/mi-basics.exp
@@ -258,6 +258,10 @@ proc test_setshow_inferior_tty {} {
mi_gdb_test "307-inferior-tty-show" \
"307\\\^done,inferior_tty_terminal=\"$mi_inferior_tty_name\"" \
"verify tty is correct"
+
+ mi_gdb_test "308-inferior-tty-show should-take-no-args" \
+ "308\\\^error,msg=\"-inferior-tty-show: Usage: No args\"" \
+ "make sure show takes no arguments"
}
if { [test_mi_interpreter_selection]
--
2.4.3
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 0/4]: GDB: inferior standard I/O redirection
@ 2015-10-05 11:47 Cleber Rosa
2015-10-05 11:47 ` [PATCH 1/4] " Cleber Rosa
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Cleber Rosa @ 2015-10-05 11:47 UTC (permalink / raw)
To: gdb-patches; +Cc: areis, palves
GDB currently relies on shell capabilities to implement the
redirection of standard I/O[1]. This is limited and may conflict with
situations where the shell is not wanted at all.
These patches implement commands at the CLI and MI level that allow
the user to select each of the streams (input, output and error) that
they may want to have redirected while running their inferior process.
This happens to be a feature needed for the Avocado[2] test
framework, which has some interesting integration capabilities with
GDB.
This is a followup of the response for a RFC sent back in May/2015[3].
[1] - https://sourceware.org/gdb/current/onlinedocs/gdb/Input_002fOutput.html#Input_002fOutput
[2] - http://avocado-framework.github.io/
[3] - https://sourceware.org/ml/gdb-patches/2015-05/msg00131.html
Series summary:
[PATCH 1/4] GDB: inferior standard I/O redirection
[PATCH 2/4] GDB/MI: fix and simplify mi_valid_noargs utility function
[PATCH 3/4] GDB/MI: add test for command -inferior-tty-show
[PATCH 4/4] GDB/MI: inferior standard I/O redirection
Series diff stat:
gdb/NEWS | 15 ++++
gdb/doc/gdb.texinfo | 250 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
gdb/fork-child.c | 81 ++++++++++++++++++++
gdb/infcmd.c | 146 +++++++++++++++++++++++++++++++++++
gdb/inferior.c | 3 +
gdb/inferior.h | 11 +++
gdb/mi/mi-cmd-env.c | 77 +++++++++++++++++++
gdb/mi/mi-cmds.c | 6 ++
gdb/mi/mi-cmds.h | 6 ++
gdb/mi/mi-getopt.c | 16 ++--
gdb/testsuite/gdb.base/default.exp | 6 ++
gdb/testsuite/gdb.mi/mi-basics.exp | 66 ++++++++++++++++
12 files changed, 655 insertions(+), 28 deletions(-)
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/4] GDB: inferior standard I/O redirection
2015-10-05 11:47 [PATCH 0/4]: GDB: inferior standard I/O redirection Cleber Rosa
@ 2015-10-05 11:47 ` Cleber Rosa
2015-10-05 12:23 ` Eli Zaretskii
2015-10-21 11:18 ` Pedro Alves
2015-10-05 11:47 ` [PATCH 3/4] GDB/MI: add test for command -inferior-tty-show Cleber Rosa
` (2 subsequent siblings)
3 siblings, 2 replies; 12+ messages in thread
From: Cleber Rosa @ 2015-10-05 11:47 UTC (permalink / raw)
To: gdb-patches; +Cc: areis, palves, Cleber Rosa
This introduces a set of commands:
* set inferior-stdin (aliased as stdin)
* set inferior-stdout (aliased as stdout)
* set inferior-stderr (aliased as stderr)
Those commands complement the "set inferior-tty" command, also
allowing the inferior standard I/O to be defined before the inferior
itself is started.
This is useful in a number of situations, including when shell based
redirection (the only current way to do it) is not desirable.
gdb/doc/ChangeLog:
2015-10-05 Cleber Rosa <crosa@redhat.com>
* gdb.texinfo (info): Added section on commands stdin, stdout and
stderr
gdb/ChangeLog:
2015-10-05 Cleber Rosa <crosa@redhat.com>
* NEWS: New commands in gdb: set inferior-stdin (aliased as
stdin), set inferior-stdout (aliased as stdout) and set
inferior-stderr (aliased as stderr).
* fork-child.c (set_std_io_helper): New utility function.
* infcmd.c: Added inferior_io_std_scratch array.
(set_inferior_io_helper): New utility function.
(set_inferior_io_stdin): New function.
(get_inferior_io_stdin): Likewise.
(set_inferior_io_stdin_command): Likewise.
(show_inferior_io_stdin_command): Likewise.
(set_inferior_io_stdout): Likewise.
(get_inferior_io_stdout): Likewise.
(set_inferior_io_stdout_command): Likewise.
(show_inferior_io_stdout_command): Likewise.
(set_inferior_io_stderr): Likewise.
(get_inferior_io_stderr): Likewise.
(set_inferior_io_stderr_command): Likewise.
(show_inferior_io_stderr_command): Likewise.
(get_inferior_args): Added inferior-stdin/stdin,
inferior-stdout/stdout and inferior-stderr/stderr commands.
* inferior.c (free_inferior): Free inferior standard_io.
* inferior.h (set_inferior_io_stdin): New declaration.
(get_inferior_io_stdin): Likewise.
(set_inferior_io_stdout): Likewise.
(get_inferior_io_stdout): Likewise.
(set_inferior_io_stderr): Likewise.
(get_inferior_io_stderr): Likewise.
(struct inferior): <inferior_io>: New field.
gdb/testsuite/ChangeLog:
2015-10-05 Cleber Rosa <crosa@redhat.com>
* gdb.base/default.exp: New tests for stdin, stdout and stderr
commands.
---
gdb/NEWS | 15 ++++
gdb/doc/gdb.texinfo | 97 +++++++++++++++++++-----
gdb/fork-child.c | 81 ++++++++++++++++++++
gdb/infcmd.c | 146 +++++++++++++++++++++++++++++++++++++
gdb/inferior.c | 3 +
gdb/inferior.h | 11 +++
gdb/testsuite/gdb.base/default.exp | 6 ++
7 files changed, 341 insertions(+), 18 deletions(-)
diff --git a/gdb/NEWS b/gdb/NEWS
index 2e38d9a..07bd4db 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -42,6 +42,21 @@ set remote multiprocess-extensions-packet
show remote multiprocess-extensions-packet
Set/show the use of the remote protocol multiprocess extensions.
+set inferior-stdin
+stdin
+show inferior-stdin
+ Set/show the standard input for the program being debugged.
+
+set inferior-stdout
+stdout
+show inferior-stdout
+ Set/show the standard output for the program being debugged.
+
+set inferior-stderr
+stderr
+show inferior-stderr
+ Set/show the standard error for the program being debugged.
+
* The "disassemble" command accepts a new modifier: /s.
It prints mixed source+disassembly like /m with two differences:
- disassembled instructions are now printed in program order, and
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 57e47b8..39d5a1c 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -2443,6 +2443,12 @@ current working directory of the debuggee.
@cindex redirection
@cindex i/o
@cindex terminal
+@value{GDBN} supports different ways of redirecting your program's
+input and output, including setting a specific terminal (a
+@code{tty}), individually setting standard input, output and error
+(@code{stdin}, @code{stdout} and @code{stderr}) or using shell based
+redirection (@code{run > output}).
+
By default, the program you run under @value{GDBN} does input and output to
the same terminal that @value{GDBN} uses. @value{GDBN} switches the terminal
to its own terminal modes to interact with you, but it records the terminal
@@ -2456,19 +2462,9 @@ Displays information recorded by @value{GDBN} about the terminal modes your
program is using.
@end table
-You can redirect your program's input and/or output using shell
-redirection with the @code{run} command. For example,
-
-@smallexample
-run > outfile
-@end smallexample
-
-@noindent
-starts your program, diverting its output to the file @file{outfile}.
-
@kindex tty
@cindex controlling terminal
-Another way to specify where your program should do input and output is
+One way to specify where your program should do input and output is
with the @code{tty} command. This command accepts a file name as
argument, and causes this file to be the default for future @code{run}
commands. It also resets the controlling terminal for the child
@@ -2483,14 +2479,17 @@ directs that processes started with subsequent @code{run} commands
default to do input and output on the terminal @file{/dev/ttyb} and have
that as their controlling terminal.
-An explicit redirection in @code{run} overrides the @code{tty} command's
-effect on the input/output device, but not its effect on the controlling
-terminal.
+An explicit redirection using either
+@code{stdin}/@code{stdout}/@code{stderr} or @code{run} overrides the
+@code{tty} command's effect on the input/output device, but not its
+effect on the controlling terminal.
-When you use the @code{tty} command or redirect input in the @code{run}
-command, only the input @emph{for your program} is affected. The input
-for @value{GDBN} still comes from your terminal. @code{tty} is an alias
-for @code{set inferior-tty}.
+When you use the @code{tty} command or redirect input using either
+@code{stdin}/@code{stdout}/@code{stderr} or the @code{run} command,
+only the input @emph{for your program} is affected. The input for
+@value{GDBN} still comes from your terminal and from the original
+standard I/O channels. @code{tty} is an alias for @code{set
+inferior-tty}.
@cindex inferior tty
@cindex set inferior controlling terminal
@@ -2508,6 +2507,68 @@ Set the tty for the program being debugged to /dev/ttyb.
Show the current tty for the program being debugged.
@end table
+@cindex inferior standard i/o
+@cindex set inferior standard i/o
+As mentioned before, you can also redirect your program's standard
+input, output and error individually with the @code{stdin},
+@code{stdout} and @code{stderr} commands. For example,
+
+@smallexample
+stdin /tmp/answers
+stdout /tmp/output
+stderr /dev/null
+@end smallexample
+
+@noindent
+will set your program's standard input (file descriptor number 0) to
+the @file{/tmp/answers}, the standard output (file description number
+1) to the @file{/tmp/output} and will silence the standard error (file
+descriptor number 2) by redirecting it to @file{/dev/null}.
+
+The @code{stdin}, @code{stdout} and @code{stderr} are actually aliases
+to the commands @code{set inferior-stdin}, @code{set inferior-stdout}
+and @code{set inferior-stderr}.
+
+@table @code
+@item set inferior-stdin /tmp/answers
+@kindex set inferior-stdin
+@kindex stdin
+Set the standard input for the program being debugged to /tmp/answers.
+
+@item show inferior-stdin
+@kindex show inferior-stdin
+Show the current standard input redirection for the program being debugged.
+
+@item set inferior-stdout /tmp/output
+@kindex set inferior-stdout
+@kindex stdout
+Set the standard output for the program being debugged to /tmp/output.
+
+@item show inferior-stdout
+@kindex show inferior-stdout
+Show the current standard output redirection for the program being debugged.
+
+@item set inferior-stderr /dev/null
+@kindex set inferior-stderr
+@kindex stderr
+Set the standard error for the program being debugged to /dev/null
+
+@item show inferior-error
+@kindex show inferior-error
+Show the current standard error redirection for the program being debugged.
+@end table
+
+@cindex inferior i/o shell based redirection
+Yet another way of doing redirection is by using the shell
+capabilities with the @code{run} command. For example,
+
+@smallexample
+run > outfile
+@end smallexample
+
+@noindent
+starts your program, diverting its output to the file @file{outfile}.
+
@node Attach
@section Debugging an Already-running Process
@kindex attach
diff --git a/gdb/fork-child.c b/gdb/fork-child.c
index 959f578..1b1bd47 100644
--- a/gdb/fork-child.c
+++ b/gdb/fork-child.c
@@ -108,6 +108,64 @@ escape_bang_in_quoted_argument (const char *shell_file)
return 0;
}
+/* Helper function that attempts to open a file and if successful
+ redirects another file descriptor to the one just opened. If
+ file_name is not given, this returns -1 as a simple way to flag
+ a skip (user has not asked for a redirection). Seems OK since
+ this is a helper function. */
+
+static int
+set_std_io_helper (const char *file_name, int std_io_fd, int flags, mode_t mode)
+{
+ int fd;
+
+ if (file_name == NULL)
+ return -1;
+
+ fd = open (file_name, flags, mode);
+ if (fd < 0)
+ return 0;
+
+ if (dup2 (fd, std_io_fd) == -1) {
+ close (fd);
+ return 0;
+ }
+
+ close (fd);
+ return 1;
+}
+
+/* Attempts to redirect stdin, stdout and stderr. If redirection was
+ not requested by the user, it will be skipped in the helper function.
+ In case of errors, each requested and failed redirection error will
+ be passed on for individual error reporting (no details such as
+ errno/perror though). */
+
+#define SET_STDIO_ERROR_STDIN 0x01
+#define SET_STDIO_ERROR_STDOUT 0x02
+#define SET_STDIO_ERROR_STDERR 0x04
+
+static int
+set_std_io (void)
+{
+ int result = 0;
+ char *file_name = NULL;
+
+ if (set_std_io_helper (get_inferior_io_stdin(), 0,
+ O_RDONLY, S_IRUSR | S_IWUSR) == 0)
+ result |= SET_STDIO_ERROR_STDIN;
+
+ if (set_std_io_helper (get_inferior_io_stdout(), 1,
+ O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR) == 0)
+ result |= SET_STDIO_ERROR_STDOUT;
+
+ if (set_std_io_helper (get_inferior_io_stderr(), 2,
+ O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR) == 0)
+ result |= SET_STDIO_ERROR_STDERR;
+
+ return result;
+}
+
/* Start an inferior Unix child process and sets inferior_ptid to its
pid. EXEC_FILE is the file to run. ALLARGS is a string containing
the arguments to the program. ENV is the environment vector to
@@ -141,6 +199,7 @@ fork_inferior (char *exec_file_arg, char *allargs, char **env,
struct inferior *inf;
int i;
int save_errno;
+ int io_redir_errors = 0;
/* If no exec file handed to us, get it from the exec-file command
-- with a good, common error message if none is specified. */
@@ -358,6 +417,28 @@ fork_inferior (char *exec_file_arg, char *allargs, char **env,
path to find $SHELL. Rich Pixley says so, and I agree. */
environ = env;
+ /* Sets the inferior process standard I/O (input, output, error)
+ redirection if set with the "set inferior std{in,out,err}"
+ commands. */
+ gdb_flush (gdb_stdout);
+ gdb_flush (gdb_stderr);
+ io_redir_errors = set_std_io();
+ if (io_redir_errors & SET_STDIO_ERROR_STDIN)
+ fprintf_unfiltered (gdb_stderr,
+ "Could not set %s as stdin for %s\n",
+ get_inferior_io_stdin(),
+ exec_file);
+ if (io_redir_errors & SET_STDIO_ERROR_STDOUT)
+ fprintf_unfiltered (gdb_stderr,
+ "Could not set %s as stdout for %s\n",
+ get_inferior_io_stdout(),
+ exec_file);
+ if (io_redir_errors & SET_STDIO_ERROR_STDERR)
+ fprintf_unfiltered (gdb_stderr,
+ "Could not set %s as stderr for %s\n",
+ get_inferior_io_stderr(),
+ exec_file);
+
if (exec_fun != NULL)
(*exec_fun) (argv[0], argv, env);
else
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 4713490..9941a98 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -115,6 +115,11 @@ static char *inferior_args_scratch;
static char *inferior_io_terminal_scratch;
+/* Scratch area where 'set inferior-{stdin,stdout,stderr}' will store
+ user provided value. */
+
+static char *inferior_io_std_scratch[3] = { NULL, NULL, NULL };
+
/* Pid of our debugged inferior, or 0 if no inferior now.
Since various parts of infrun.c test this to see whether there is a program
being debugged it should be nonzero (currently 3 is used) for remote
@@ -182,6 +187,117 @@ show_inferior_tty_command (struct ui_file *file, int from_tty,
"is \"%s\".\n"), inferior_io_terminal);
}
+static void
+set_inferior_io_helper (const char *file_name, int stdfd)
+{
+ gdb_assert (0 <= stdfd && stdfd <= 2);
+ xfree (current_inferior ()->standard_io[stdfd]);
+ current_inferior ()->standard_io[stdfd] =
+ file_name != NULL ? xstrdup (file_name) : NULL;
+}
+
+void
+set_inferior_io_stdin (const char *file_name)
+{
+ set_inferior_io_helper(file_name, 0);
+}
+
+const char *
+get_inferior_io_stdin (void)
+{
+ return current_inferior ()->standard_io[0];
+}
+
+static void
+set_inferior_stdin_command (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ set_inferior_io_stdin (inferior_io_std_scratch[0]);
+}
+
+static void
+show_inferior_stdin_command (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ /* Note that we ignore the passed-in value in favor of computing it
+ directly. */
+ const char *inferior_io_stdin = get_inferior_io_stdin ();
+
+ if (inferior_io_stdin == NULL)
+ inferior_io_stdin = "";
+ fprintf_filtered (gdb_stdout,
+ _("Standard input for future runs of program being "
+ "debugged is \"%s\".\n"), inferior_io_stdin);
+}
+
+void
+set_inferior_io_stdout (const char *file_name)
+{
+ set_inferior_io_helper(file_name, 1);
+}
+
+const char *
+get_inferior_io_stdout (void)
+{
+ return current_inferior ()->standard_io[1];
+}
+
+static void
+set_inferior_stdout_command (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ set_inferior_io_stdout (inferior_io_std_scratch[1]);
+}
+
+static void
+show_inferior_stdout_command (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ /* Note that we ignore the passed-in value in favor of computing it
+ directly. */
+ const char *inferior_io_stdout = get_inferior_io_stdout ();
+
+ if (inferior_io_stdout == NULL)
+ inferior_io_stdout = "";
+ fprintf_filtered (gdb_stdout,
+ _("Standard output for future runs of program being "
+ "debugged is \"%s\".\n"), inferior_io_stdout);
+}
+
+void
+set_inferior_io_stderr (const char *file_name)
+{
+ set_inferior_io_helper(file_name, 2);
+}
+
+const char *
+get_inferior_io_stderr (void)
+{
+ return current_inferior ()->standard_io[2];
+}
+
+static void
+set_inferior_stderr_command (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ set_inferior_io_stderr (inferior_io_std_scratch[2]);
+}
+
+static void
+show_inferior_stderr_command (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ /* Note that we ignore the passed-in value in favor of computing it
+ directly. */
+ const char *inferior_io_stderr = get_inferior_io_stderr ();
+
+ if (inferior_io_stderr == NULL)
+ inferior_io_stderr = "";
+ fprintf_filtered (gdb_stderr,
+ _("Standard error for future runs of program being "
+ "debugged is \"%s\".\n"), inferior_io_stderr);
+}
+
char *
get_inferior_args (void)
{
@@ -3132,6 +3248,36 @@ Usage: set inferior-tty /dev/pts/1"),
&setlist, &showlist);
add_com_alias ("tty", "set inferior-tty", class_alias, 0);
+ add_setshow_filename_cmd ("inferior-stdin", class_run,
+ &inferior_io_std_scratch[0], _("\
+Set standard input for future runs of program being debugged."), _("\
+Show standard input for future runs of program being debugged."), _("\
+Usage: set inferior-input /tmp/redirected.stdin"),
+ set_inferior_stdin_command,
+ show_inferior_stdin_command,
+ &setlist, &showlist);
+ add_com_alias ("stdin", "set inferior-stdin", class_alias, 0);
+
+ add_setshow_filename_cmd ("inferior-stdout", class_run,
+ &inferior_io_std_scratch[1], _("\
+Set standard output for future runs of program being debugged."), _("\
+Show standard output for future runs of program being debugged."), _("\
+Usage: set inferior-stdout /tmp/redirected.stdout"),
+ set_inferior_stdout_command,
+ show_inferior_stdout_command,
+ &setlist, &showlist);
+ add_com_alias ("stdout", "set inferior-stdout", class_alias, 0);
+
+ add_setshow_filename_cmd ("inferior-stderr", class_run,
+ &inferior_io_std_scratch[2], _("\
+Set standard error for future runs of program being debugged."), _("\
+Show standard error for future runs of program being debugged."), _("\
+Usage: set inferior-stderr /tmp/redirected.stderr"),
+ set_inferior_stderr_command,
+ show_inferior_stderr_command,
+ &setlist, &showlist);
+ add_com_alias ("stderr", "set inferior-stderr", class_alias, 0);
+
cmd_name = "args";
add_setshow_string_noescape_cmd (cmd_name, class_run,
&inferior_args_scratch, _("\
diff --git a/gdb/inferior.c b/gdb/inferior.c
index 04e9a28..6c6b5aa 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -99,6 +99,9 @@ free_inferior (struct inferior *inf)
inferior_free_data (inf);
xfree (inf->args);
xfree (inf->terminal);
+ xfree (inf->standard_io[0]);
+ xfree (inf->standard_io[1]);
+ xfree (inf->standard_io[2]);
free_environ (inf->environment);
target_desc_info_free (inf->tdesc_info);
xfree (inf->priv);
diff --git a/gdb/inferior.h b/gdb/inferior.h
index e09cb00..ed42bbd 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -77,6 +77,14 @@ extern void clear_sigint_trap (void);
extern void set_inferior_io_terminal (const char *terminal_name);
extern const char *get_inferior_io_terminal (void);
+/* Set/get file name for standard input/output/error. */
+extern void set_inferior_io_stdin (const char *file_name);
+extern const char *get_inferior_io_stdin (void);
+extern void set_inferior_io_stdout (const char *file_name);
+extern const char *get_inferior_io_stdout (void);
+extern void set_inferior_io_stderr (const char *file_name);
+extern const char *get_inferior_io_stderr (void);
+
/* Collected pid, tid, etc. of the debugged inferior. When there's
no inferior, ptid_get_pid (inferior_ptid) will be 0. */
@@ -329,6 +337,9 @@ struct inferior
/* The name of terminal device to use for I/O. */
char *terminal;
+ /* The names of files to use as standard input/output/error */
+ char *standard_io[3];
+
/* Environment to use for running inferior,
in format described in environ.h. */
struct gdb_environ *environment;
diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp
index 4395c98..2ae4f90 100644
--- a/gdb/testsuite/gdb.base/default.exp
+++ b/gdb/testsuite/gdb.base/default.exp
@@ -798,6 +798,12 @@ gdb_test "thread find" "Command requires an argument." "thread find"
gdb_test "thread name" "No thread selected" "thread name"
#test tty
gdb_test "tty" "Argument required .filename to set it to\..*" "tty"
+#test stdin
+gdb_test "stdin" "Argument required .filename to set it to\..*" "stdin"
+#test stdout
+gdb_test "stdout" "Argument required .filename to set it to\..*" "stdout"
+#test stderr
+gdb_test "stderr" "Argument required .filename to set it to\..*" "stderr"
#test until "u" abbreviation
gdb_test "u" "The program is not being run." "until \"u\" abbreviation"
#test until
--
2.4.3
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 4/4] GDB/MI: inferior standard I/O redirection
2015-10-05 11:47 [PATCH 0/4]: GDB: inferior standard I/O redirection Cleber Rosa
` (2 preceding siblings ...)
2015-10-05 11:47 ` [PATCH 2/4] GDB/MI: fix and simplify mi_valid_noargs utility function Cleber Rosa
@ 2015-10-05 11:54 ` Cleber Rosa
2015-10-05 12:26 ` Eli Zaretskii
` (2 more replies)
3 siblings, 3 replies; 12+ messages in thread
From: Cleber Rosa @ 2015-10-05 11:54 UTC (permalink / raw)
To: gdb-patches; +Cc: areis, palves, Cleber Rosa
This introduces the following MI commands:
* -inferior-stdin-set
* -inferior-stdin-show
* -inferior-stdout-set
* -inferior-stdout-show
* -inferior-stderr-set
* -inferior-stderr-show
Which are the MI version of the inferior standard I/O redirection
commands:
* set inferior-stdin (aliased as stdin)
* show inferior-stdin
* set inferior-stdout (aliased as stdout)
* show inferior-stdout
* set inferior-stderr (aliased as stderr)
gdb/doc/ChangeLog:
2015-10-05 Cleber Rosa <crosa@redhat.com>
* gdb.texinfo (info): Add documentation about the
-inferior-stdin-set, inferior-stdin-show, -inferior-stdout-set,
inferior-stdout-show, -inferior-stderr-set, inferior-stderr-show
commands.
gdb/ChangeLog:
2015-10-05 Cleber Rosa <crosa@redhat.com>
* mi/mi-cmd-env.c (mi_cmd_inferior_std_show_helper): New utility
function.
(mi_cmd_inferior_stdin_set): New function.
(mi_cmd_inferior_stdin_show): Likewise.
(mi_cmd_inferior_stdout_set): Likewise.
(mi_cmd_inferior_stdout_show): Likewise.
(mi_cmd_inferior_stderr_set): Likewise.
(mi_cmd_inferior_stderr_show): Likewise.
* mi/mi-cmds.c (struct mi_cmds): Add inferior-stdin-set,
inferior-stdin-show, inferior-stdout-set, inferior-stdout-show,
inferior-stderr-set, inferior-stderr-show.
* mi/mi-cmds.h: Add mi_cmd_inferior_stdin_set,
mi_cmd_inferior_stdin_show,
mi_cmd_inferior_stdout_set,mi_cmd_inferior_stdout_show,
mi_cmd_inferior_stderr_set and mi_cmd_inferior_stderr_show
declarations.
gdb/testsuite/ChangeLog:
2015-10-05 Cleber Rosa <crosa@redhat.com>
* gdb.mi/mi-basics.exp (test_setshow_inferior_std): New tests for
commands -inferior-stdin-set, -inferior-stdin-show,
-inferior-stdin-set, -inferior-stdin-show, -inferior-stdin-set and
-inferior-stdin-show.
---
gdb/doc/gdb.texinfo | 153 +++++++++++++++++++++++++++++++++++++
gdb/mi/mi-cmd-env.c | 77 +++++++++++++++++++
gdb/mi/mi-cmds.c | 6 ++
gdb/mi/mi-cmds.h | 6 ++
gdb/testsuite/gdb.mi/mi-basics.exp | 62 +++++++++++++++
5 files changed, 304 insertions(+)
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 39d5a1c..d6f77a8 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -32144,6 +32144,159 @@ The corresponding @value{GDBN} command is @samp{show inferior-tty}.
(gdb)
@end smallexample
+@subheading The @code{-inferior-stdin-set} Command
+@findex -inferior-stdin-set
+
+@subheading Synopsis
+
+@smallexample
+-inferior-stdin-set /tmp/answers
+@end smallexample
+
+Set standard input for future runs of the program being debugged.
+
+@subheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{set inferior-stdin} /tmp/answers.
+
+@subheading Example
+
+@smallexample
+(gdb)
+-inferior-stdin-set /tmp/answers
+^done
+(gdb)
+@end smallexample
+
+@subheading The @code{-inferior-stdin-show} Command
+@findex -inferior-stdin-show
+
+@subheading Synopsis
+
+@smallexample
+-inferior-stdin-show
+@end smallexample
+
+Show standard input to be used on future runs of program being debugged.
+
+@subheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{show inferior-stdin}.
+
+@subheading Example
+
+@smallexample
+(gdb)
+-inferior-stdin-set /tmp/answers
+^done
+(gdb)
+-inferior-stdin-show
+^done,inferior_stdin="/tmp/answers"
+(gdb)
+@end smallexample
+
+@subheading The @code{-inferior-stdout-set} Command
+@findex -inferior-stdout-set
+
+@subheading Synopsis
+
+@smallexample
+-inferior-stdout-set /tmp/output
+@end smallexample
+
+Set standard output for future runs of the program being debugged.
+
+@subheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{set inferior-stdout} /tmp/output.
+
+@subheading Example
+
+@smallexample
+(gdb)
+-inferior-stdout-set /tmp/output
+^done
+(gdb)
+@end smallexample
+
+@subheading The @code{-inferior-stdout-show} Command
+@findex -inferior-stdout-show
+
+@subheading Synopsis
+
+@smallexample
+-inferior-stdout-show
+@end smallexample
+
+Show standard output to be used on future runs of program being debugged.
+
+@subheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{show inferior-stdout}.
+
+@subheading Example
+
+@smallexample
+(gdb)
+-inferior-stdout-set /tmp/output
+^done
+(gdb)
+-inferior-stdout-show
+^done,inferior_stdout="/tmp/output"
+(gdb)
+@end smallexample
+
+@subheading The @code{-inferior-stderr-set} Command
+@findex -inferior-stderr-set
+
+@subheading Synopsis
+
+@smallexample
+-inferior-stderr-set /dev/null
+@end smallexample
+
+Set standard error for future runs of the program being debugged.
+
+@subheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{set inferior-stderr} /dev/null.
+
+@subheading Example
+
+@smallexample
+(gdb)
+-inferior-stderr-set /dev/null
+^done
+(gdb)
+@end smallexample
+
+@subheading The @code{-inferior-stderr-show} Command
+@findex -inferior-stderr-show
+
+@subheading Synopsis
+
+@smallexample
+-inferior-stderr-show
+@end smallexample
+
+Show standard error to be used on future runs of program being debugged.
+
+@subheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{show inferior-stderr}.
+
+@subheading Example
+
+@smallexample
+(gdb)
+-inferior-stderr-set /dev/null
+^done
+(gdb)
+-inferior-stderr-show
+^done,inferior_stderr="/dev/null"
+(gdb)
+@end smallexample
+
@subheading The @code{-enable-timings} Command
@findex -enable-timings
diff --git a/gdb/mi/mi-cmd-env.c b/gdb/mi/mi-cmd-env.c
index fad9297..610070d 100644
--- a/gdb/mi/mi-cmd-env.c
+++ b/gdb/mi/mi-cmd-env.c
@@ -268,6 +268,83 @@ mi_cmd_inferior_tty_show (char *command, char **argv, int argc)
"inferior_tty_terminal", inferior_io_terminal);
}
+/* Helper function to simplify mi_cmd_inferior_std{in,out,err}_show. */
+
+static void
+mi_cmd_inferior_std_show_helper(char *command,
+ char **argv,
+ int argc,
+ char *field_name,
+ const char *inferior_std_name)
+{
+ if ( !mi_valid_noargs ("-inferior-stdin-show", argc, argv))
+ error (_("%s: Usage: No args"), command);
+
+ if (inferior_std_name)
+ ui_out_field_string (current_uiout,
+ field_name, inferior_std_name);
+}
+
+/* Set the inferior stdin file name. */
+
+void
+mi_cmd_inferior_stdin_set (char *command, char **argv, int argc)
+{
+ set_inferior_io_stdin (argv[0]);
+}
+
+/* Print the inferior stdin file name. */
+
+void
+mi_cmd_inferior_stdin_show (char *command, char **argv, int argc)
+{
+ mi_cmd_inferior_std_show_helper("-inferior-stdin-show",
+ argv,
+ argc,
+ "inferior_stdin",
+ get_inferior_io_stdin ());
+}
+
+/* Set the inferior stdout file name. */
+
+void
+mi_cmd_inferior_stdout_set (char *command, char **argv, int argc)
+{
+ set_inferior_io_stdout (argv[0]);
+}
+
+/* Print the inferior stdout file name. */
+
+void
+mi_cmd_inferior_stdout_show (char *command, char **argv, int argc)
+{
+ mi_cmd_inferior_std_show_helper("-inferior-stdout-show",
+ argv,
+ argc,
+ "inferior_stdout",
+ get_inferior_io_stdout ());
+}
+
+/* Set the inferior stderr file name. */
+
+void
+mi_cmd_inferior_stderr_set (char *command, char **argv, int argc)
+{
+ set_inferior_io_stderr (argv[0]);
+}
+
+/* Print the inferior stderr file name. */
+
+void
+mi_cmd_inferior_stderr_show (char *command, char **argv, int argc)
+{
+ mi_cmd_inferior_std_show_helper("-inferior-stderr-show",
+ argv,
+ argc,
+ "inferior_stderr",
+ get_inferior_io_stderr ());
+}
+
void
_initialize_mi_cmd_env (void)
{
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index 2d8af2f..388b5b1 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -123,6 +123,12 @@ static struct mi_cmd mi_cmds[] =
DEF_MI_CMD_CLI ("gdb-version", "show version", 0),
DEF_MI_CMD_MI ("inferior-tty-set", mi_cmd_inferior_tty_set),
DEF_MI_CMD_MI ("inferior-tty-show", mi_cmd_inferior_tty_show),
+ DEF_MI_CMD_MI ("inferior-stdin-set", mi_cmd_inferior_stdin_set),
+ DEF_MI_CMD_MI ("inferior-stdin-show", mi_cmd_inferior_stdin_show),
+ DEF_MI_CMD_MI ("inferior-stdout-set", mi_cmd_inferior_stdout_set),
+ DEF_MI_CMD_MI ("inferior-stdout-show", mi_cmd_inferior_stdout_show),
+ DEF_MI_CMD_MI ("inferior-stderr-set", mi_cmd_inferior_stderr_set),
+ DEF_MI_CMD_MI ("inferior-stderr-show", mi_cmd_inferior_stderr_show),
DEF_MI_CMD_MI ("info-ada-exceptions", mi_cmd_info_ada_exceptions),
DEF_MI_CMD_MI ("info-gdb-mi-command", mi_cmd_info_gdb_mi_command),
DEF_MI_CMD_MI ("info-os", mi_cmd_info_os),
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index 55141f3..8ffb65f 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -73,6 +73,12 @@ extern mi_cmd_argv_ftype mi_cmd_file_list_exec_source_files;
extern mi_cmd_argv_ftype mi_cmd_gdb_exit;
extern mi_cmd_argv_ftype mi_cmd_inferior_tty_set;
extern mi_cmd_argv_ftype mi_cmd_inferior_tty_show;
+extern mi_cmd_argv_ftype mi_cmd_inferior_stdin_set;
+extern mi_cmd_argv_ftype mi_cmd_inferior_stdin_show;
+extern mi_cmd_argv_ftype mi_cmd_inferior_stdout_set;
+extern mi_cmd_argv_ftype mi_cmd_inferior_stdout_show;
+extern mi_cmd_argv_ftype mi_cmd_inferior_stderr_set;
+extern mi_cmd_argv_ftype mi_cmd_inferior_stderr_show;
extern mi_cmd_argv_ftype mi_cmd_info_ada_exceptions;
extern mi_cmd_argv_ftype mi_cmd_info_gdb_mi_command;
extern mi_cmd_argv_ftype mi_cmd_info_os;
diff --git a/gdb/testsuite/gdb.mi/mi-basics.exp b/gdb/testsuite/gdb.mi/mi-basics.exp
index 476dbdc..89f7d68 100644
--- a/gdb/testsuite/gdb.mi/mi-basics.exp
+++ b/gdb/testsuite/gdb.mi/mi-basics.exp
@@ -264,6 +264,67 @@ proc test_setshow_inferior_tty {} {
"make sure show takes no arguments"
}
+proc test_setshow_inferior_std {} {
+ global mi_gdb_prompt
+
+ # Test that the commands,
+ # -inferior-stdin-set
+ # -inferior-stdin-show
+ # -inferior-stdin-set
+ # -inferior-stdin-show
+ # -inferior-stdin-set
+ # -inferior-stdin-show
+ # are setting/getting the same data in GDB.
+
+ mi_gdb_test "301-inferior-stdin-show" \
+ "301\\\^done" \
+ "initial stdin is not set"
+
+ mi_gdb_test "302-inferior-stdin-set /foo/bar" \
+ "302\\\^done" \
+ "set stdin to /foo/bar"
+
+ mi_gdb_test "303-inferior-stdin-show" \
+ "303\\\^done,inferior_stdin=\"/foo/bar\"" \
+ "std was set correctly"
+
+ mi_gdb_test "304-inferior-stdin-show should-take-no-args" \
+ "304\\\^error,msg=\"-inferior-stdin-show: Usage: No args\"" \
+ "make sure show takes no arguments"
+
+ mi_gdb_test "305-inferior-stdout-show" \
+ "305\\\^done" \
+ "initial stdout is not set"
+
+ mi_gdb_test "306-inferior-stdout-set /foo/bar" \
+ "306\\\^done" \
+ "set stdout to /foo/bar"
+
+ mi_gdb_test "307-inferior-stdout-show" \
+ "307\\\^done,inferior_stdout=\"/foo/bar\"" \
+ "std was set correctly"
+
+ mi_gdb_test "308-inferior-stdout-show should-take-no-args" \
+ "308\\\^error,msg=\"-inferior-stdout-show: Usage: No args\"" \
+ "make sure show takes no arguments"
+
+ mi_gdb_test "309-inferior-stderr-show" \
+ "309\\\^done" \
+ "initial stderr is not set"
+
+ mi_gdb_test "310-inferior-stderr-set /foo/bar" \
+ "310\\\^done" \
+ "set stderr to /foo/bar"
+
+ mi_gdb_test "311-inferior-stderr-show" \
+ "311\\\^done,inferior_stderr=\"/foo/bar\"" \
+ "std was set correctly"
+
+ mi_gdb_test "312-inferior-stderr-show should-take-no-args" \
+ "312\\\^error,msg=\"-inferior-stderr-show: Usage: No args\"" \
+ "make sure show takes no arguments"
+}
+
if { [test_mi_interpreter_selection]
&& [test_exec_and_symbol_mi_operatons] } {
test_breakpoints_deletion
@@ -271,6 +332,7 @@ if { [test_mi_interpreter_selection]
test_cwd_specification
test_path_specification
test_setshow_inferior_tty
+ test_setshow_inferior_std
}
mi_gdb_exit
--
2.4.3
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/4] GDB: inferior standard I/O redirection
2015-10-05 11:47 ` [PATCH 1/4] " Cleber Rosa
@ 2015-10-05 12:23 ` Eli Zaretskii
2015-10-21 11:18 ` Pedro Alves
1 sibling, 0 replies; 12+ messages in thread
From: Eli Zaretskii @ 2015-10-05 12:23 UTC (permalink / raw)
To: Cleber Rosa; +Cc: gdb-patches, areis, palves, crosa
> From: Cleber Rosa <crosa@redhat.com>
> Cc: areis@redhat.com, palves@redhat.com, Cleber Rosa <crosa@redhat.com>
> Date: Mon, 5 Oct 2015 08:46:54 -0300
>
> This introduces a set of commands:
>
> * set inferior-stdin (aliased as stdin)
> * set inferior-stdout (aliased as stdout)
> * set inferior-stderr (aliased as stderr)
Thanks.
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -42,6 +42,21 @@ set remote multiprocess-extensions-packet
> show remote multiprocess-extensions-packet
> Set/show the use of the remote protocol multiprocess extensions.
>
> +set inferior-stdin
> +stdin
> +show inferior-stdin
> + Set/show the standard input for the program being debugged.
> +
> +set inferior-stdout
> +stdout
> +show inferior-stdout
> + Set/show the standard output for the program being debugged.
> +
> +set inferior-stderr
> +stderr
> +show inferior-stderr
> + Set/show the standard error for the program being debugged.
> +
This part is OK.
> +When you use the @code{tty} command or redirect input using either
> +@code{stdin}/@code{stdout}/@code{stderr} or the @code{run} command,
> +only the input @emph{for your program} is affected. The input for
> +@value{GDBN} still comes from your terminal and from the original
> +standard I/O channels. @code{tty} is an alias for @code{set
> +inferior-tty}.
It is strange to talk about redirecting input, when the description
also includes stdout and stderr. Did you really mean only input here?
> + add_setshow_filename_cmd ("inferior-stdin", class_run,
> + &inferior_io_std_scratch[0], _("\
> +Set standard input for future runs of program being debugged."), _("\
This correctly says that the effect of these commands is only for
_future_ runs of the inferior, but the text in the manual completely
omits this important detail, so the reader could think we have some
magical way of redirecting I/O of an already running program.
The documentation is OK with those gotchas fixed.
Thanks.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 4/4] GDB/MI: inferior standard I/O redirection
2015-10-05 11:54 ` [PATCH 4/4] GDB/MI: inferior standard I/O redirection Cleber Rosa
@ 2015-10-05 12:26 ` Eli Zaretskii
2015-10-21 11:19 ` Pedro Alves
2015-10-22 10:55 ` Vladimir Prus
2 siblings, 0 replies; 12+ messages in thread
From: Eli Zaretskii @ 2015-10-05 12:26 UTC (permalink / raw)
To: Cleber Rosa; +Cc: gdb-patches, areis, palves, crosa
> From: Cleber Rosa <crosa@redhat.com>
> Cc: areis@redhat.com, palves@redhat.com, Cleber Rosa <crosa@redhat.com>
> Date: Mon, 5 Oct 2015 08:46:57 -0300
>
> This introduces the following MI commands:
>
> * -inferior-stdin-set
> * -inferior-stdin-show
> * -inferior-stdout-set
> * -inferior-stdout-show
> * -inferior-stderr-set
> * -inferior-stderr-show
>
> Which are the MI version of the inferior standard I/O redirection
> commands:
>
> * set inferior-stdin (aliased as stdin)
> * show inferior-stdin
> * set inferior-stdout (aliased as stdout)
> * show inferior-stdout
> * set inferior-stderr (aliased as stderr)
Thanks.
> gdb/doc/ChangeLog:
> 2015-10-05 Cleber Rosa <crosa@redhat.com>
>
> * gdb.texinfo (info): Add documentation about the
> -inferior-stdin-set, inferior-stdin-show, -inferior-stdout-set,
> inferior-stdout-show, -inferior-stderr-set, inferior-stderr-show
> commands.
I think these new MI commands should be mentioned in NEWS as well.
> +The corresponding @value{GDBN} command is @samp{set inferior-stdin} /tmp/answers.
I believe we use @code as markup for command names, not @samp.
Otherwise, the documentation part is OK.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/4] GDB: inferior standard I/O redirection
2015-10-05 11:47 ` [PATCH 1/4] " Cleber Rosa
2015-10-05 12:23 ` Eli Zaretskii
@ 2015-10-21 11:18 ` Pedro Alves
1 sibling, 0 replies; 12+ messages in thread
From: Pedro Alves @ 2015-10-21 11:18 UTC (permalink / raw)
To: Cleber Rosa, gdb-patches; +Cc: areis
On 10/05/2015 12:46 PM, Cleber Rosa wrote:
> +/* Helper function that attempts to open a file and if successful
> + redirects another file descriptor to the one just opened. If
> + file_name is not given, this returns -1 as a simple way to flag
> + a skip (user has not asked for a redirection). Seems OK since
> + this is a helper function. */
> +
> +static int
> +set_std_io_helper (const char *file_name, int std_io_fd, int flags, mode_t mode)
> +{
> + int fd;
> +
> + if (file_name == NULL)
> + return -1;
> +
> + fd = open (file_name, flags, mode);
> + if (fd < 0)
> + return 0;
> +
> + if (dup2 (fd, std_io_fd) == -1) {
{ goes on the next line, and the reindent block.
> + close (fd);
> + return 0;
> + }
> +
> + close (fd);
> + return 1;
> +}
> +
> +/* Attempts to redirect stdin, stdout and stderr. If redirection was
Double-space after period.
> + not requested by the user, it will be skipped in the helper function.
> + In case of errors, each requested and failed redirection error will
> + be passed on for individual error reporting (no details such as
> + errno/perror though). */
> +
> +#define SET_STDIO_ERROR_STDIN 0x01
> +#define SET_STDIO_ERROR_STDOUT 0x02
> +#define SET_STDIO_ERROR_STDERR 0x04
> +
> +static int
> +set_std_io (void)
> +{
> + int result = 0;
> + char *file_name = NULL;
> +
> + if (set_std_io_helper (get_inferior_io_stdin(), 0,
> + O_RDONLY, S_IRUSR | S_IWUSR) == 0)
> + result |= SET_STDIO_ERROR_STDIN;
> +
> + if (set_std_io_helper (get_inferior_io_stdout(), 1,
> + O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR) == 0)
> + result |= SET_STDIO_ERROR_STDOUT;
> +
> + if (set_std_io_helper (get_inferior_io_stderr(), 2,
> + O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR) == 0)
> + result |= SET_STDIO_ERROR_STDERR;
Shouldn't we specify O_APPEND? I'm thinking of the case of starting
multiple inferiors simultaneously under gdb. Not one after the other,
but really in parallel. E.g., run&; add-inferior ...; inferior 2; run&; etc.
> +
> + return result;
> +}
> +
> /* Start an inferior Unix child process and sets inferior_ptid to its
> pid. EXEC_FILE is the file to run. ALLARGS is a string containing
> the arguments to the program. ENV is the environment vector to
> @@ -141,6 +199,7 @@ fork_inferior (char *exec_file_arg, char *allargs, char **env,
> struct inferior *inf;
> int i;
> int save_errno;
> + int io_redir_errors = 0;
>
> /* If no exec file handed to us, get it from the exec-file command
> -- with a good, common error message if none is specified. */
> @@ -358,6 +417,28 @@ fork_inferior (char *exec_file_arg, char *allargs, char **env,
> path to find $SHELL. Rich Pixley says so, and I agree. */
> environ = env;
>
> + /* Sets the inferior process standard I/O (input, output, error)
> + redirection if set with the "set inferior std{in,out,err}"
> + commands. */
> + gdb_flush (gdb_stdout);
> + gdb_flush (gdb_stderr);
> + io_redir_errors = set_std_io();
Space before parens. More instances below.
> + if (io_redir_errors & SET_STDIO_ERROR_STDIN)
> + fprintf_unfiltered (gdb_stderr,
> + "Could not set %s as stdin for %s\n",
Wrap user-visible strings in _() for i18n. More instances below.
> + get_inferior_io_stdin(),
> + exec_file);
> + if (io_redir_errors & SET_STDIO_ERROR_STDOUT)
> + fprintf_unfiltered (gdb_stderr,
> + "Could not set %s as stdout for %s\n",
> + get_inferior_io_stdout(),
> + exec_file);
> + if (io_redir_errors & SET_STDIO_ERROR_STDERR)
> + fprintf_unfiltered (gdb_stderr,
> + "Could not set %s as stderr for %s\n",
> + get_inferior_io_stderr(),
> + exec_file);
> +
> if (exec_fun != NULL)
> (*exec_fun) (argv[0], argv, env);
> else
> diff --git a/gdb/infcmd.c b/gdb/infcmd.c
> index 4713490..9941a98 100644
> --- a/gdb/infcmd.c
> +++ b/gdb/infcmd.c
> @@ -115,6 +115,11 @@ static char *inferior_args_scratch;
>
> static char *inferior_io_terminal_scratch;
>
> +/* Scratch area where 'set inferior-{stdin,stdout,stderr}' will store
> + user provided value. */
> +
> +static char *inferior_io_std_scratch[3] = { NULL, NULL, NULL };
> +
> /* Pid of our debugged inferior, or 0 if no inferior now.
> Since various parts of infrun.c test this to see whether there is a program
> being debugged it should be nonzero (currently 3 is used) for remote
> @@ -182,6 +187,117 @@ show_inferior_tty_command (struct ui_file *file, int from_tty,
> "is \"%s\".\n"), inferior_io_terminal);
> }
>
New functions below need intro comments. For extern functions,
use "/* See whatever.h. */".
> +static void
> +set_inferior_io_helper (const char *file_name, int stdfd)
> +{
> + gdb_assert (0 <= stdfd && stdfd <= 2);
> + xfree (current_inferior ()->standard_io[stdfd]);
> + current_inferior ()->standard_io[stdfd] =
> + file_name != NULL ? xstrdup (file_name) : NULL;
> +}
> +
> +void
> +set_inferior_io_stdin (const char *file_name)
> +{
> + set_inferior_io_helper(file_name, 0);
Space before parens.
> diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp
> index 4395c98..2ae4f90 100644
> --- a/gdb/testsuite/gdb.base/default.exp
> +++ b/gdb/testsuite/gdb.base/default.exp
> @@ -798,6 +798,12 @@ gdb_test "thread find" "Command requires an argument." "thread find"
> gdb_test "thread name" "No thread selected" "thread name"
> #test tty
> gdb_test "tty" "Argument required .filename to set it to\..*" "tty"
> +#test stdin
> +gdb_test "stdin" "Argument required .filename to set it to\..*" "stdin"
> +#test stdout
> +gdb_test "stdout" "Argument required .filename to set it to\..*" "stdout"
> +#test stderr
> +gdb_test "stderr" "Argument required .filename to set it to\..*" "stderr"
> #test until "u" abbreviation
> gdb_test "u" "The program is not being run." "until \"u\" abbreviation"
> #test until
>
It'd be great if we also tested that it actually works.
Thanks,
Pedro Alves
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/4] GDB/MI: add test for command -inferior-tty-show
2015-10-05 11:47 ` [PATCH 3/4] GDB/MI: add test for command -inferior-tty-show Cleber Rosa
@ 2015-10-21 11:19 ` Pedro Alves
0 siblings, 0 replies; 12+ messages in thread
From: Pedro Alves @ 2015-10-21 11:19 UTC (permalink / raw)
To: Cleber Rosa, gdb-patches; +Cc: areis
On 10/05/2015 12:46 PM, Cleber Rosa wrote:
> Simple test that gives arguments to a command that should take none.
>
> gdb/testsuite/ChangeLog:
> 2015-10-05 Cleber Rosa <crosa@redhat.com>
>
> * gdb.mi/mi-basics.exp: Added test for inferior-tty-show with
> arguments when it should take none.
This is OK. I see the same test on patch #4 though?
Thanks,
Pedro Alves
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/4] GDB/MI: fix and simplify mi_valid_noargs utility function
2015-10-05 11:47 ` [PATCH 2/4] GDB/MI: fix and simplify mi_valid_noargs utility function Cleber Rosa
@ 2015-10-21 11:19 ` Pedro Alves
0 siblings, 0 replies; 12+ messages in thread
From: Pedro Alves @ 2015-10-21 11:19 UTC (permalink / raw)
To: Cleber Rosa, gdb-patches; +Cc: areis
On 10/05/2015 12:46 PM, Cleber Rosa wrote:
...
> If the command should take no arguments, then it should be OK to just
> check the given argument count.
...
>
> diff --git a/gdb/mi/mi-getopt.c b/gdb/mi/mi-getopt.c
> index 0a07a39..574ccd2 100644
> --- a/gdb/mi/mi-getopt.c
> +++ b/gdb/mi/mi-getopt.c
> @@ -95,18 +95,14 @@ mi_getopt_allow_unknown (const char *prefix, int argc, char **argv,
> return mi_getopt_1 (prefix, argc, argv, opts, oind, oarg, 0);
> }
>
> +/* Tests if a command that takes no arguments was properly used.
> + Returns 1 if no options were given, otherwise return 0. */
This function is already documented in mi-getopt.h. Any comment
here should just be "/* See mi-getopt.h. */"
But the comment in mi-getopt.h says:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* mi_valid_noargs determines if ARGC/ARGV are a valid set of
parameters to satisfy an MI function that is not supposed to
recieve any arguments.
An MI function that should not receive arguments can still be
passed parameters after the special option '--' such as below.
Example: The MI function -exec-run takes no args.
However, the client may pass '-exec-run -- -a ...'
See PR-783
PREFIX is passed to mi_getopt for an error message.
This function Returns 1 if the parameter pair ARGC/ARGV are valid
for an MI function that takes no arguments. Otherwise, it returns 0
and the appropriate error message is displayed by mi_getopt. */
extern int mi_valid_noargs (const char *prefix, int argc, char **argv);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sounds like that conflicts with your patch?
Thanks,
Pedro Alves
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 4/4] GDB/MI: inferior standard I/O redirection
2015-10-05 11:54 ` [PATCH 4/4] GDB/MI: inferior standard I/O redirection Cleber Rosa
2015-10-05 12:26 ` Eli Zaretskii
@ 2015-10-21 11:19 ` Pedro Alves
2015-10-22 10:55 ` Vladimir Prus
2 siblings, 0 replies; 12+ messages in thread
From: Pedro Alves @ 2015-10-21 11:19 UTC (permalink / raw)
To: Cleber Rosa, gdb-patches; +Cc: areis, Vladimir Prus
(+Vladimir as MI maintainer.)
On 10/05/2015 12:46 PM, Cleber Rosa wrote:
> +@smallexample
> +(gdb)
> +-inferior-stderr-set /dev/null
> +^done
> +(gdb)
> +-inferior-stderr-show
> +^done,inferior_stderr="/dev/null"
(Note that if you want, you're free to use '-', as in 'inferior-stderr',
instead of '_'. It's actually more common.)
> +(gdb)
> +@end smallexample
> +
> @subheading The @code{-enable-timings} Command
> @findex -enable-timings
>
> diff --git a/gdb/mi/mi-cmd-env.c b/gdb/mi/mi-cmd-env.c
> index fad9297..610070d 100644
> --- a/gdb/mi/mi-cmd-env.c
> +++ b/gdb/mi/mi-cmd-env.c
> @@ -268,6 +268,83 @@ mi_cmd_inferior_tty_show (char *command, char **argv, int argc)
> "inferior_tty_terminal", inferior_io_terminal);
> }
>
> +/* Helper function to simplify mi_cmd_inferior_std{in,out,err}_show. */
> +
> +static void
> +mi_cmd_inferior_std_show_helper(char *command,
Space before parens. Can 'command' and 'field_name' be const?
> + char **argv,
> + int argc,
> + char *field_name,
> + const char *inferior_std_name)
> +{
> + if ( !mi_valid_noargs ("-inferior-stdin-show", argc, argv))
Spurious space before '!'.
> + error (_("%s: Usage: No args"), command);
> +
> + if (inferior_std_name)
if (inferior_std_name != NULL)
> + ui_out_field_string (current_uiout,
> + field_name, inferior_std_name);
> +}
> +
> +/* Set the inferior stdin file name. */
> +
> +void
> +mi_cmd_inferior_stdin_set (char *command, char **argv, int argc)
> +{
> + set_inferior_io_stdin (argv[0]);
> +}
> +
> +/* Print the inferior stdin file name. */
> +
> +void
> +mi_cmd_inferior_stdin_show (char *command, char **argv, int argc)
> +{
> + mi_cmd_inferior_std_show_helper("-inferior-stdin-show",
Space before parens.
> + argv,
> + argc,
> + "inferior_stdin",
> + get_inferior_io_stdin ());
> +}
> +
> +/* Set the inferior stdout file name. */
> +
> +void
> +mi_cmd_inferior_stdout_set (char *command, char **argv, int argc)
> +{
> + set_inferior_io_stdout (argv[0]);
> +}
> +
> +/* Print the inferior stdout file name. */
> +
> +void
> +mi_cmd_inferior_stdout_show (char *command, char **argv, int argc)
> +{
> + mi_cmd_inferior_std_show_helper("-inferior-stdout-show",
Space before parens.
> + argv,
> + argc,
> + "inferior_stdout",
Something odd with indentation here.
> + get_inferior_io_stdout ());
> +}
> +
> +/* Set the inferior stderr file name. */
> +
> +void
> +mi_cmd_inferior_stderr_set (char *command, char **argv, int argc)
> +{
> + set_inferior_io_stderr (argv[0]);
> +}
> +
> +/* Print the inferior stderr file name. */
> +
> +void
> +mi_cmd_inferior_stderr_show (char *command, char **argv, int argc)
> +{
> + mi_cmd_inferior_std_show_helper("-inferior-stderr-show",
Space before parens.
> + argv,
> + argc,
> + "inferior_stderr",
> + get_inferior_io_stderr ());
> +}
> +
> void
> _initialize_mi_cmd_env (void)
> {
> diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
> index 2d8af2f..388b5b1 100644
> --- a/gdb/mi/mi-cmds.c
> +++ b/gdb/mi/mi-cmds.c
> @@ -123,6 +123,12 @@ static struct mi_cmd mi_cmds[] =
> DEF_MI_CMD_CLI ("gdb-version", "show version", 0),
> DEF_MI_CMD_MI ("inferior-tty-set", mi_cmd_inferior_tty_set),
> DEF_MI_CMD_MI ("inferior-tty-show", mi_cmd_inferior_tty_show),
> + DEF_MI_CMD_MI ("inferior-stdin-set", mi_cmd_inferior_stdin_set),
> + DEF_MI_CMD_MI ("inferior-stdin-show", mi_cmd_inferior_stdin_show),
> + DEF_MI_CMD_MI ("inferior-stdout-set", mi_cmd_inferior_stdout_set),
> + DEF_MI_CMD_MI ("inferior-stdout-show", mi_cmd_inferior_stdout_show),
> + DEF_MI_CMD_MI ("inferior-stderr-set", mi_cmd_inferior_stderr_set),
> + DEF_MI_CMD_MI ("inferior-stderr-show", mi_cmd_inferior_stderr_show),
> DEF_MI_CMD_MI ("info-ada-exceptions", mi_cmd_info_ada_exceptions),
> DEF_MI_CMD_MI ("info-gdb-mi-command", mi_cmd_info_gdb_mi_command),
> DEF_MI_CMD_MI ("info-os", mi_cmd_info_os),
> diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
> index 55141f3..8ffb65f 100644
> --- a/gdb/mi/mi-cmds.h
> +++ b/gdb/mi/mi-cmds.h
> @@ -73,6 +73,12 @@ extern mi_cmd_argv_ftype mi_cmd_file_list_exec_source_files;
> extern mi_cmd_argv_ftype mi_cmd_gdb_exit;
> extern mi_cmd_argv_ftype mi_cmd_inferior_tty_set;
> extern mi_cmd_argv_ftype mi_cmd_inferior_tty_show;
> +extern mi_cmd_argv_ftype mi_cmd_inferior_stdin_set;
> +extern mi_cmd_argv_ftype mi_cmd_inferior_stdin_show;
> +extern mi_cmd_argv_ftype mi_cmd_inferior_stdout_set;
> +extern mi_cmd_argv_ftype mi_cmd_inferior_stdout_show;
> +extern mi_cmd_argv_ftype mi_cmd_inferior_stderr_set;
> +extern mi_cmd_argv_ftype mi_cmd_inferior_stderr_show;
> extern mi_cmd_argv_ftype mi_cmd_info_ada_exceptions;
> extern mi_cmd_argv_ftype mi_cmd_info_gdb_mi_command;
> extern mi_cmd_argv_ftype mi_cmd_info_os;
> diff --git a/gdb/testsuite/gdb.mi/mi-basics.exp b/gdb/testsuite/gdb.mi/mi-basics.exp
> index 476dbdc..89f7d68 100644
> --- a/gdb/testsuite/gdb.mi/mi-basics.exp
> +++ b/gdb/testsuite/gdb.mi/mi-basics.exp
> @@ -264,6 +264,67 @@ proc test_setshow_inferior_tty {} {
> "make sure show takes no arguments"
> }
>
> +proc test_setshow_inferior_std {} {
> + global mi_gdb_prompt
> +
> + # Test that the commands,
> + # -inferior-stdin-set
> + # -inferior-stdin-show
> + # -inferior-stdin-set
> + # -inferior-stdin-show
> + # -inferior-stdin-set
> + # -inferior-stdin-show
> + # are setting/getting the same data in GDB.
> +
> + mi_gdb_test "301-inferior-stdin-show" \
> + "301\\\^done" \
> + "initial stdin is not set"
> +
> + mi_gdb_test "302-inferior-stdin-set /foo/bar" \
> + "302\\\^done" \
> + "set stdin to /foo/bar"
> +
> + mi_gdb_test "303-inferior-stdin-show" \
> + "303\\\^done,inferior_stdin=\"/foo/bar\"" \
> + "std was set correctly"
> +
> + mi_gdb_test "304-inferior-stdin-show should-take-no-args" \
> + "304\\\^error,msg=\"-inferior-stdin-show: Usage: No args\"" \
> + "make sure show takes no arguments"
> +
> + mi_gdb_test "305-inferior-stdout-show" \
> + "305\\\^done" \
> + "initial stdout is not set"
> +
> + mi_gdb_test "306-inferior-stdout-set /foo/bar" \
> + "306\\\^done" \
> + "set stdout to /foo/bar"
> +
> + mi_gdb_test "307-inferior-stdout-show" \
> + "307\\\^done,inferior_stdout=\"/foo/bar\"" \
> + "std was set correctly"
> +
> + mi_gdb_test "308-inferior-stdout-show should-take-no-args" \
> + "308\\\^error,msg=\"-inferior-stdout-show: Usage: No args\"" \
> + "make sure show takes no arguments"
Please make sure there are no duplicate test messages:
https://sourceware.org/gdb/wiki/GDBTestcaseCookbook#Make_sure_test_messages_are_unique
> +
> + mi_gdb_test "309-inferior-stderr-show" \
> + "309\\\^done" \
> + "initial stderr is not set"
> +
> + mi_gdb_test "310-inferior-stderr-set /foo/bar" \
> + "310\\\^done" \
> + "set stderr to /foo/bar"
> +
> + mi_gdb_test "311-inferior-stderr-show" \
> + "311\\\^done,inferior_stderr=\"/foo/bar\"" \
> + "std was set correctly"
> +
> + mi_gdb_test "312-inferior-stderr-show should-take-no-args" \
> + "312\\\^error,msg=\"-inferior-stderr-show: Usage: No args\"" \
> + "make sure show takes no arguments"
> +}
> +
> if { [test_mi_interpreter_selection]
> && [test_exec_and_symbol_mi_operatons] } {
> test_breakpoints_deletion
> @@ -271,6 +332,7 @@ if { [test_mi_interpreter_selection]
> test_cwd_specification
> test_path_specification
> test_setshow_inferior_tty
> + test_setshow_inferior_std
> }
>
> mi_gdb_exit
>
Looks good to me with the nits above fixed.
Thanks,
Pedro Alves
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 4/4] GDB/MI: inferior standard I/O redirection
2015-10-05 11:54 ` [PATCH 4/4] GDB/MI: inferior standard I/O redirection Cleber Rosa
2015-10-05 12:26 ` Eli Zaretskii
2015-10-21 11:19 ` Pedro Alves
@ 2015-10-22 10:55 ` Vladimir Prus
2 siblings, 0 replies; 12+ messages in thread
From: Vladimir Prus @ 2015-10-22 10:55 UTC (permalink / raw)
To: gdb-patches
Cleber, thanks for the patch! And thanks Pedro for the CC.
On 05-Oct-15 2:46 PM, Cleber Rosa wrote:
> This introduces the following MI commands:
>
> * -inferior-stdin-set
> * -inferior-stdin-show
> * -inferior-stdout-set
> * -inferior-stdout-show
> * -inferior-stderr-set
> * -inferior-stderr-show
>
> Which are the MI version of the inferior standard I/O redirection
> commands:
>
> * set inferior-stdin (aliased as stdin)
> * show inferior-stdin
> * set inferior-stdout (aliased as stdout)
> * show inferior-stdout
> * set inferior-stderr (aliased as stderr)
These additions look non-controversial to me.
> +@subheading The @code{-inferior-stdin-set} Command
> +@findex -inferior-stdin-set
> +
> +@subheading Synopsis
> +
> +@smallexample
> +-inferior-stdin-set /tmp/answers
> +@end smallexample
> +
> +Set standard input for future runs of the program being debugged.
This documentation does not specify what the parameter to the command is. Is this something you can write
explicitly, so that one does not have to consult CLI docs? It seems you need a filepath, in which case
writing
+@smallexample
+-inferior-stdin-set <filepath>
+@end smallexample
might be clearer (I don't remember texinfo syntax for replaceable part).
Do we want to support passing integer file descriptor here as well?
Thanks,
Volodya
--
Vladimir Prus
http://vladimirprus.com
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2015-10-22 7:21 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-05 11:47 [PATCH 0/4]: GDB: inferior standard I/O redirection Cleber Rosa
2015-10-05 11:47 ` [PATCH 1/4] " Cleber Rosa
2015-10-05 12:23 ` Eli Zaretskii
2015-10-21 11:18 ` Pedro Alves
2015-10-05 11:47 ` [PATCH 3/4] GDB/MI: add test for command -inferior-tty-show Cleber Rosa
2015-10-21 11:19 ` Pedro Alves
2015-10-05 11:47 ` [PATCH 2/4] GDB/MI: fix and simplify mi_valid_noargs utility function Cleber Rosa
2015-10-21 11:19 ` Pedro Alves
2015-10-05 11:54 ` [PATCH 4/4] GDB/MI: inferior standard I/O redirection Cleber Rosa
2015-10-05 12:26 ` Eli Zaretskii
2015-10-21 11:19 ` Pedro Alves
2015-10-22 10:55 ` Vladimir Prus
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox