This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix use of lazy strings outside of pretty-printers


Hi.

Python lazy string support is broken, outside of usage in pretty-printers.
The pretty-printer machinery knows how to read NUL-terminated lazy strings,
but there is no such support in py-lazy-string.c:stpy_convert_to_value.

Regression tested on amd64-linux.

2016-03-30  Doug Evans  <dje@google.com>

	* python/py-lazy-string.c (lazy_string_object): Add comment.
	(stpy_convert_to_value): Handle NUL-terminated strings.
	* python/py-value.c (valpy_lazy_string): Handle TYPE_CODE_ARRAY like
	TYPE_CODE_PTR.

	testsuite/
	* gdb.python/py-lazy-string.c (name): New global.
	* gdb.python/py-lazy-string.exp: Add tests for extracting lazy string
	values.

diff --git a/gdb/python/py-lazy-string.c b/gdb/python/py-lazy-string.c
index d4b40df..8688bd9 100644
--- a/gdb/python/py-lazy-string.c
+++ b/gdb/python/py-lazy-string.c
@@ -41,7 +41,8 @@ typedef struct {
   long length;

   /*  This attribute holds the type that is represented by the lazy
-      string's type.  */
+      string's type.  IOW, this is the type of the character in the string.
+      For a C string, this is "char", not "char *".  */
   struct type *type;
 } lazy_string_object;

@@ -106,7 +107,25 @@ stpy_convert_to_value  (PyObject *self, PyObject *args)

   TRY
     {
-      val = value_at_lazy (self_string->type, self_string->address);
+      struct type *elm_type = self_string->type;
+      long length = self_string->length;
+      struct type *index_type, *range_type, *array_type;
+
+      if (TYPE_OBJFILE_OWNED (elm_type))
+	index_type
+	  = objfile_type (TYPE_OWNER (elm_type).objfile)->builtin_long;
+      else
+	index_type
+	  = builtin_type (TYPE_OWNER (elm_type).gdbarch)->builtin_long;
+
+      if (self_string->length == -1)
+	range_type = create_static_range_type (NULL, index_type, 0, -1);
+      else
+	range_type
+	  = create_static_range_type (NULL, index_type, 0, length - 1);
+
+      array_type = create_array_type (NULL, elm_type, range_type);
+      val = value_at_lazy (array_type, self_string->address);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 7dba0ad..88301e2 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -429,7 +429,8 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
     {
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());

-      if (TYPE_CODE (value_type (value)) == TYPE_CODE_PTR)
+      if (TYPE_CODE (value_type (value)) == TYPE_CODE_PTR
+	  || TYPE_CODE (value_type (value)) == TYPE_CODE_ARRAY)
 	value = value_ind (value);

str_obj = gdbpy_create_lazy_string_object (value_address (value), length, diff --git a/gdb/testsuite/gdb.python/py-lazy-string.c b/gdb/testsuite/gdb.python/py-lazy-string.c
index a6e1ee8..8bef66f 100644
--- a/gdb/testsuite/gdb.python/py-lazy-string.c
+++ b/gdb/testsuite/gdb.python/py-lazy-string.c
@@ -15,6 +15,8 @@
    You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */

+const char name[32] = "Dave";
+
 int
 main ()
 {
diff --git a/gdb/testsuite/gdb.python/py-lazy-string.exp b/gdb/testsuite/gdb.python/py-lazy-string.exp
index f57a482..5d0557f 100644
--- a/gdb/testsuite/gdb.python/py-lazy-string.exp
+++ b/gdb/testsuite/gdb.python/py-lazy-string.exp
@@ -40,3 +40,14 @@ gdb_test "python print(null.lazy_string(length=0).value())" \ "gdb.MemoryError: Cannot create a value from NULL.*Error while executing Python code."
 gdb_test "python print(null.lazy_string(length=3).value())" \
"gdb.MemoryError: Cannot create a lazy string with address 0x0, and a non-zero length.*Error while executing Python code."
+
+gdb_test_no_output "python name = gdb.parse_and_eval(\"name\")"
+gdb_test_no_output "python char_ptr = gdb.lookup_type(\"char\").pointer()"
+gdb_test "python print name.lazy_string().value()" \
+    "\"Dave\""
+gdb_test "python print name.lazy_string(length=2).value()" \
+    "\"Da\""
+gdb_test "python print name.cast(char_ptr).lazy_string().value()" \
+    "\"Dave\""
+gdb_test "python print name.cast(char_ptr).lazy_string(length=2).value()" \
+    "\"Da\""


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]