[PR,18438] PyExc_MemoryError != gdbpy_gdb_memory_error

Message ID e89a8ffbacdfb7112205169d623e@google.com
State New, archived
Headers

Commit Message

Doug Evans May 21, 2015, 8:28 p.m. UTC
  Hi.

This patch fixes pr 18438.
The problem here is that the wrong exception is being thrown
causing python backtraces to be printed when they shouldn't be.

There's still an issue of whether the error text should change.
The user may not know what a lazy string is (and shouldn't have to,
s/he may be using some random pretty-printer).
Left for a separate patch, pr 18445.

Regression tested on amd64-linux.

2015-05-21  Doug Evans  <dje@google.com>

	PR python/18438
	* python/py-lazy-string.c (stpy_convert_to_value): Use
	gdbpy_gdb_memory_error not PyExc_MemoryError.
	(gdbpy_create_lazy_string_object): Ditto.

	testsuite/
	* gdb.python/py-lazy-string.c: New file.
	* gdb.python/py-lazy-string.exp: New file.
	* gdb.python/py-prettyprint.c (lazystring) <len>: New member.
	(main): Update.  Add estring3, estring4.
	* gdb.python/py-prettyprint.exp: Add tests for strings at address 0.
	* gdb.python/py-prettyprint.py (pp_ls): Handle length.

          return 'string'
  

Comments

Doug Evans May 26, 2015, 11:16 p.m. UTC | #1
On Thu, May 21, 2015 at 1:28 PM, Doug Evans <dje@google.com> wrote:
> Hi.
>
> This patch fixes pr 18438.
> The problem here is that the wrong exception is being thrown
> causing python backtraces to be printed when they shouldn't be.
>
> There's still an issue of whether the error text should change.
> The user may not know what a lazy string is (and shouldn't have to,
> s/he may be using some random pretty-printer).
> Left for a separate patch, pr 18445.
>
> Regression tested on amd64-linux.
>
> 2015-05-21  Doug Evans  <dje@google.com>
>
>         PR python/18438
>         * python/py-lazy-string.c (stpy_convert_to_value): Use
>         gdbpy_gdb_memory_error not PyExc_MemoryError.
>         (gdbpy_create_lazy_string_object): Ditto.
>
>         testsuite/
>         * gdb.python/py-lazy-string.c: New file.
>         * gdb.python/py-lazy-string.exp: New file.
>         * gdb.python/py-prettyprint.c (lazystring) <len>: New member.
>         (main): Update.  Add estring3, estring4.
>         * gdb.python/py-prettyprint.exp: Add tests for strings at address 0.
>         * gdb.python/py-prettyprint.py (pp_ls): Handle length.

Committed.
  

Patch

diff --git a/gdb/python/py-lazy-string.c b/gdb/python/py-lazy-string.c
index c9774ab..97bc9cb 100644
--- a/gdb/python/py-lazy-string.c
+++ b/gdb/python/py-lazy-string.c
@@ -99,7 +99,7 @@  stpy_convert_to_value  (PyObject *self, PyObject *args)

    if (self_string->address == 0)
      {
-      PyErr_SetString (PyExc_MemoryError,
+      PyErr_SetString (gdbpy_gdb_memory_error,
  		       _("Cannot create a value from NULL."));
        return NULL;
      }
@@ -133,7 +133,7 @@  gdbpy_create_lazy_string_object (CORE_ADDR address,  
long length,

    if (address == 0 && length != 0)
      {
-      PyErr_SetString (PyExc_MemoryError,
+      PyErr_SetString (gdbpy_gdb_memory_error,
  		       _("Cannot create a lazy string with address 0x0, " \
  			 "and a non-zero length."));
        return NULL;
diff --git a/gdb/testsuite/gdb.python/py-lazy-string.c  
b/gdb/testsuite/gdb.python/py-lazy-string.c
new file mode 100644
index 0000000..c72e1fa
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-lazy-string.c
@@ -0,0 +1,24 @@ 
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2015 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/>.   
*/
+
+int
+main ()
+{
+  const char *null = 0;
+
+  return 0; /* break here */
+}
diff --git a/gdb/testsuite/gdb.python/py-lazy-string.exp  
b/gdb/testsuite/gdb.python/py-lazy-string.exp
new file mode 100644
index 0000000..55e903e
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-lazy-string.exp
@@ -0,0 +1,42 @@ 
+# Copyright (C) 2015 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 lazy string support
+# not tested by py-prettyprinter.exp.
+
+load_lib gdb-python.exp
+
+standard_testfile
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+    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"
+
+gdb_test_no_output "python null = gdb.parse_and_eval(\"null\")"
+
+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."
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.c  
b/gdb/testsuite/gdb.python/py-prettyprint.c
index 60163d6..b6e111d 100644
--- a/gdb/testsuite/gdb.python/py-prettyprint.c
+++ b/gdb/testsuite/gdb.python/py-prettyprint.c
@@ -42,6 +42,8 @@  struct ns {

  struct lazystring {
    const char *lazy_str;
+  /* If -1, don't pass length to gdb.lazy_string().  */
+  int len;
  };

  struct hint_error {
@@ -270,7 +272,7 @@  main ()
    nostring_type nstype, nstype2;
    struct memory_error me;
    struct ns ns, ns2;
-  struct lazystring estring, estring2;
+  struct lazystring estring, estring2, estring3;
    struct hint_error hint_error;
    struct children_as_list children_as_list;

@@ -295,10 +297,15 @@  main ()
    ns2.null_str = NULL;
    ns2.length = 20;

-  estring.lazy_str = "embedded x\201\202\203\204" ;
+  estring.lazy_str = "embedded x\201\202\203\204";
+  estring.len = -1;

    /* Incomplete UTF-8, but ok Latin-1.  */
    estring2.lazy_str = "embedded x\302";
+  estring2.len = -1;
+
+  estring3.lazy_str = NULL;
+  estring3.len = 42;

  #ifdef __cplusplus
    S cps;
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.exp  
b/gdb/testsuite/gdb.python/py-prettyprint.exp
index 094f956..399f041 100644
--- a/gdb/testsuite/gdb.python/py-prettyprint.exp
+++ b/gdb/testsuite/gdb.python/py-prettyprint.exp
@@ -92,6 +92,8 @@  proc run_lang_tests {exefile lang} {
      gdb_test "print cstring" " = \"const string\""

      gdb_test "print estring" " = \"embedded  
x\\\\201\\\\202\\\\203\\\\204\""
+    gdb_test "print estring3" \
+	" = <error reading variable: Cannot create a lazy string with address  
0x0, and a non-zero length.>"

      gdb_test_no_output "python pp_ls_encoding = 'UTF-8'"
      gdb_test "print estring2" "\"embedded \", <incomplete sequence  
\\\\302>"
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.py  
b/gdb/testsuite/gdb.python/py-prettyprint.py
index c350bfe..442813b 100644
--- a/gdb/testsuite/gdb.python/py-prettyprint.py
+++ b/gdb/testsuite/gdb.python/py-prettyprint.py
@@ -152,10 +152,20 @@  class pp_ls (object):
          self.val = val

      def to_string(self):
+        length = self.val['len']
          if pp_ls_encoding is not None:
-            return self.val['lazy_str'].lazy_string(encoding =  
pp_ls_encoding)
+            if length >= 0:
+                return self.val['lazy_str'].lazy_string(
+                        encoding = pp_ls_encoding,
+                        length = length)
+            else:
+                return self.val['lazy_str'].lazy_string(
+                        encoding = pp_ls_encoding)
          else:
-            return self.val['lazy_str'].lazy_string()
+            if length >= 0:
+                return self.val['lazy_str'].lazy_string(length = length)
+            else:
+                return self.val['lazy_str'].lazy_string()

      def display_hint (self):