public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [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

* 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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).