* [RFC] A new command 'grep'
@ 2012-01-02 5:01 Siva Chandra
2012-01-02 8:54 ` Eli Zaretskii
0 siblings, 1 reply; 7+ messages in thread
From: Siva Chandra @ 2012-01-02 5:01 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 2163 bytes --]
Hi all,
Attached is a patch which implements a 'grep' command using the GDB
Python API. The idea behind the 'grep' command is as follows. We often
have deep data structures and are probably interested in some one
particular field or value embedded somewhere deep in that data
structure. For such cases, instead of typing the complete expression
for the field, we can use the 'grep' command to lookup the field or
value of interest. A simple example is as follows:
struct SimpleStruct
{
int int_val;
double double_val;
};
struct SimpleStruct ss;
ss.int_val = 10;
ss.double_val = 1.11;
Examples of grepping for fields:
(gdb) grep int ss
ss.int_val = (int) 10
(gdb) grep dou ss
ss.double_val = (double) 1.11
Examples of grepping for values:
(gdb) grep 10 ss
ss.int_val = (int) 10
(gdb) grep "1\\." ss
ss.double_val = (double) 1.11
In general, one can grep for any matching regular expression in any
valid expression. Few points to note:
1. To restrict searches to values or fields, one can use the sub
commands 'grep value' or 'grep field' respectively.
2. The value grep looks for matches in scalar and string values only.
3. The search goes as deep as the data structure of the expression
with one exception; It does not grep through union values unless it
finds a field selector for that union value. A field selector is a
user defined class with a specific interface which helps the grep
command select the appropriate field of the union to grep through. The
patch includes a field selector, which selects all fields, as an
example.
Thanks,
Siva Chandra
2012-01-02 Siva Chandra <sivachandra@google.com>
New command 'grep' which helps to grep through field names and values
of expressions in scope.
* data-directory/Makefile.in: Add gdb/command/grep.py
* python/lib/gdb/command/grep.py: Implemention of the 'grep'
command using the GDB Python API.
* testsuite/gdb.python/Makefile.in: Add py-grep to EXECUTABLES
* testsuite/gdb.python/py-grep.c: C program used for testing
the new 'grep' command.
* testsuite/gdb-python/py-grep.exp: Tests for the new 'grep'
command.
[-- Attachment #2: grep_command_patch_v1.txt --]
[-- Type: text/plain, Size: 24452 bytes --]
diff -rupN src/gdb/data-directory/Makefile.in src_grep/gdb/data-directory/Makefile.in
--- src/gdb/data-directory/Makefile.in 2011-08-17 16:11:20.000000000 +0530
+++ src_grep/gdb/data-directory/Makefile.in 2011-12-11 17:38:40.851766467 +0530
@@ -58,7 +58,8 @@ PYTHON_FILES = \
gdb/prompt.py \
gdb/command/__init__.py \
gdb/command/pretty_printers.py \
- gdb/command/prompt.py
+ gdb/command/prompt.py \
+ gdb/command/grep.py
FLAGS_TO_PASS = \
"prefix=$(prefix)" \
diff -rupN src/gdb/python/lib/gdb/command/grep.py src_grep/gdb/python/lib/gdb/command/grep.py
--- src/gdb/python/lib/gdb/command/grep.py 1970-01-01 05:30:00.000000000 +0530
+++ src_grep/gdb/python/lib/gdb/command/grep.py 2012-01-02 10:20:07.565936926 +0530
@@ -0,0 +1,430 @@
+# GDB 'grep' command.
+# Copyright (C) 2012 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""Implementation of the GDB 'grep' command using the GDB Python API"""
+
+from collections import deque
+import gdb
+import re
+
+class GrepBase(object):
+ """A base class for classes which can grep through values of a particular
+ type. See below for implementation of the different sub classes.
+ """
+
+ def grep(self, regex, name, path, value, grep_field, grep_value):
+ """The method which should perform the actual grep action.
+ The sub classes should override this method to reflect the type specfic
+ grep operation.
+
+ Arguments:
+ regex: The regular expression to match names.
+ name: The name which has to be matched with the regular expression.
+ path: The path (as in the expression) to the current value.
+ value: The value to be grepped.
+ grep_field: A boolean value to indicate whether the field name
+ should be matched or not.
+ grep_value: A boolean value to indicate whether the value should be
+ matched or not.
+ """
+ print "Cannot yet grep through values of type %s." % str(value.type)
+
+
+class GrepScalar(GrepBase):
+ """A class to grep through values which are of a scalar type."""
+
+ def __init__(self, grep_command):
+ """
+ Arguments:
+ grep_command: The command object which wants to do the grep
+ operation.
+ """
+ self._grep_command = grep_command
+
+ def grep(self, regex, name, path, value, grep_field, grep_value):
+ """ The method which greps through values which are of a scalar type.
+ See GrepBase.grep for more information.
+ """
+ if ((grep_field and re.search(regex, name)) or
+ (grep_value and re.search(regex, str(value)))):
+ print "%s = (%s) %s" % (path, str(value.type), str(value))
+
+
+class GrepPointer(GrepBase):
+ """A class to grep through values which are of a pointer type."""
+
+ def __init__(self, grep_command):
+ """
+ Arguments:
+ grep_command: The command object which wants to do the grep
+ operation.
+ """
+ self._grep_command = grep_command
+
+ def grep(self, regex, name, path, value, grep_field, grep_value):
+ """ The method which greps through values which are of a pointer type.
+ See GrepBase.grep for more information.
+ """
+ if str(value.type.target().unqualified()) == "char":
+ try:
+ str_val = value.string()
+ if ((grep_field and re.search(regex, name)) or
+ (grep_value and re.search(regex, str_val))):
+ print "%s = (%s) \"%s\"" % (path, str(value.type), str_val)
+ return
+ except:
+ pass
+
+ if grep_field and re.search(regex, name):
+ print "%s = (%s) %s" % (path, str(value.type), str(value))
+
+ deref_value = None
+ try:
+ deref_value = value.dereference()
+ str(deref_value)
+ except RuntimeError:
+ return
+
+ self._grep_command.grep(
+ regex, name, "(*%s)" % path, deref_value, grep_field, grep_value)
+
+
+class GrepArray(GrepBase):
+ """A class to grep through values which are of an array type."""
+
+ def __init__(self, grep_command):
+ """
+ Arguments:
+ grep_command: The command object which wants to do the grep
+ operation.
+ """
+ self._grep_command = grep_command
+
+ def grep(self, regex, name, path, value, grep_field, grep_value):
+ """ The method which greps through values which are of an array type.
+ See GrepBase.grep for more information.
+ """
+ if grep_field and re.search(regex, name):
+ print ("%s = <array of elements of type '%s'>" %
+ (path, str(value.type.target())))
+
+ if grep_value:
+ array_range = value.type.range()
+ for index in range(array_range[0], array_range[1] + 1):
+ self._grep_command.grep(regex,
+ name,
+ "%s[%d]" % (path, index),
+ value[index],
+ False,
+ True)
+
+
+class GrepStruct(GrepBase):
+ """A class to grep through values which are of a struct type."""
+
+ def __init__(self, grep_command):
+ """
+ Arguments:
+ grep_command: The command object which wants to do the grep
+ operation.
+ """
+ self._grep_command = grep_command
+
+ def grep(self, regex, name, path, value, grep_field, grep_value):
+ """ The method which greps through values which are of a struct type.
+ See GrepBase.grep for more information.
+ """
+ if grep_field and re.search(regex, name):
+ print "%s = <value of type '%s'>" % (path, str(value.type))
+
+ for field in value.type.fields():
+ self._grep_command.grep(regex,
+ field.name,
+ "%s.%s" % (path, field.name),
+ value[field.name],
+ grep_field,
+ grep_value)
+
+
+class GrepUnion(GrepBase):
+ """A class to grep through values which are of a union type."""
+
+ def __init__(self, grep_command):
+ """
+ Arguments:
+ grep_command: The command object which wants to do the grep
+ operation.
+ """
+ self._grep_command = grep_command
+ self._field_selector_list = [ ]
+
+ def register_field_selector(self, selector):
+ """Method with which one can register a field selector.
+
+ Arguments:
+ selector: The field selector. It should support a method with the
+ following signature:
+ get_field_name_matcher(value)
+ The argument 'value' is the union value which has to be
+ grepped. The method should return a regular expression
+ with which the field names of the union are matched. The
+ grep method greps through a field of the union only if
+ there is a match.
+ See the class AllFieldsSelector below as an example.
+ """
+ self._field_selector_list.append(selector)
+
+ def grep(self, regex, name, path, value, grep_field, grep_value):
+ """ The method which greps through values which are of a union type.
+ See GrepBase.grep for more information.
+ """
+ if grep_field and re.search(regex, name):
+ print "%s = <value of type '%s'>" % (path, str(value.type))
+
+ for field_selector in self._field_selector_list:
+ field_matcher = field_selector.get_field_name_matcher(value)
+ if field_matcher:
+ for field in value.type.fields():
+ if re.search(field_matcher, field.name):
+ self._grep_command.grep(regex,
+ field.name,
+ "%s.%s" % (path, field.name),
+ value[field.name],
+ grep_field,
+ grep_value)
+ return
+
+
+class GrepTypedef(GrepBase):
+ """A class to grep through values which are of a typedef type."""
+
+ def __init__(self, grep_command):
+ """
+ Arguments:
+ grep_command: The command object which wants to do the grep
+ operation.
+ """
+ self._grep_command = grep_command
+
+ def grep(self, regex, name, path, value, grep_field, grep_value):
+ """ The method which greps through values which are of a typdef type.
+ See GrepBase.grep for more information.
+ """
+ base_type_value = value.cast(value.type.strip_typedefs())
+ self._grep_command.grep(
+ regex, name, path, base_type_value, grep_field, grep_value)
+
+
+class GrepUtils(object):
+ """A class of utilities for implementing 'grep' and it's sub commands."""
+
+ @staticmethod
+ def parse_arg_str(arg_str):
+ """A function to help parse the arguments to 'grep' and its sub
+ commands.
+
+ Arguments:
+ arg_str: The argument string as passed to the 'grep' or its sub
+ commands.
+
+ Returns:
+ A 3-tuple of the form (regex, expr, value) where
+ i. regex is the regular expression passed to the command,
+ ii. expr is the expression whose value has to be 'grepped' with the
+ regex,
+ iii. value is the value of the expression.
+
+ Raises:
+ gdb.GdbError if insufficient arguments are provided in the argument
+ string, or if the expression given in the argument string does not
+ evaluate to any value in the current context.
+ """
+ args = gdb.string_to_argv(arg_str)
+ if len(args) < 2:
+ raise gdb.GdbError(
+ "ERROR: 'grep' and its sub commands need two arguments.")
+
+ regex = args[0]
+ expr = ""
+ for i in range(1, len(args) - 1):
+ expr += args[i] + " "
+ expr += args[len(args) - 1]
+
+ value = None
+ try:
+ value = gdb.parse_and_eval(expr)
+ except:
+ raise gdb.GdbError(
+ "ERROR: '%s' does not evaluate to any value in the current "
+ "context." % expr)
+
+ return (regex, expr, value)
+
+
+class GrepCommand(gdb.Command):
+ """Command to 'grep' for field names and values in expressions.
+
+ Usage: grep [OPTION] REGEX EXPR
+
+ OPTION - An optional argument which can be either 'field' or 'value'.
+ If it is 'value', then only values are matched with the REGEX. If it
+ is 'field', then only field names are matched with the REGEX.
+
+ REGEX - A regular expression in double quotes if it contains spaces.
+ EXPR - A valid expression in the current scope.
+
+ The command looks for values (of scalar, enum and string types) and field
+ names matching with the REGEX. It scans through the value of EXPR top-down
+ to look for matches. "Top-down" here means starting from the EXPR itself, to
+ the names and values of the fields (if any) of the type of the EXPR value,
+ and right down to the leaf scalar field names and values of these fields.
+ """
+
+ def __init__(self):
+ super(GrepCommand, self).__init__(name = "grep",
+ command_class = gdb.COMMAND_DATA,
+ prefix = True)
+ self.init_env()
+
+ def init_env(self):
+ """Initializes the internal environment of the command."""
+ self._type_to_greper_map = self._get_type_to_greper_map()
+ self._bfs_queue = deque([ ])
+
+ def register_union_field_selector(self, field_selector):
+ """Registers a field selector with the union grepper.
+ See GrepUnion.register_field_selector for more information.
+ """
+ self._type_to_greper_map[gdb.TYPE_CODE_UNION].register_field_selector(
+ field_selector)
+
+ def _get_type_to_greper_map(self):
+ """An internal method which returns type code to grepper map."""
+ return {
+ gdb.TYPE_CODE_PTR : GrepPointer(self),
+ gdb.TYPE_CODE_ARRAY : GrepArray(self),
+ gdb.TYPE_CODE_STRUCT : GrepStruct(self),
+ gdb.TYPE_CODE_UNION : GrepUnion(self),
+ gdb.TYPE_CODE_ENUM : GrepScalar(self),
+ gdb.TYPE_CODE_INT : GrepScalar(self),
+ gdb.TYPE_CODE_FLT : GrepScalar(self),
+ gdb.TYPE_CODE_CHAR : GrepScalar(self),
+ gdb.TYPE_CODE_BOOL : GrepScalar(self),
+ gdb.TYPE_CODE_TYPEDEF : GrepTypedef(self)
+ }
+
+ def grep(self, regex, name, path, value, grep_field, grep_value):
+ """The function to request the 'grep' for a value or a field.
+
+ NOTE: One should invoke the 'start' function to beging the search.
+ """
+ self._bfs_queue.append(
+ (regex, name, path, value, grep_field, grep_value))
+
+ def start(self):
+ """The function which starts the search once a 'grep' has been requested.
+
+ It does something useful if invoked only after making a request with the
+ 'grep' function.
+ """
+ while len(self._bfs_queue) > 0:
+ (regex, name, path, value, grep_field, grep_value) = (
+ self._bfs_queue[0])
+
+ type_code = value.type.code
+ if type_code in self._type_to_greper_map:
+ greper = self._type_to_greper_map[type_code]
+ greper.grep(regex, name, path, value, grep_field, grep_value)
+
+ self._bfs_queue.popleft()
+
+ def invoke(self, arg_str, from_tty):
+ (regex, expr, value) = GrepUtils.parse_arg_str(arg_str)
+ self.grep(regex, expr, expr, value, True, True)
+ self.start()
+
+
+class GrepFieldCommand(GrepCommand):
+ """Command to 'grep' for field names in expressions.
+
+ Usage: grep field REGEX EXPR
+
+ REGEX is a regular expression in double quotes if it contains spaces.
+ EXPR is a valid expression in the current scope.
+
+ The command looks for field names matching with the REGEX. It scans through
+ the value of EXPR top-down to look for matches. "Top-down" here means
+ starting from the EXPR itself, to the names of the fields (if any) of the
+ type of the EXPR value, and right down to the leaf scalar field names of
+ these fields.
+ """
+
+ def __init__(self):
+ super(GrepCommand, self).__init__(name = "grep field",
+ command_class = gdb.COMMAND_DATA)
+ self.init_env()
+
+ def invoke(self, arg_str, from_tty):
+ (regex, expr, value) = GrepUtils.parse_arg_str(arg_str)
+ self.grep(regex, expr, expr, value, True, False)
+ self.start()
+
+
+class GrepValueCommand(GrepCommand):
+ """Command to 'grep' for field values in expressions.
+
+ Usage: grep value REGEX EXPR
+
+ REGEX is a regular expression in double quotes if it contains spaces.
+ EXPR is a valid expression in the current scope.
+
+ The command looks for values (of scalar, enum and string fields) matching
+ with the REGEX. It scans through the value of EXPR top-down
+ to look for matches. "Top-down" here means starting from the EXPR itself, to
+ the values of the fields (if any) of the type of the EXPR value, and right
+ down to the values of the leaf scalar fields of these fields.
+ """
+
+ def __init__(self):
+ super(GrepCommand, self).__init__(name = "grep value",
+ command_class = gdb.COMMAND_DATA)
+ self.init_env()
+
+ def invoke(self, arg_str, from_tty):
+ (regex, expr, value) = GrepUtils.parse_arg_str(arg_str)
+ self.grep(regex, expr, expr, value, False, True)
+ self.start()
+
+
+gc = GrepCommand()
+gfc = GrepFieldCommand()
+gvc = GrepValueCommand()
+
+class AllFieldsSelector(object):
+ """A union field selector which selects all fields.
+ It is defined here as an example and for testing purposes.
+
+ See GrepUnion.register_field_selector for more information.
+ """
+
+ def get_field_name_matcher(self, value):
+ """Returns an all matching regular expression."""
+ return ".*"
+
+def register_union_field_selector(field_selector):
+ gc.register_union_field_selector(field_selector)
+ gfc.register_union_field_selector(field_selector)
+ gvc.register_union_field_selector(field_selector)
diff -rupN src/gdb/testsuite/gdb.python/Makefile.in src_grep/gdb/testsuite/gdb.python/Makefile.in
--- src/gdb/testsuite/gdb.python/Makefile.in 2011-05-16 19:26:40.000000000 +0530
+++ src_grep/gdb/testsuite/gdb.python/Makefile.in 2011-12-11 17:40:06.341794630 +0530
@@ -4,7 +4,8 @@ srcdir = @srcdir@
EXECUTABLES = py-type py-value py-prettyprint py-template py-block \
py-symbol py-mi py-breakpoint py-inferior py-infthread \
py-shared python lib-types py-events py-evthreads py-frame \
- py-mi py-pp-maint py-progspace py-section-script py-objfile
+ py-mi py-pp-maint py-progspace py-section-script py-objfile \
+ py-grep
MISCELLANEOUS = py-shared-sl.sl
diff -rupN src/gdb/testsuite/gdb.python/py-grep.c src_grep/gdb/testsuite/gdb.python/py-grep.c
--- src/gdb/testsuite/gdb.python/py-grep.c 1970-01-01 05:30:00.000000000 +0530
+++ src_grep/gdb/testsuite/gdb.python/py-grep.c 2011-12-31 11:29:58.342047729 +0530
@@ -0,0 +1,79 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2012 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+struct SimpleStruct
+{
+ int int_val;
+ double double_val;
+};
+
+struct ComplexStruct_1
+{
+ struct SimpleStruct ss;
+ char* str_val;
+};
+
+struct ComplexStruct_2
+{
+ struct ComplexStruct_1 cs1;
+ int int_array[10];
+ int* int_ptr;
+};
+
+union UnionOfStructs
+{
+ struct SimpleStruct ss;
+ struct ComplexStruct_1 cs1;
+ struct ComplexStruct_2 cs2;
+};
+
+typedef union UnionOfStructs TheType;
+
+int
+main (void)
+{
+ int i;
+ char* str_val = "I am a string";
+ char char_array[] =
+ { 'n', 'o', 't', ' ' , 'a' , ' ', 's', 't', 'r', 'i', 'n', 'g' };
+
+ char* ptr_to_char_array = char_array;
+
+ struct SimpleStruct ss;
+ ss.int_val = 10;
+ ss.double_val = 1.11;
+
+ struct ComplexStruct_1 cs1;
+ cs1.ss = ss;
+ cs1.str_val = "embedded string value";
+
+ struct ComplexStruct_2 cs2;
+ cs2.cs1 = cs1;
+ cs2.int_ptr = &i;
+ for (i = 0; i < 10; i++)
+ {
+ cs2.int_array[i] = i;
+ }
+
+ union UnionOfStructs us;
+ us.cs2 = cs2;
+
+ TheType* tt = &us;
+
+ return 0; /* Break here. */
+}
diff -rupN src/gdb/testsuite/gdb.python/py-grep.exp src_grep/gdb/testsuite/gdb.python/py-grep.exp
--- src/gdb/testsuite/gdb.python/py-grep.exp 1970-01-01 05:30:00.000000000 +0530
+++ src_grep/gdb/testsuite/gdb.python/py-grep.exp 2011-12-31 11:30:19.782050107 +0530
@@ -0,0 +1,85 @@
+# Copyright (C) 2012 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the GDB testsuite. It tests the command 'grep'
+# which is implemented using the GDB-Python API.
+
+load_lib gdb-python.exp
+
+set testfile "py-grep"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+ return -1
+}
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+if ![runto_main] {
+ return -1
+}
+
+gdb_breakpoint [gdb_get_line_number "Break here."]
+gdb_continue_to_breakpoint "Break here" ".*Break here.*"
+
+gdb_test "python gdb.command.grep.register_union_field_selector(gdb.command.grep.AllFieldsSelector())" ""
+
+gdb_test "grep i i" "i = \\(int\\) 10"
+
+gdb_test "grep str str_val" "str_val = \\(char \\*\\) \"I am a string\""
+
+gdb_test "grep s char_array" "char_array\\\[6\\\] = \\(char\\) 115 's'"
+
+gdb_test "grep not ptr_to_char_array" "ptr_to_char_array = \\(char \\*\\) \"not a string\""
+
+set ss_int "ss\\.int_val = \\(int\\) 10"
+set ss_double "ss\\.double_val = \\(double\\) 1\\.1.*"
+gdb_test "grep \"val\" ss" "(($ss_int\[\\n\\r\]*)|($ss_double\[\\n\\r\]*))+"
+
+gdb_test "grep value \"^10$\" ss" "$ss_int"
+
+set cs1_ss_int "cs1\\.$ss_int"
+set cs1_ss_double "cs1\\.$ss_double"
+set cs1_str "cs1\\.str_val = \\(char \\*\\) \"embedded string value\""
+gdb_test "grep field val cs1" "(($cs1_ss_int\[\\n\\r\]*)|($cs1_ss_double\[\\n\\r\]*)|($cs1_str\[\\n\\r\]*))+"
+gdb_test "grep value val cs1" "$cs1_str"
+
+set cs2_cs1_ss_int "cs2\\.$cs1_ss_int"
+set cs2_int_ptr "\\*\\(cs2\\.int_ptr\\) = \\(int\\) 10"
+gdb_test "grep \"^10$\" cs2" "(($cs2_cs1_ss_int\[\\n\\r\]*)|($cs2_int_ptr\[\\n\\r\]*))+"
+gdb_test "grep \"^9$\" cs2" "cs2\\.int_array\\\[9\\\] = \\(int\\) 9"
+
+set us_val1 "us\\.$ss_int"
+set us_val2 "us\\.$ss_double"
+set us_val3 "us\\.$cs1_str"
+set us_val4 "us\\.$cs1_ss_int"
+set us_val5 "us\\.$cs1_ss_double"
+set us_val6 "us\\.cs2\\.$cs1_str"
+set us_val7 "us\\.cs2\\.$cs1_ss_int"
+set us_val8 "us\\.cs2\\.$cs1_ss_double"
+gdb_test "grep field val us" "(($us_val1\[\\n\\r\]*)|($us_val2\[\\n\\r\]*)|($us_val3\[\\n\\r\]*)|($us_val4\[\\n\\r\]*)|($us_val5\[\\n\\r\]*)|($us_val6\[\\n\\r\]*)|($us_val7\[\\n\\r\]*)|($us_val8\[\\n\\r\]*))+"
+gdb_test "grep value val us" "(($us_val3\[\\n\\r\]*)|($us_val6\[\\n\\r\]*))+"
+
+set tt_val1 "\\(\\*tt\\)\\.$ss_int"
+set tt_val2 "\\(\\*tt\\)\\.$ss_double"
+set tt_val3 "\\(\\*tt\\)\\.$cs1_str"
+set tt_val4 "\\(\\*tt\\)\\.$cs1_ss_int"
+set tt_val5 "\\(\\*tt\\)\\.$cs1_ss_double"
+set tt_val6 "\\(\\*tt\\)\\.cs2\\.$cs1_str"
+set tt_val7 "\\(\\*tt\\)\\.cs2\\.$cs1_ss_int"
+set tt_val8 "\\(\\*tt\\)\\.cs2\\.$cs1_ss_double"
+gdb_test "grep field val tt" "(($tt_val1\[\\n\\r\]*)|($tt_val2\[\\n\\r\]*)|($tt_val3\[\\n\\r\]*)|($tt_val4\[\\n\\r\]*)|($tt_val5\[\\n\\r\]*)|($tt_val6\[\\n\\r\]*)|($tt_val7\[\\n\\r\]*)|($tt_val8\[\\n\\r\]*))+"
+gdb_test "grep value val tt" "(($tt_val3\[\\n\\r\]*)|($tt_val6\[\\n\\r\]*))+"
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [RFC] A new command 'grep'
2012-01-02 5:01 [RFC] A new command 'grep' Siva Chandra
@ 2012-01-02 8:54 ` Eli Zaretskii
2012-01-02 9:28 ` Kevin Pouget
0 siblings, 1 reply; 7+ messages in thread
From: Eli Zaretskii @ 2012-01-02 8:54 UTC (permalink / raw)
To: Siva Chandra; +Cc: gdb-patches
> Date: Mon, 2 Jan 2012 10:30:55 +0530
> From: Siva Chandra <sivachandra@google.com>
>
> Attached is a patch which implements a 'grep' command using the GDB
> Python API. The idea behind the 'grep' command is as follows. We often
> have deep data structures and are probably interested in some one
> particular field or value embedded somewhere deep in that data
> structure. For such cases, instead of typing the complete expression
> for the field, we can use the 'grep' command to lookup the field or
> value of interest.
Thanks.
I think this is the first time we receive a proposal for a command
implemented in Python. Perhaps there's a place to discuss whether
some policy is in order in this regard. E.g., the command will be
unavailable in non-Python builds, which at least needs to be
documented. There may be other aspects that are worth discussing.
If this is accepted, it will need user-level documentation.
I cannot say I like the name "grep". Users will associate that name
with the Unix command that searches through files, which is radically
different from what your command does. How about "lookup-fields"
instead?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC] A new command 'grep'
2012-01-02 8:54 ` Eli Zaretskii
@ 2012-01-02 9:28 ` Kevin Pouget
2012-01-02 9:35 ` Abhijit Halder
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Kevin Pouget @ 2012-01-02 9:28 UTC (permalink / raw)
To: Eli Zaretskii, Siva Chandra; +Cc: gdb-patches
On Mon, Jan 2, 2012 at 9:54 AM, Eli Zaretskii <eliz@gnu.org> wrote:
>
> I think this is the first time we receive a proposal for a command
> implemented in Python. Perhaps there's a place to discuss whether
> some policy is in order in this regard. E.g., the command will be
> unavailable in non-Python builds, which at least needs to be
> documented. There may be other aspects that are worth discussing.
I'm also curious about that, and maybe first of all, is there a Python
specific coding convention likely to be enforced in GNU projects
and/or GDB?
>> Date: Mon, 2 Jan 2012 10:30:55 +0530
>> From: Siva Chandra <sivachandra@google.com>
>>
>> Attached is a patch which implements a 'grep' command using the GDB
>> Python API. The idea behind the 'grep' command is as follows. We often
>> have deep data structures and are probably interested in some one
>> particular field or value embedded somewhere deep in that data
>> structure. For such cases, instead of typing the complete expression
>> for the field, we can use the 'grep' command to lookup the field or
>> value of interest.
>
> Thanks.
>
> I think this is the first time we receive a proposal for a command
> implemented in Python. Perhaps there's a place to discuss whether
> some policy is in order in this regard. E.g., the command will be
> unavailable in non-Python builds, which at least needs to be
> documented. There may be other aspects that are worth discussing.
>
> If this is accepted, it will need user-level documentation.
>
> I cannot say I like the name "grep". Users will associate that name
> with the Unix command that searches through files, which is radically
> different from what your command does. How about "lookup-fields"
> instead?
There was a discussion a few months ago about "Implementation of pipe
to pass GDB's command output to the shell" [1] which would allow to
use the 'real' grep to do a similar job, but I'm not sure about the
status of this patch, it seems not to be in the trunk yet, according
to the ChangeLog.
I didn't really look in depth at the sources, but based on you email
description, I wonder how it differs from a generic code like that
(not tested):
> (gdb) grep int ss
> ss.int_val = (int) 10
#assume set print pretty on
command = "print %s" % ss
to_grep = "int"
out = gdb.execute (command, to_string=True)
for line in out.split("\n")
if to_grep in line:
print line
good idea anyway,
thanks,
Kevin
[1]: http://sourceware.org/ml/gdb-patches/2011-08/msg00483.html
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [RFC] A new command 'grep'
2012-01-02 9:28 ` Kevin Pouget
@ 2012-01-02 9:35 ` Abhijit Halder
2012-01-02 10:17 ` Siva Chandra
2012-01-02 17:44 ` Doug Evans
2 siblings, 0 replies; 7+ messages in thread
From: Abhijit Halder @ 2012-01-02 9:35 UTC (permalink / raw)
To: Kevin Pouget; +Cc: Eli Zaretskii, Siva Chandra, gdb-patches
On Mon, Jan 2, 2012 at 2:58 PM, Kevin Pouget <kevin.pouget@gmail.com> wrote:
> On Mon, Jan 2, 2012 at 9:54 AM, Eli Zaretskii <eliz@gnu.org> wrote:
>>
>> I think this is the first time we receive a proposal for a command
>> implemented in Python. Perhaps there's a place to discuss whether
>> some policy is in order in this regard. E.g., the command will be
>> unavailable in non-Python builds, which at least needs to be
>> documented. There may be other aspects that are worth discussing.
>
> I'm also curious about that, and maybe first of all, is there a Python
> specific coding convention likely to be enforced in GNU projects
> and/or GDB?
>
>>> Date: Mon, 2 Jan 2012 10:30:55 +0530
>>> From: Siva Chandra <sivachandra@google.com>
>>>
>>> Attached is a patch which implements a 'grep' command using the GDB
>>> Python API. The idea behind the 'grep' command is as follows. We often
>>> have deep data structures and are probably interested in some one
>>> particular field or value embedded somewhere deep in that data
>>> structure. For such cases, instead of typing the complete expression
>>> for the field, we can use the 'grep' command to lookup the field or
>>> value of interest.
>>
>> Thanks.
>>
>> I think this is the first time we receive a proposal for a command
>> implemented in Python. Perhaps there's a place to discuss whether
>> some policy is in order in this regard. E.g., the command will be
>> unavailable in non-Python builds, which at least needs to be
>> documented. There may be other aspects that are worth discussing.
>>
>> If this is accepted, it will need user-level documentation.
>>
>> I cannot say I like the name "grep". Users will associate that name
>> with the Unix command that searches through files, which is radically
>> different from what your command does. How about "lookup-fields"
>> instead?
>
> There was a discussion a few months ago about "Implementation of pipe
> to pass GDB's command output to the shell" [1] which would allow to
> use the 'real' grep to do a similar job, but I'm not sure about the
> status of this patch, it seems not to be in the trunk yet, according
> to the ChangeLog.
Hi all,
Sorry, I'm still struggling with copyright assignment. I almost got
approval from my organization but waiting for the disclaimer to be in
hand. I will send a final patch for review once this assignment is
done.
Thanks,
Abhijit Halder
>
> I didn't really look in depth at the sources, but based on you email
> description, I wonder how it differs from a generic code like that
> (not tested):
>
>> (gdb) grep int ss
>> ss.int_val = (int) 10
>
> #assume set print pretty on
>
> command = "print %s" % ss
> to_grep = "int"
>
> out = gdb.execute (command, to_string=True)
> for line in out.split("\n")
> if to_grep in line:
> print line
>
>
> good idea anyway,
> thanks,
>
> Kevin
>
> [1]: http://sourceware.org/ml/gdb-patches/2011-08/msg00483.html
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [RFC] A new command 'grep'
2012-01-02 9:28 ` Kevin Pouget
2012-01-02 9:35 ` Abhijit Halder
@ 2012-01-02 10:17 ` Siva Chandra
2012-01-02 17:44 ` Doug Evans
2 siblings, 0 replies; 7+ messages in thread
From: Siva Chandra @ 2012-01-02 10:17 UTC (permalink / raw)
To: gdb-patches; +Cc: Eli Zaretskii, Kevin Pouget
Hello,
Thanks for taking a look. My comments inline.
Eli > I think this is the first time we receive a proposal for a command
Eli > implemented in Python. Perhaps there's a place to discuss whether
Eli > some policy is in order in this regard. E.g., the command will be
Eli > unavailable in non-Python builds, which at least needs to be
Eli > documented. There may be other aspects that are worth discussing.
This is not the first, I submitted RFC another command called
'explore' few weeks back implemented in Python :-)
Kevin > I'm also curious about that, and maybe first of all, is there a Python
Kevin > specific coding convention likely to be enforced in GNU projects
Kevin > and/or GDB?
I couldn't locate any GNU coding conventions for Python. Hence, I
tried to follow the convention I could reverse engineer from the other
Python files in python/lib/gdb/command directory.
Kevin > There was a discussion a few months ago about "Implementation of pipe
Kevin > to pass GDB's command output to the shell" [1] which would allow to
Kevin > use the 'real' grep to do a similar job, but I'm not sure about the
Kevin > status of this patch, it seems not to be in the trunk yet, according
Kevin > to the ChangeLog.
I agree that if we can pass GDB output to shell, a lot of
functionality in this command is redundant. I was unaware of this
work. However, I have a part of this command extensible. When
'grepping' through unions, the user can define a field selector for
the union and the command will select only that field to grep through.
I have found this very useful in understanding GCC data structures.
Another point is that if we rely the shell grep and the GDB print
command, it cannot grep through pointer values.
Kevin > I didn't really look in depth at the sources, but based on you email
Kevin > description, I wonder how it differs from a generic code like that
Kevin > (not tested)
Kevin >
Kevin > (gdb) grep int ss
Kevin > ss.int_val = (int) 10
Kevin >
Kevin > #assume set print pretty on
Kevin >
Kevin > command = "print %s" % ss
Kevin > to_grep = "int"
Kevin >
Kevin > out = gdb.execute (command, to_string=True)
Kevin > for line in out.split("\n")
Kevin > if to_grep in line:
Kevin > print line
This does most of the job again but for the two points I mentioned
above. And again, I didn't think of this approach before. It seems to
me that we can either have this command I submitted in Python, or
extend the existing commands to support user defined plugins. I am a
newcomer to GDB code and its development: I am probably not thinking
very correctly.
About the name of the command itself, I am OK with 'lookup' instead of
'grep'. I favor 'grep' over 'lookup' because 'lookup' kind of implies
(probably just in my mind) to return a boolean value.
Thanks,
Siva Chandra
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [RFC] A new command 'grep'
2012-01-02 9:28 ` Kevin Pouget
2012-01-02 9:35 ` Abhijit Halder
2012-01-02 10:17 ` Siva Chandra
@ 2012-01-02 17:44 ` Doug Evans
2012-01-03 6:02 ` Siva Chandra
2 siblings, 1 reply; 7+ messages in thread
From: Doug Evans @ 2012-01-02 17:44 UTC (permalink / raw)
To: Kevin Pouget; +Cc: Eli Zaretskii, Siva Chandra, gdb-patches
On Mon, Jan 2, 2012 at 1:28 AM, Kevin Pouget <kevin.pouget@gmail.com> wrote:
> On Mon, Jan 2, 2012 at 9:54 AM, Eli Zaretskii <eliz@gnu.org> wrote:
>>
>> I think this is the first time we receive a proposal for a command
>> implemented in Python. Perhaps there's a place to discuss whether
>> some policy is in order in this regard. E.g., the command will be
>> unavailable in non-Python builds, which at least needs to be
>> documented. There may be other aspects that are worth discussing.
>
> I'm also curious about that, and maybe first of all, is there a Python
> specific coding convention likely to be enforced in GNU projects
> and/or GDB?
Sorry for the repeat.
[I wasn't aware the mail program I was using would sent it as rich html, sigh.]
For reference sake,
there are already some gdb commands in python,
see python/lib/gdb/command.
The pretty printer support there doesn't need to worry about
non-python builds of course.
As for coding convention, we follow pep008 with a few additions.
ref: http://sourceware.org/gdb/current/onlinedocs/gdbint/Coding-Standards.html#Coding-Standards
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC] A new command 'grep'
2012-01-02 17:44 ` Doug Evans
@ 2012-01-03 6:02 ` Siva Chandra
0 siblings, 0 replies; 7+ messages in thread
From: Siva Chandra @ 2012-01-03 6:02 UTC (permalink / raw)
To: gdb-patches; +Cc: Kevin Pouget, Eli Zaretskii, Doug Evans
On Mon, Jan 2, 2012 at 11:14 PM, Doug Evans <dje@google.com> wrote:
> On Mon, Jan 2, 2012 at 1:28 AM, Kevin Pouget <kevin.pouget@gmail.com> wrote:
>> On Mon, Jan 2, 2012 at 9:54 AM, Eli Zaretskii <eliz@gnu.org> wrote:
>>>
>>> I think this is the first time we receive a proposal for a command
>>> implemented in Python. Perhaps there's a place to discuss whether
>>> some policy is in order in this regard. E.g., the command will be
>>> unavailable in non-Python builds, which at least needs to be
>>> documented. There may be other aspects that are worth discussing.
>>
>> I'm also curious about that, and maybe first of all, is there a Python
>> specific coding convention likely to be enforced in GNU projects
>> and/or GDB?
>
> Sorry for the repeat.
> [I wasn't aware the mail program I was using would sent it as rich html, sigh.]
>
> For reference sake,
> there are already some gdb commands in python,
> see python/lib/gdb/command.
> The pretty printer support there doesn't need to worry about
> non-python builds of course.
>
> As for coding convention, we follow pep008 with a few additions.
> ref: http://sourceware.org/gdb/current/onlinedocs/gdbint/Coding-Standards.html#Coding-Standards
1. OK. I have verified that my code sticks to PEP008 but for the order
of imports. I will fix that.
2. Eli's query on the policy on general purpose commands implemented
in Python is very relevant. But before that, is this new command I
propose worth having?
3. If yes, then is it a good idea to have general purpose commands
implemented in Python? If not, I will implement this, and the earlier
'explore' command I proposed in C.
Thanks,
Siva Chandra
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-01-03 6:02 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-02 5:01 [RFC] A new command 'grep' Siva Chandra
2012-01-02 8:54 ` Eli Zaretskii
2012-01-02 9:28 ` Kevin Pouget
2012-01-02 9:35 ` Abhijit Halder
2012-01-02 10:17 ` Siva Chandra
2012-01-02 17:44 ` Doug Evans
2012-01-03 6:02 ` Siva Chandra
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox