* [PATCH] gdb output pipelining to shell
@ 2011-07-16 10:09 Abhijit Halder
2011-07-16 14:49 ` Eli Zaretskii
0 siblings, 1 reply; 9+ messages in thread
From: Abhijit Halder @ 2011-07-16 10:09 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1560 bytes --]
At present, there is no way to pass the output of a gdb command
directly to the shell for further processing. For example, something
similar is not permitted:
(gdb) thread apply all bt | less
This kind of feature is quite helpful in a scenario where a program
under debugger has hundreds of threads running and one wants to
examine the stack-trace of all the threads at once. The current
behaviour of gdb makes it somewhat difficult since the entire output
of gdb command (sometimes more than a number of pages) is dumped onto
the screen. One can always redirect the output of gdb using logging
mechanism, but that requires offline analysis of the log-file which
may not be acceptable in certain situations. Another option is to get
a shell using gdb's shell command, but that forces one every time to
source the shell profile. Furthermore, the log-file contains entire
debug information, parsing that huge file is resource and time
consuming.
I have implemented a feature which will allow one to pass the output
of any gdb command to the shell for further processing.
2011-07-09 Abhijit Halder <abhijit.k.halder@symantec.com>
* top.c (execute_command_to_pipe): New function.
(parse_for_shell_command): New function
(execute_command): Update.
* ui-file.c (gdb_modify_io): New function.
* ui-file.h (gdb_modify_io): Prototype.
top.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
ui-file.c | 15 ++++++++++++
ui-file.h | 3 ++
3 files changed, 91 insertions(+), 1 deletion(-)
Regards,
Abhijit Halder
[-- Attachment #2: gdb-shell-integration.patch --]
[-- Type: text/x-patch, Size: 3447 bytes --]
diff -rup src//gdb/top.c dst//gdb/top.c
--- src//gdb/top.c 2011-06-28 00:51:50.000000000 +0530
+++ dst//gdb/top.c 2011-07-15 13:48:19.943911979 +0530
@@ -48,6 +48,7 @@
#include "event-loop.h"
#include "gdbthread.h"
#include "python/python.h"
+#include "ui-file.h"
/* readline include files. */
#include "readline/readline.h"
@@ -358,6 +359,68 @@ prepare_execute_command (void)
return cleanup;
}
+char *
+parse_for_shell_command (char *p)
+{
+ char *sh_cmd, *cpos, *spos, *epos;
+ int quote_cnt = 0;
+
+ if ((sh_cmd = strchr (p, '|')) != NULL)
+ {
+ spos = p;
+ epos = p + strlen (p) - 1;
+
+ for (;;)
+ {
+ for (cpos = spos; (cpos = memchr (cpos, '"', (sh_cmd-cpos))) != NULL; cpos++)
+ quote_cnt++;
+ spos = (sh_cmd + 1);
+ if ((quote_cnt % 2) == 0 || (sh_cmd = strchr (spos, '|')) == NULL)
+ break;
+ }
+
+ if (sh_cmd == NULL)
+ return NULL;
+
+ cpos = spos;
+ while (isspace(*cpos))
+ cpos++;
+
+ if (*cpos != '{')
+ return NULL;
+
+ *cpos = ' ';
+
+ cpos = epos;
+ while (isspace(*cpos))
+ cpos--;
+
+ if (*cpos != '}')
+ return NULL;
+
+ *cpos = ' ';
+ }
+
+ if (sh_cmd)
+ *sh_cmd++ = '\0';
+
+ return sh_cmd;
+}
+
+/* Run execute_command for P and FROM_TTY. Write output in pipe,
+ do not display it to the screen. */
+
+void
+execute_command_to_pipe (char *p, int from_tty, FILE *pipe)
+{
+ FILE *file;
+
+ file = gdb_modify_io (gdb_stdout, pipe);
+ execute_command (p, from_tty);
+ pipe = gdb_modify_io (gdb_stdout, file);
+ pclose (pipe);
+}
+
/* Execute the line P as a command, in the current user context.
Pass FROM_TTY as second argument to the defining function. */
@@ -368,7 +431,16 @@ execute_command (char *p, int from_tty)
struct cmd_list_element *c;
enum language flang;
static int warned = 0;
- char *line;
+ char *line, *sh_cmd;
+
+ if ((sh_cmd = parse_for_shell_command (p)) != NULL)
+ {
+ FILE *pipe;
+
+ pipe = popen (sh_cmd, "w");
+ execute_command_to_pipe (p, from_tty, pipe);
+ return;
+ }
cleanup = prepare_execute_command ();
diff -rup src//gdb/ui-file.c dst//gdb/ui-file.c
--- src//gdb/ui-file.c 2011-05-14 11:14:36.000000000 +0530
+++ dst//gdb/ui-file.c 2011-07-15 13:49:34.999910332 +0530
@@ -617,6 +617,21 @@ struct ui_file *
stdio_fileopen (FILE *file)
{
return stdio_file_new (file, 0);
+
+}
+
+FILE *
+gdb_modify_io (struct ui_file *file, FILE *iostream_new)
+{
+ FILE *iostream_old;
+ struct stdio_file *stdio = ui_file_data (file);
+
+ if (stdio->magic != &stdio_file_magic)
+ internal_error (__FILE__, __LINE__,
+ _("gdb_modify_io: bad magic number"));
+ iostream_old = stdio->file;
+ stdio->file = iostream_new;
+ return iostream_old;
}
struct ui_file *
diff -rup src//gdb/ui-file.h dst//gdb/ui-file.h
--- src//gdb/ui-file.h 2011-05-13 22:58:20.000000000 +0530
+++ dst//gdb/ui-file.h 2011-07-15 13:48:54.603912199 +0530
@@ -126,6 +126,9 @@ extern struct ui_file *stdio_fileopen (F
/* Open NAME returning an STDIO based UI_FILE. */
extern struct ui_file *gdb_fopen (char *name, char *mode);
+/* Modify the file pointer of an STDIO based UI_FILE. */
+FILE *gdb_modify_io (struct ui_file *file, FILE *iostream_new);
+
/* Create a file which writes to both ONE and TWO. CLOSE_ONE
and CLOSE_TWO indicate whether the original files should be
closed when the new file is closed. */
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH] gdb output pipelining to shell 2011-07-16 10:09 [PATCH] gdb output pipelining to shell Abhijit Halder @ 2011-07-16 14:49 ` Eli Zaretskii 2011-07-16 18:06 ` Abhijit Halder 0 siblings, 1 reply; 9+ messages in thread From: Eli Zaretskii @ 2011-07-16 14:49 UTC (permalink / raw) To: Abhijit Halder; +Cc: gdb-patches > Date: Sat, 16 Jul 2011 14:12:35 +0530 > From: Abhijit Halder <abhijit.k.halder@gmail.com> > > I have implemented a feature which will allow one to pass the output > of any gdb command to the shell for further processing. Thanks. If this is accepted, we will need a corresponding addition to the manual. > + for (cpos = spos; (cpos = memchr (cpos, '"', (sh_cmd-cpos))) != NULL; cpos++) > + quote_cnt++; > + spos = (sh_cmd + 1); > + if ((quote_cnt % 2) == 0 || (sh_cmd = strchr (spos, '|')) == NULL) > + break; I'm not sure I understand this (comments would be helpful). Are you assuming that quote characters `"' in shell commands cannot be escaped, e.g. with a backslash? And what about quoting with a single quote character ("'")? > + if (*cpos != '{') > + return NULL; > + > + *cpos = ' '; > + > + cpos = epos; > + while (isspace(*cpos)) > + cpos--; > + > + if (*cpos != '}') > + return NULL; What is this magic about {...} that you are removing? Again, comments could help. > + > + *cpos = ' '; > + } > + > + if (sh_cmd) > + *sh_cmd++ = '\0'; > + > + return sh_cmd; This butchers the string passed to execute_command. Are you sure all the callers of execute_command can safely deal with that? What if the string is a constant string, for example? ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] gdb output pipelining to shell 2011-07-16 14:49 ` Eli Zaretskii @ 2011-07-16 18:06 ` Abhijit Halder 2011-07-17 20:26 ` Abhijit Halder 0 siblings, 1 reply; 9+ messages in thread From: Abhijit Halder @ 2011-07-16 18:06 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gdb-patches On Sat, Jul 16, 2011 at 3:17 PM, Eli Zaretskii <eliz@gnu.org> wrote: >> Date: Sat, 16 Jul 2011 14:12:35 +0530 >> From: Abhijit Halder <abhijit.k.halder@gmail.com> >> >> I have implemented a feature which will allow one to pass the output >> of any gdb command to the shell for further processing. > > Thanks. > > If this is accepted, we will need a corresponding addition to the > manual. > >> + for (cpos = spos; (cpos = memchr (cpos, '"', (sh_cmd-cpos))) != NULL; cpos++) >> + quote_cnt++; >> + spos = (sh_cmd + 1); >> + if ((quote_cnt % 2) == 0 || (sh_cmd = strchr (spos, '|')) == NULL) >> + break; > > I'm not sure I understand this (comments would be helpful). Are you > assuming that quote characters `"' in shell commands cannot be > escaped, e.g. with a backslash? And what about quoting with a single > quote character ("'")? > Any pipe ('|' character), not within double quote will be considered as either a bitwise-OR operator or a pipe between gdb and shell. String after pipe (not within double quote) will be considered as shell command if (and only if) it is encapsulated within opening and closing braces ('{' and '}') . The shell command can surely contain double quote, even braces. There is no validation done for shell command. >> + if (*cpos != '{') >> + return NULL; >> + >> + *cpos = ' '; >> + >> + cpos = epos; >> + while (isspace(*cpos)) >> + cpos--; >> + >> + if (*cpos != '}') >> + return NULL; > > What is this magic about {...} that you are removing? Again, comments > could help. > Here I am removing the braces from the shell command. An example will help in understanding this: (gdb) thread apply all bt | { grep "foo" } This will be a valid command. { grep "foo" } will be considered as shell command and we need to erase the braces part of it to make it a valid shell command. >> + >> + *cpos = ' '; >> + } >> + >> + if (sh_cmd) >> + *sh_cmd++ = '\0'; >> + >> + return sh_cmd; > > This butchers the string passed to execute_command. Are you sure all > the callers of execute_command can safely deal with that? What if the > string is a constant string, for example? > The new code path will be executed only when one will enter a command containing pipeline between gdb and shell. In that case the string passed to execute_command must not be a constant string (since it is user input from gdb prompt). Hence we are safe. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] gdb output pipelining to shell 2011-07-16 18:06 ` Abhijit Halder @ 2011-07-17 20:26 ` Abhijit Halder 2011-07-18 18:23 ` Abhijit Halder 0 siblings, 1 reply; 9+ messages in thread From: Abhijit Halder @ 2011-07-17 20:26 UTC (permalink / raw) To: gdb-patches [-- Attachment #1: Type: text/plain, Size: 2808 bytes --] A small correction. Re-submitting the patch. The earlier patch was not able to handle below situation: (gdb) p '|' | { less } On Sat, Jul 16, 2011 at 3:38 PM, Abhijit Halder <abhijit.k.halder@gmail.com> wrote: > On Sat, Jul 16, 2011 at 3:17 PM, Eli Zaretskii <eliz@gnu.org> wrote: >>> Date: Sat, 16 Jul 2011 14:12:35 +0530 >>> From: Abhijit Halder <abhijit.k.halder@gmail.com> >>> >>> I have implemented a feature which will allow one to pass the output >>> of any gdb command to the shell for further processing. >> >> Thanks. >> >> If this is accepted, we will need a corresponding addition to the >> manual. >> >>> + for (cpos = spos; (cpos = memchr (cpos, '"', (sh_cmd-cpos))) != NULL; cpos++) >>> + quote_cnt++; >>> + spos = (sh_cmd + 1); >>> + if ((quote_cnt % 2) == 0 || (sh_cmd = strchr (spos, '|')) == NULL) >>> + break; >> >> I'm not sure I understand this (comments would be helpful). Are you >> assuming that quote characters `"' in shell commands cannot be >> escaped, e.g. with a backslash? And what about quoting with a single >> quote character ("'")? >> > Any pipe ('|' character), not within double quote will be considered > as either a bitwise-OR operator or a pipe between gdb and shell. > String after pipe (not within double quote) will be considered as > shell command if (and only if) it is encapsulated within opening and > closing braces ('{' and '}') . The shell command can surely contain > double quote, even braces. There is no validation done for shell > command. > >>> + if (*cpos != '{') >>> + return NULL; >>> + >>> + *cpos = ' '; >>> + >>> + cpos = epos; >>> + while (isspace(*cpos)) >>> + cpos--; >>> + >>> + if (*cpos != '}') >>> + return NULL; >> >> What is this magic about {...} that you are removing? Again, comments >> could help. >> > Here I am removing the braces from the shell command. An example will > help in understanding this: > (gdb) thread apply all bt | { grep "foo" } > This will be a valid command. { grep "foo" } will be considered as > shell command and we need to erase the braces part of it to make it a > valid shell command. >>> + >>> + *cpos = ' '; >>> + } >>> + >>> + if (sh_cmd) >>> + *sh_cmd++ = '\0'; >>> + >>> + return sh_cmd; >> >> This butchers the string passed to execute_command. Are you sure all >> the callers of execute_command can safely deal with that? What if the >> string is a constant string, for example? >> > The new code path will be executed only when one will enter a command > containing pipeline between gdb and shell. In that case the string > passed to execute_command must not be a constant string (since it is > user input from gdb prompt). Hence we are safe. > [-- Attachment #2: gdb-shell-integration-new.patch --] [-- Type: text/x-patch, Size: 3499 bytes --] diff -rup src//gdb/top.c dst//gdb/top.c --- src//gdb/top.c 2011-06-28 00:51:50.000000000 +0530 +++ dst//gdb/top.c 2011-07-16 23:05:46.745978992 +0530 @@ -48,6 +48,7 @@ #include "event-loop.h" #include "gdbthread.h" #include "python/python.h" +#include "ui-file.h" /* readline include files. */ #include "readline/readline.h" @@ -358,6 +359,68 @@ prepare_execute_command (void) return cleanup; } +char * +parse_for_shell_command (char *p) +{ + char *sh_cmd, *cpos, *spos, *epos; + int quote_cnt = 0; + + if ((sh_cmd = strchr (p, '|')) != NULL) + { + spos = p; + epos = p + strlen (p) - 1; + + for (;;) + { + for (cpos = spos; (cpos = memchr (cpos, '"', (sh_cmd-cpos))) != NULL; cpos++) + quote_cnt++; + spos = (sh_cmd + 1); + if ((quote_cnt % 2) == 0 || (sh_cmd = strchr (spos, '|')) == NULL) + break; + } + + if (sh_cmd == NULL) + return NULL; + + cpos = spos; + while (isspace(*cpos)) + cpos++; + + if (*cpos != '{') + return parse_for_shell_command (cpos); + + *cpos = ' '; + + cpos = epos; + while (isspace(*cpos)) + cpos--; + + if (*cpos != '}') + return parse_for_shell_command (cpos); + + *cpos = ' '; + } + + if (sh_cmd) + *sh_cmd++ = '\0'; + + return sh_cmd; +} + +/* Run execute_command for P and FROM_TTY. Write output in pipe, + do not display it to the screen. */ + +void +execute_command_to_pipe (char *p, int from_tty, FILE *pipe) +{ + FILE *file; + + file = gdb_modify_io (gdb_stdout, pipe); + execute_command (p, from_tty); + pipe = gdb_modify_io (gdb_stdout, file); + pclose (pipe); +} + /* Execute the line P as a command, in the current user context. Pass FROM_TTY as second argument to the defining function. */ @@ -368,7 +431,16 @@ execute_command (char *p, int from_tty) struct cmd_list_element *c; enum language flang; static int warned = 0; - char *line; + char *line, *sh_cmd; + + if ((sh_cmd = parse_for_shell_command (p)) != NULL) + { + FILE *pipe; + + pipe = popen (sh_cmd, "w"); + execute_command_to_pipe (p, from_tty, pipe); + return; + } cleanup = prepare_execute_command (); diff -rup src//gdb/ui-file.c dst//gdb/ui-file.c --- src//gdb/ui-file.c 2011-05-14 11:14:36.000000000 +0530 +++ dst//gdb/ui-file.c 2011-07-15 13:49:34.999910332 +0530 @@ -617,6 +617,21 @@ struct ui_file * stdio_fileopen (FILE *file) { return stdio_file_new (file, 0); + +} + +FILE * +gdb_modify_io (struct ui_file *file, FILE *iostream_new) +{ + FILE *iostream_old; + struct stdio_file *stdio = ui_file_data (file); + + if (stdio->magic != &stdio_file_magic) + internal_error (__FILE__, __LINE__, + _("gdb_modify_io: bad magic number")); + iostream_old = stdio->file; + stdio->file = iostream_new; + return iostream_old; } struct ui_file * diff -rup src//gdb/ui-file.h dst//gdb/ui-file.h --- src//gdb/ui-file.h 2011-05-13 22:58:20.000000000 +0530 +++ dst//gdb/ui-file.h 2011-07-15 13:48:54.603912199 +0530 @@ -126,6 +126,9 @@ extern struct ui_file *stdio_fileopen (F /* Open NAME returning an STDIO based UI_FILE. */ extern struct ui_file *gdb_fopen (char *name, char *mode); +/* Modify the file pointer of an STDIO based UI_FILE. */ +FILE *gdb_modify_io (struct ui_file *file, FILE *iostream_new); + /* Create a file which writes to both ONE and TWO. CLOSE_ONE and CLOSE_TWO indicate whether the original files should be closed when the new file is closed. */ ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] gdb output pipelining to shell 2011-07-17 20:26 ` Abhijit Halder @ 2011-07-18 18:23 ` Abhijit Halder 2011-07-18 20:15 ` Abhijit Halder 0 siblings, 1 reply; 9+ messages in thread From: Abhijit Halder @ 2011-07-18 18:23 UTC (permalink / raw) To: gdb-patches Please don't consider this patch. This has a conflict with following syntax of of (gdb) p var | {type} address On Sat, Jul 16, 2011 at 11:35 PM, Abhijit Halder <abhijit.k.halder@gmail.com> wrote: > A small correction. Re-submitting the patch. The earlier patch was not > able to handle below situation: > (gdb) p '|' | { less } > > On Sat, Jul 16, 2011 at 3:38 PM, Abhijit Halder > <abhijit.k.halder@gmail.com> wrote: >> On Sat, Jul 16, 2011 at 3:17 PM, Eli Zaretskii <eliz@gnu.org> wrote: >>>> Date: Sat, 16 Jul 2011 14:12:35 +0530 >>>> From: Abhijit Halder <abhijit.k.halder@gmail.com> >>>> >>>> I have implemented a feature which will allow one to pass the output >>>> of any gdb command to the shell for further processing. >>> >>> Thanks. >>> >>> If this is accepted, we will need a corresponding addition to the >>> manual. >>> >>>> + for (cpos = spos; (cpos = memchr (cpos, '"', (sh_cmd-cpos))) != NULL; cpos++) >>>> + quote_cnt++; >>>> + spos = (sh_cmd + 1); >>>> + if ((quote_cnt % 2) == 0 || (sh_cmd = strchr (spos, '|')) == NULL) >>>> + break; >>> >>> I'm not sure I understand this (comments would be helpful). Are you >>> assuming that quote characters `"' in shell commands cannot be >>> escaped, e.g. with a backslash? And what about quoting with a single >>> quote character ("'")? >>> >> Any pipe ('|' character), not within double quote will be considered >> as either a bitwise-OR operator or a pipe between gdb and shell. >> String after pipe (not within double quote) will be considered as >> shell command if (and only if) it is encapsulated within opening and >> closing braces ('{' and '}') . The shell command can surely contain >> double quote, even braces. There is no validation done for shell >> command. >> >>>> + if (*cpos != '{') >>>> + return NULL; >>>> + >>>> + *cpos = ' '; >>>> + >>>> + cpos = epos; >>>> + while (isspace(*cpos)) >>>> + cpos--; >>>> + >>>> + if (*cpos != '}') >>>> + return NULL; >>> >>> What is this magic about {...} that you are removing? Again, comments >>> could help. >>> >> Here I am removing the braces from the shell command. An example will >> help in understanding this: >> (gdb) thread apply all bt | { grep "foo" } >> This will be a valid command. { grep "foo" } will be considered as >> shell command and we need to erase the braces part of it to make it a >> valid shell command. >>>> + >>>> + *cpos = ' '; >>>> + } >>>> + >>>> + if (sh_cmd) >>>> + *sh_cmd++ = '\0'; >>>> + >>>> + return sh_cmd; >>> >>> This butchers the string passed to execute_command. Are you sure all >>> the callers of execute_command can safely deal with that? What if the >>> string is a constant string, for example? >>> >> The new code path will be executed only when one will enter a command >> containing pipeline between gdb and shell. In that case the string >> passed to execute_command must not be a constant string (since it is >> user input from gdb prompt). Hence we are safe. >> > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] gdb output pipelining to shell 2011-07-18 18:23 ` Abhijit Halder @ 2011-07-18 20:15 ` Abhijit Halder 2011-07-19 8:50 ` Abhijit Halder 0 siblings, 1 reply; 9+ messages in thread From: Abhijit Halder @ 2011-07-18 20:15 UTC (permalink / raw) To: gdb-patches [-- Attachment #1: Type: text/plain, Size: 4055 bytes --] Since I was overwriting the braces by space character, this could essentially change a valid gdb command having braces after pipe. Here is the example: (gdb) p argc | {int} &argc I have modified the patch to defer the any overwrite (and essentially the modification) of actual input string for very last moment when the a sub-string of a given input in gdb prompt is qualified to be in a valid format of shell command. I am re-submitting the patch for review and comments with the necessary corrections in place. Please do comment on the changes. top.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- ui-file.c | 15 ++++++++++++ ui-file.h | 3 ++ 3 files changed, 94 insertions(+), 1 deletion(-) Regards, Abhijit Halder On Mon, Jul 18, 2011 at 11:31 PM, Abhijit Halder <abhijit.k.halder@gmail.com> wrote: > Please don't consider this patch. This has a conflict with following > syntax of of > (gdb) p var | {type} address > > On Sat, Jul 16, 2011 at 11:35 PM, Abhijit Halder > <abhijit.k.halder@gmail.com> wrote: >> A small correction. Re-submitting the patch. The earlier patch was not >> able to handle below situation: >> (gdb) p '|' | { less } >> >> On Sat, Jul 16, 2011 at 3:38 PM, Abhijit Halder >> <abhijit.k.halder@gmail.com> wrote: >>> On Sat, Jul 16, 2011 at 3:17 PM, Eli Zaretskii <eliz@gnu.org> wrote: >>>>> Date: Sat, 16 Jul 2011 14:12:35 +0530 >>>>> From: Abhijit Halder <abhijit.k.halder@gmail.com> >>>>> >>>>> I have implemented a feature which will allow one to pass the output >>>>> of any gdb command to the shell for further processing. >>>> >>>> Thanks. >>>> >>>> If this is accepted, we will need a corresponding addition to the >>>> manual. >>>> >>>>> + for (cpos = spos; (cpos = memchr (cpos, '"', (sh_cmd-cpos))) != NULL; cpos++) >>>>> + quote_cnt++; >>>>> + spos = (sh_cmd + 1); >>>>> + if ((quote_cnt % 2) == 0 || (sh_cmd = strchr (spos, '|')) == NULL) >>>>> + break; >>>> >>>> I'm not sure I understand this (comments would be helpful). Are you >>>> assuming that quote characters `"' in shell commands cannot be >>>> escaped, e.g. with a backslash? And what about quoting with a single >>>> quote character ("'")? >>>> >>> Any pipe ('|' character), not within double quote will be considered >>> as either a bitwise-OR operator or a pipe between gdb and shell. >>> String after pipe (not within double quote) will be considered as >>> shell command if (and only if) it is encapsulated within opening and >>> closing braces ('{' and '}') . The shell command can surely contain >>> double quote, even braces. There is no validation done for shell >>> command. >>> >>>>> + if (*cpos != '{') >>>>> + return NULL; >>>>> + >>>>> + *cpos = ' '; >>>>> + >>>>> + cpos = epos; >>>>> + while (isspace(*cpos)) >>>>> + cpos--; >>>>> + >>>>> + if (*cpos != '}') >>>>> + return NULL; >>>> >>>> What is this magic about {...} that you are removing? Again, comments >>>> could help. >>>> >>> Here I am removing the braces from the shell command. An example will >>> help in understanding this: >>> (gdb) thread apply all bt | { grep "foo" } >>> This will be a valid command. { grep "foo" } will be considered as >>> shell command and we need to erase the braces part of it to make it a >>> valid shell command. >>>>> + >>>>> + *cpos = ' '; >>>>> + } >>>>> + >>>>> + if (sh_cmd) >>>>> + *sh_cmd++ = '\0'; >>>>> + >>>>> + return sh_cmd; >>>> >>>> This butchers the string passed to execute_command. Are you sure all >>>> the callers of execute_command can safely deal with that? What if the >>>> string is a constant string, for example? >>>> >>> The new code path will be executed only when one will enter a command >>> containing pipeline between gdb and shell. In that case the string >>> passed to execute_command must not be a constant string (since it is >>> user input from gdb prompt). Hence we are safe. >>> >> > [-- Attachment #2: gdb-shell-integration-correction.patch --] [-- Type: text/x-patch, Size: 3543 bytes --] diff -rup src//gdb/top.c dst//gdb/top.c --- src//gdb/top.c 2011-06-28 00:51:50.000000000 +0530 +++ dst//gdb/top.c 2011-07-19 00:10:51.623144702 +0530 @@ -48,6 +48,7 @@ #include "event-loop.h" #include "gdbthread.h" #include "python/python.h" +#include "ui-file.h" /* readline include files. */ #include "readline/readline.h" @@ -358,6 +359,71 @@ prepare_execute_command (void) return cleanup; } +char * +parse_for_shell_command (char *p) +{ + char *sh_cmd, *cpos, *spos, *epos; + int quote_cnt = 0; + + if ((sh_cmd = strchr (p, '|')) != NULL) + { + spos = p; + epos = p + strlen (p) - 1; + + for (;;) + { + for (cpos = spos; (cpos = memchr (cpos, '"', (sh_cmd-cpos))) != NULL; cpos++) + quote_cnt++; + spos = (sh_cmd + 1); + if ((quote_cnt % 2) == 0 || (sh_cmd = strchr (spos, '|')) == NULL) + break; + } + + if (sh_cmd == NULL) + return NULL; + + cpos = spos; + while (isspace(*cpos)) + cpos++; + + if (*cpos != '{') + return parse_for_shell_command (cpos); + + spos = cpos; + + cpos = epos; + while (isspace(*cpos)) + cpos--; + + if (*cpos != '}') + return parse_for_shell_command (cpos); + + epos = cpos; + } + + if (sh_cmd) + { + *spos = *epos = ' '; + *sh_cmd++ = '\0'; + } + + return sh_cmd; +} + +/* Run execute_command for P and FROM_TTY. Write output in pipe, + do not display it to the screen. */ + +void +execute_command_to_pipe (char *p, int from_tty, FILE *pipe) +{ + FILE *file; + + file = gdb_modify_io (gdb_stdout, pipe); + execute_command (p, from_tty); + pipe = gdb_modify_io (gdb_stdout, file); + pclose (pipe); +} + /* Execute the line P as a command, in the current user context. Pass FROM_TTY as second argument to the defining function. */ @@ -368,7 +434,16 @@ execute_command (char *p, int from_tty) struct cmd_list_element *c; enum language flang; static int warned = 0; - char *line; + char *line, *sh_cmd; + + if ((sh_cmd = parse_for_shell_command (p)) != NULL) + { + FILE *pipe; + + pipe = popen (sh_cmd, "w"); + execute_command_to_pipe (p, from_tty, pipe); + return; + } cleanup = prepare_execute_command (); diff -rup src//gdb/ui-file.c dst//gdb/ui-file.c --- src//gdb/ui-file.c 2011-05-14 11:14:36.000000000 +0530 +++ dst//gdb/ui-file.c 2011-07-15 13:49:34.999910332 +0530 @@ -617,6 +617,21 @@ struct ui_file * stdio_fileopen (FILE *file) { return stdio_file_new (file, 0); + +} + +FILE * +gdb_modify_io (struct ui_file *file, FILE *iostream_new) +{ + FILE *iostream_old; + struct stdio_file *stdio = ui_file_data (file); + + if (stdio->magic != &stdio_file_magic) + internal_error (__FILE__, __LINE__, + _("gdb_modify_io: bad magic number")); + iostream_old = stdio->file; + stdio->file = iostream_new; + return iostream_old; } struct ui_file * diff -rup src//gdb/ui-file.h dst//gdb/ui-file.h --- src//gdb/ui-file.h 2011-05-13 22:58:20.000000000 +0530 +++ dst//gdb/ui-file.h 2011-07-15 13:48:54.603912199 +0530 @@ -126,6 +126,9 @@ extern struct ui_file *stdio_fileopen (F /* Open NAME returning an STDIO based UI_FILE. */ extern struct ui_file *gdb_fopen (char *name, char *mode); +/* Modify the file pointer of an STDIO based UI_FILE. */ +FILE *gdb_modify_io (struct ui_file *file, FILE *iostream_new); + /* Create a file which writes to both ONE and TWO. CLOSE_ONE and CLOSE_TWO indicate whether the original files should be closed when the new file is closed. */ ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] gdb output pipelining to shell 2011-07-18 20:15 ` Abhijit Halder @ 2011-07-19 8:50 ` Abhijit Halder 2011-07-19 10:31 ` Abhijit Halder 0 siblings, 1 reply; 9+ messages in thread From: Abhijit Halder @ 2011-07-19 8:50 UTC (permalink / raw) To: gdb-patches Further concern. The last submitted patch does not work in following scenario: (gdb) p argc | {int} &argc | {vim -} I think now I should take a pause and refrain myself of doing patch submission in this thread for some time! Regards, Abhijit Halder On Tue, Jul 19, 2011 at 12:31 AM, Abhijit Halder <abhijit.k.halder@gmail.com> wrote: > Since I was overwriting the braces by space character, this could > essentially change a valid gdb command having braces after pipe. > Here is the example: > (gdb) p argc | {int} &argc > > I have modified the patch to defer the any overwrite (and essentially > the modification) of actual input string for very last moment when the > a sub-string of a given input in gdb prompt is qualified to be in a > valid format of shell command. > > I am re-submitting the patch for review and comments with the > necessary corrections in place. Please do comment on the changes. > > top.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- > ui-file.c | 15 ++++++++++++ > ui-file.h | 3 ++ > 3 files changed, 94 insertions(+), 1 deletion(-) > > Regards, > Abhijit Halder > > > On Mon, Jul 18, 2011 at 11:31 PM, Abhijit Halder > <abhijit.k.halder@gmail.com> wrote: >> Please don't consider this patch. This has a conflict with following >> syntax of of >> (gdb) p var | {type} address >> >> On Sat, Jul 16, 2011 at 11:35 PM, Abhijit Halder >> <abhijit.k.halder@gmail.com> wrote: >>> A small correction. Re-submitting the patch. The earlier patch was not >>> able to handle below situation: >>> (gdb) p '|' | { less } >>> >>> On Sat, Jul 16, 2011 at 3:38 PM, Abhijit Halder >>> <abhijit.k.halder@gmail.com> wrote: >>>> On Sat, Jul 16, 2011 at 3:17 PM, Eli Zaretskii <eliz@gnu.org> wrote: >>>>>> Date: Sat, 16 Jul 2011 14:12:35 +0530 >>>>>> From: Abhijit Halder <abhijit.k.halder@gmail.com> >>>>>> >>>>>> I have implemented a feature which will allow one to pass the output >>>>>> of any gdb command to the shell for further processing. >>>>> >>>>> Thanks. >>>>> >>>>> If this is accepted, we will need a corresponding addition to the >>>>> manual. >>>>> >>>>>> + for (cpos = spos; (cpos = memchr (cpos, '"', (sh_cmd-cpos))) != NULL; cpos++) >>>>>> + quote_cnt++; >>>>>> + spos = (sh_cmd + 1); >>>>>> + if ((quote_cnt % 2) == 0 || (sh_cmd = strchr (spos, '|')) == NULL) >>>>>> + break; >>>>> >>>>> I'm not sure I understand this (comments would be helpful). Are you >>>>> assuming that quote characters `"' in shell commands cannot be >>>>> escaped, e.g. with a backslash? And what about quoting with a single >>>>> quote character ("'")? >>>>> >>>> Any pipe ('|' character), not within double quote will be considered >>>> as either a bitwise-OR operator or a pipe between gdb and shell. >>>> String after pipe (not within double quote) will be considered as >>>> shell command if (and only if) it is encapsulated within opening and >>>> closing braces ('{' and '}') . The shell command can surely contain >>>> double quote, even braces. There is no validation done for shell >>>> command. >>>> >>>>>> + if (*cpos != '{') >>>>>> + return NULL; >>>>>> + >>>>>> + *cpos = ' '; >>>>>> + >>>>>> + cpos = epos; >>>>>> + while (isspace(*cpos)) >>>>>> + cpos--; >>>>>> + >>>>>> + if (*cpos != '}') >>>>>> + return NULL; >>>>> >>>>> What is this magic about {...} that you are removing? Again, comments >>>>> could help. >>>>> >>>> Here I am removing the braces from the shell command. An example will >>>> help in understanding this: >>>> (gdb) thread apply all bt | { grep "foo" } >>>> This will be a valid command. { grep "foo" } will be considered as >>>> shell command and we need to erase the braces part of it to make it a >>>> valid shell command. >>>>>> + >>>>>> + *cpos = ' '; >>>>>> + } >>>>>> + >>>>>> + if (sh_cmd) >>>>>> + *sh_cmd++ = '\0'; >>>>>> + >>>>>> + return sh_cmd; >>>>> >>>>> This butchers the string passed to execute_command. Are you sure all >>>>> the callers of execute_command can safely deal with that? What if the >>>>> string is a constant string, for example? >>>>> >>>> The new code path will be executed only when one will enter a command >>>> containing pipeline between gdb and shell. In that case the string >>>> passed to execute_command must not be a constant string (since it is >>>> user input from gdb prompt). Hence we are safe. >>>> >>> >> > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] gdb output pipelining to shell 2011-07-19 8:50 ` Abhijit Halder @ 2011-07-19 10:31 ` Abhijit Halder [not found] ` <CAOhZP9yZ01y8KY9BEjWvtXnJw1jEjTZxPcTNK6h+A9dn-WZWwQ@mail.gmail.com> 0 siblings, 1 reply; 9+ messages in thread From: Abhijit Halder @ 2011-07-19 10:31 UTC (permalink / raw) To: gdb-patches [-- Attachment #1: Type: text/plain, Size: 5247 bytes --] I have made a correction to handle possibly all the cases. Hope this is my last correction. Please bear with me. I have changed the syntax of using shell command. Here it is: (gdb) gdb command | `{ shell command }` The shell command to be executed has to be encapsulated in `{}` and not only {} as gdb command itself can have braces, no spaces between backtick and braces are allowed. Hope this constraint will be acceptable from usability point of view. Regards, Abhijit Halder On Tue, Jul 19, 2011 at 11:03 AM, Abhijit Halder <abhijit.k.halder@gmail.com> wrote: > Further concern. The last submitted patch does not work in following scenario: > (gdb) p argc | {int} &argc | {vim -} > > I think now I should take a pause and refrain myself of doing patch > submission in this thread for some time! > > Regards, > Abhijit Halder > > On Tue, Jul 19, 2011 at 12:31 AM, Abhijit Halder > <abhijit.k.halder@gmail.com> wrote: >> Since I was overwriting the braces by space character, this could >> essentially change a valid gdb command having braces after pipe. >> Here is the example: >> (gdb) p argc | {int} &argc >> >> I have modified the patch to defer the any overwrite (and essentially >> the modification) of actual input string for very last moment when the >> a sub-string of a given input in gdb prompt is qualified to be in a >> valid format of shell command. >> >> I am re-submitting the patch for review and comments with the >> necessary corrections in place. Please do comment on the changes. >> >> top.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- >> ui-file.c | 15 ++++++++++++ >> ui-file.h | 3 ++ >> 3 files changed, 94 insertions(+), 1 deletion(-) >> >> Regards, >> Abhijit Halder >> >> >> On Mon, Jul 18, 2011 at 11:31 PM, Abhijit Halder >> <abhijit.k.halder@gmail.com> wrote: >>> Please don't consider this patch. This has a conflict with following >>> syntax of of >>> (gdb) p var | {type} address >>> >>> On Sat, Jul 16, 2011 at 11:35 PM, Abhijit Halder >>> <abhijit.k.halder@gmail.com> wrote: >>>> A small correction. Re-submitting the patch. The earlier patch was not >>>> able to handle below situation: >>>> (gdb) p '|' | { less } >>>> >>>> On Sat, Jul 16, 2011 at 3:38 PM, Abhijit Halder >>>> <abhijit.k.halder@gmail.com> wrote: >>>>> On Sat, Jul 16, 2011 at 3:17 PM, Eli Zaretskii <eliz@gnu.org> wrote: >>>>>>> Date: Sat, 16 Jul 2011 14:12:35 +0530 >>>>>>> From: Abhijit Halder <abhijit.k.halder@gmail.com> >>>>>>> >>>>>>> I have implemented a feature which will allow one to pass the output >>>>>>> of any gdb command to the shell for further processing. >>>>>> >>>>>> Thanks. >>>>>> >>>>>> If this is accepted, we will need a corresponding addition to the >>>>>> manual. >>>>>> >>>>>>> + for (cpos = spos; (cpos = memchr (cpos, '"', (sh_cmd-cpos))) != NULL; cpos++) >>>>>>> + quote_cnt++; >>>>>>> + spos = (sh_cmd + 1); >>>>>>> + if ((quote_cnt % 2) == 0 || (sh_cmd = strchr (spos, '|')) == NULL) >>>>>>> + break; >>>>>> >>>>>> I'm not sure I understand this (comments would be helpful). Are you >>>>>> assuming that quote characters `"' in shell commands cannot be >>>>>> escaped, e.g. with a backslash? And what about quoting with a single >>>>>> quote character ("'")? >>>>>> >>>>> Any pipe ('|' character), not within double quote will be considered >>>>> as either a bitwise-OR operator or a pipe between gdb and shell. >>>>> String after pipe (not within double quote) will be considered as >>>>> shell command if (and only if) it is encapsulated within opening and >>>>> closing braces ('{' and '}') . The shell command can surely contain >>>>> double quote, even braces. There is no validation done for shell >>>>> command. >>>>> >>>>>>> + if (*cpos != '{') >>>>>>> + return NULL; >>>>>>> + >>>>>>> + *cpos = ' '; >>>>>>> + >>>>>>> + cpos = epos; >>>>>>> + while (isspace(*cpos)) >>>>>>> + cpos--; >>>>>>> + >>>>>>> + if (*cpos != '}') >>>>>>> + return NULL; >>>>>> >>>>>> What is this magic about {...} that you are removing? Again, comments >>>>>> could help. >>>>>> >>>>> Here I am removing the braces from the shell command. An example will >>>>> help in understanding this: >>>>> (gdb) thread apply all bt | { grep "foo" } >>>>> This will be a valid command. { grep "foo" } will be considered as >>>>> shell command and we need to erase the braces part of it to make it a >>>>> valid shell command. >>>>>>> + >>>>>>> + *cpos = ' '; >>>>>>> + } >>>>>>> + >>>>>>> + if (sh_cmd) >>>>>>> + *sh_cmd++ = '\0'; >>>>>>> + >>>>>>> + return sh_cmd; >>>>>> >>>>>> This butchers the string passed to execute_command. Are you sure all >>>>>> the callers of execute_command can safely deal with that? What if the >>>>>> string is a constant string, for example? >>>>>> >>>>> The new code path will be executed only when one will enter a command >>>>> containing pipeline between gdb and shell. In that case the string >>>>> passed to execute_command must not be a constant string (since it is >>>>> user input from gdb prompt). Hence we are safe. >>>>> >>>> >>> >> > [-- Attachment #2: gdb-shell-integration-correction.patch --] [-- Type: text/x-patch, Size: 3607 bytes --] diff -rup src//gdb/top.c dst//gdb/top.c --- src//gdb/top.c 2011-06-28 00:51:50.000000000 +0530 +++ dst//gdb/top.c 2011-07-19 11:15:38.984381163 +0530 @@ -48,6 +48,7 @@ #include "event-loop.h" #include "gdbthread.h" #include "python/python.h" +#include "ui-file.h" /* readline include files. */ #include "readline/readline.h" @@ -358,6 +359,71 @@ prepare_execute_command (void) return cleanup; } +char * +parse_for_shell_command (char *p) +{ + char *sh_cmd, *cpos, *spos, *epos; + int quote_cnt = 0; + + if ((sh_cmd = strchr (p, '|')) != NULL) + { + spos = p; + epos = p + strlen (p) - 1; + + for (;;) + { + for (cpos = spos; (cpos = memchr (cpos, '"', (sh_cmd-cpos))) != NULL; cpos++) + quote_cnt++; + spos = (sh_cmd + 1); + if ((quote_cnt % 2) == 0 || (sh_cmd = strchr (spos, '|')) == NULL) + break; + } + + if (sh_cmd == NULL) + return NULL; + + cpos = spos; + while (isspace(*cpos)) + cpos++; + + if (*cpos != '`' || *(cpos+1) != '{') + return parse_for_shell_command (cpos); + + spos = cpos; + + cpos = epos; + while (isspace(*cpos)) + cpos--; + + if (*cpos != '`' || *(cpos-1) != '}') + return parse_for_shell_command (cpos); + + epos = cpos; + } + + if (sh_cmd) + { + *spos = *(spos+1) = *epos = *(epos-1) = ' '; + *sh_cmd++ = '\0'; + } + + return sh_cmd; +} + +/* Run execute_command for P and FROM_TTY. Write output in pipe, + do not display it to the screen. */ + +void +execute_command_to_pipe (char *p, int from_tty, FILE *pipe) +{ + FILE *file; + + file = gdb_modify_io (gdb_stdout, pipe); + execute_command (p, from_tty); + pipe = gdb_modify_io (gdb_stdout, file); + pclose (pipe); +} + /* Execute the line P as a command, in the current user context. Pass FROM_TTY as second argument to the defining function. */ @@ -368,7 +434,16 @@ execute_command (char *p, int from_tty) struct cmd_list_element *c; enum language flang; static int warned = 0; - char *line; + char *line, *sh_cmd; + + if ((sh_cmd = parse_for_shell_command (p)) != NULL) + { + FILE *pipe; + + pipe = popen (sh_cmd, "w"); + execute_command_to_pipe (p, from_tty, pipe); + return; + } cleanup = prepare_execute_command (); diff -rup src//gdb/ui-file.c dst//gdb/ui-file.c --- src//gdb/ui-file.c 2011-05-14 11:14:36.000000000 +0530 +++ dst//gdb/ui-file.c 2011-07-15 13:49:34.999910332 +0530 @@ -617,6 +617,21 @@ struct ui_file * stdio_fileopen (FILE *file) { return stdio_file_new (file, 0); + +} + +FILE * +gdb_modify_io (struct ui_file *file, FILE *iostream_new) +{ + FILE *iostream_old; + struct stdio_file *stdio = ui_file_data (file); + + if (stdio->magic != &stdio_file_magic) + internal_error (__FILE__, __LINE__, + _("gdb_modify_io: bad magic number")); + iostream_old = stdio->file; + stdio->file = iostream_new; + return iostream_old; } struct ui_file * diff -rup src//gdb/ui-file.h dst//gdb/ui-file.h --- src//gdb/ui-file.h 2011-05-13 22:58:20.000000000 +0530 +++ dst//gdb/ui-file.h 2011-07-15 13:48:54.603912199 +0530 @@ -126,6 +126,9 @@ extern struct ui_file *stdio_fileopen (F /* Open NAME returning an STDIO based UI_FILE. */ extern struct ui_file *gdb_fopen (char *name, char *mode); +/* Modify the file pointer of an STDIO based UI_FILE. */ +FILE *gdb_modify_io (struct ui_file *file, FILE *iostream_new); + /* Create a file which writes to both ONE and TWO. CLOSE_ONE and CLOSE_TWO indicate whether the original files should be closed when the new file is closed. */ ^ permalink raw reply [flat|nested] 9+ messages in thread
[parent not found: <CAOhZP9yZ01y8KY9BEjWvtXnJw1jEjTZxPcTNK6h+A9dn-WZWwQ@mail.gmail.com>]
* Re: [PATCH] gdb output pipelining to shell [not found] ` <CAOhZP9yZ01y8KY9BEjWvtXnJw1jEjTZxPcTNK6h+A9dn-WZWwQ@mail.gmail.com> @ 2011-07-20 13:17 ` Abhijit Halder 0 siblings, 0 replies; 9+ messages in thread From: Abhijit Halder @ 2011-07-20 13:17 UTC (permalink / raw) To: gdb-patches Hi, I am pretty new in this community. Just curious to know whether I will get any notification if my patch get accepted or rejected. Thanks, Abhijit Halder > > On Tue, Jul 19, 2011 at 2:20 PM, Abhijit Halder <abhijit.k.halder@gmail.com> wrote: >> >> I have made a correction to handle possibly all the cases. Hope this >> is my last correction. Please bear with me. >> >> I have changed the syntax of using shell command. Here it is: >> (gdb) gdb command | `{ shell command }` >> >> The shell command to be executed has to be encapsulated in `{}` and >> not only {} as gdb command itself can have braces, no spaces between >> backtick and braces are allowed. Hope this constraint will be >> acceptable from usability point of view. >> >> Regards, >> Abhijit Halder >> >> On Tue, Jul 19, 2011 at 11:03 AM, Abhijit Halder >> <abhijit.k.halder@gmail.com> wrote: >> > Further concern. The last submitted patch does not work in following scenario: >> > (gdb) p argc | {int} &argc | {vim -} >> > >> > I think now I should take a pause and refrain myself of doing patch >> > submission in this thread for some time! >> > >> > Regards, >> > Abhijit Halder >> > >> > On Tue, Jul 19, 2011 at 12:31 AM, Abhijit Halder >> > <abhijit.k.halder@gmail.com> wrote: >> >> Since I was overwriting the braces by space character, this could >> >> essentially change a valid gdb command having braces after pipe. >> >> Here is the example: >> >> (gdb) p argc | {int} &argc >> >> >> >> I have modified the patch to defer the any overwrite (and essentially >> >> the modification) of actual input string for very last moment when the >> >> a sub-string of a given input in gdb prompt is qualified to be in a >> >> valid format of shell command. >> >> >> >> I am re-submitting the patch for review and comments with the >> >> necessary corrections in place. Please do comment on the changes. >> >> >> >> top.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- >> >> ui-file.c | 15 ++++++++++++ >> >> ui-file.h | 3 ++ >> >> 3 files changed, 94 insertions(+), 1 deletion(-) >> >> >> >> Regards, >> >> Abhijit Halder >> >> >> >> >> >> On Mon, Jul 18, 2011 at 11:31 PM, Abhijit Halder >> >> <abhijit.k.halder@gmail.com> wrote: >> >>> Please don't consider this patch. This has a conflict with following >> >>> syntax of of >> >>> (gdb) p var | {type} address >> >>> >> >>> On Sat, Jul 16, 2011 at 11:35 PM, Abhijit Halder >> >>> <abhijit.k.halder@gmail.com> wrote: >> >>>> A small correction. Re-submitting the patch. The earlier patch was not >> >>>> able to handle below situation: >> >>>> (gdb) p '|' | { less } >> >>>> >> >>>> On Sat, Jul 16, 2011 at 3:38 PM, Abhijit Halder >> >>>> <abhijit.k.halder@gmail.com> wrote: >> >>>>> On Sat, Jul 16, 2011 at 3:17 PM, Eli Zaretskii <eliz@gnu.org> wrote: >> >>>>>>> Date: Sat, 16 Jul 2011 14:12:35 +0530 >> >>>>>>> From: Abhijit Halder <abhijit.k.halder@gmail.com> >> >>>>>>> >> >>>>>>> I have implemented a feature which will allow one to pass the output >> >>>>>>> of any gdb command to the shell for further processing. >> >>>>>> >> >>>>>> Thanks. >> >>>>>> >> >>>>>> If this is accepted, we will need a corresponding addition to the >> >>>>>> manual. >> >>>>>> >> >>>>>>> + for (cpos = spos; (cpos = memchr (cpos, '"', (sh_cmd-cpos))) != NULL; cpos++) >> >>>>>>> + quote_cnt++; >> >>>>>>> + spos = (sh_cmd + 1); >> >>>>>>> + if ((quote_cnt % 2) == 0 || (sh_cmd = strchr (spos, '|')) == NULL) >> >>>>>>> + break; >> >>>>>> >> >>>>>> I'm not sure I understand this (comments would be helpful). Are you >> >>>>>> assuming that quote characters `"' in shell commands cannot be >> >>>>>> escaped, e.g. with a backslash? And what about quoting with a single >> >>>>>> quote character ("'")? >> >>>>>> >> >>>>> Any pipe ('|' character), not within double quote will be considered >> >>>>> as either a bitwise-OR operator or a pipe between gdb and shell. >> >>>>> String after pipe (not within double quote) will be considered as >> >>>>> shell command if (and only if) it is encapsulated within opening and >> >>>>> closing braces ('{' and '}') . The shell command can surely contain >> >>>>> double quote, even braces. There is no validation done for shell >> >>>>> command. >> >>>>> >> >>>>>>> + if (*cpos != '{') >> >>>>>>> + return NULL; >> >>>>>>> + >> >>>>>>> + *cpos = ' '; >> >>>>>>> + >> >>>>>>> + cpos = epos; >> >>>>>>> + while (isspace(*cpos)) >> >>>>>>> + cpos--; >> >>>>>>> + >> >>>>>>> + if (*cpos != '}') >> >>>>>>> + return NULL; >> >>>>>> >> >>>>>> What is this magic about {...} that you are removing? Again, comments >> >>>>>> could help. >> >>>>>> >> >>>>> Here I am removing the braces from the shell command. An example will >> >>>>> help in understanding this: >> >>>>> (gdb) thread apply all bt | { grep "foo" } >> >>>>> This will be a valid command. { grep "foo" } will be considered as >> >>>>> shell command and we need to erase the braces part of it to make it a >> >>>>> valid shell command. >> >>>>>>> + >> >>>>>>> + *cpos = ' '; >> >>>>>>> + } >> >>>>>>> + >> >>>>>>> + if (sh_cmd) >> >>>>>>> + *sh_cmd++ = '\0'; >> >>>>>>> + >> >>>>>>> + return sh_cmd; >> >>>>>> >> >>>>>> This butchers the string passed to execute_command. Are you sure all >> >>>>>> the callers of execute_command can safely deal with that? What if the >> >>>>>> string is a constant string, for example? >> >>>>>> >> >>>>> The new code path will be executed only when one will enter a command >> >>>>> containing pipeline between gdb and shell. In that case the string >> >>>>> passed to execute_command must not be a constant string (since it is >> >>>>> user input from gdb prompt). Hence we are safe. >> >>>>> >> >>>> >> >>> >> >> >> > > ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2011-07-20 12:34 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-16 10:09 [PATCH] gdb output pipelining to shell Abhijit Halder
2011-07-16 14:49 ` Eli Zaretskii
2011-07-16 18:06 ` Abhijit Halder
2011-07-17 20:26 ` Abhijit Halder
2011-07-18 18:23 ` Abhijit Halder
2011-07-18 20:15 ` Abhijit Halder
2011-07-19 8:50 ` Abhijit Halder
2011-07-19 10:31 ` Abhijit Halder
[not found] ` <CAOhZP9yZ01y8KY9BEjWvtXnJw1jEjTZxPcTNK6h+A9dn-WZWwQ@mail.gmail.com>
2011-07-20 13:17 ` Abhijit Halder
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox