gdb/testsuite: more testing of pretty printer 'array' display_hint
authorAndrew Burgess <andrew.burgess@embecosm.com>
Tue, 2 Mar 2021 14:19:56 +0000 (14:19 +0000)
committerAndrew Burgess <andrew.burgess@embecosm.com>
Fri, 26 Mar 2021 17:43:14 +0000 (17:43 +0000)
This commit adds a couple of tests to the python pretty printer
testing.

I've added a test for the 'array' display hint.  This display hint is
tested by gdb.python/py-mi.exp, however, the MI testing is done via
the varobj interface, and this code makes its own direct calls to the
Python pretty printers from gdb/varobj.c.  What this means is that the
interface to the pretty printers in gdb/python/py-prettyprint.c is not
tested for the 'array' display hint path.

I also added a test for what happens when the display_hint method
raises an exception.  There wasn't a bug that inspired this test, just
while adding the previous test I thought, I wonder what happens if...

The current behaviour of GDB seems reasonable, GDB displays the Python
exception, and then continues printing the value as if display_hint
had returned None.  I added a test to lock in this behaviour.

gdb/testsuite/ChangeLog:

* gdb.python/py-prettyprint.c (struct container): Add 'is_array_p'
member.
(make_container): Initialise is_array_p.
* gdb.python/py-prettyprint.exp: Add new tests.
* gdb.python/py-prettyprint.py (ContainerPrinter.display_hint):
Check is_array_p and possibly return 'array'.

gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/py-prettyprint.c
gdb/testsuite/gdb.python/py-prettyprint.exp
gdb/testsuite/gdb.python/py-prettyprint.py

index d0fce5902d668725af59c287e72b027c4d5a2b88..3484004c129b0b9b747dc65ec8f658c20e8b3e23 100644 (file)
@@ -1,3 +1,12 @@
+2021-03-26  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * gdb.python/py-prettyprint.c (struct container): Add 'is_array_p'
+       member.
+       (make_container): Initialise is_array_p.
+       * gdb.python/py-prettyprint.exp: Add new tests.
+       * gdb.python/py-prettyprint.py (ContainerPrinter.display_hint):
+       Check is_array_p and possibly return 'array'.
+
 2021-03-26  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * gdb.cp/breakpoint.exp: Extend test names to make them unique.
index 2558e98f5c0725da2b09312725e7f4e6d251c920..126537ff529eff7d802e9825d428a56c41c2b283 100644 (file)
@@ -176,6 +176,7 @@ struct container
   int len;
   int *elements;
   int is_map_p;
+  int is_array_p;
 };
 
 typedef struct container zzz_type;
@@ -197,6 +198,7 @@ make_container (const char *s)
   result.len = 0;
   result.elements = 0;
   result.is_map_p = 0;
+  result.is_array_p = 0;
 
   return result;
 }
index 9f0b36a333c27d73f2e04ee261ea4d12c5a4eb57..6a3968fe0547d25c9671e5da6ce580a2e25af915 100644 (file)
@@ -112,7 +112,36 @@ proc run_lang_tests {exefile lang} {
     gdb_test "print c" " = container \"container\" with 2 elements = {$nl *.0. = 23,$nl *.1. = 72$nl}" \
        "print c, pretty printing on, default display hint"
 
+    gdb_test_no_output "set variable c.is_array_p=1"
+    gdb_test "print c" " = container \"container\" with 2 elements = \\{23, 72\\}" \
+       "print c, pretty printing on, display hint is now array"
+
+    # Setting is_map_p while _is_array_p is also set will cause the
+    # display_hint method to raise an exception (see py-prettyprint.py).
     gdb_test_no_output "set variable c.is_map_p=1"
+
+    # This test checks what happens when the display hint throws an
+    # error.  GDB just treats this as though the display hint was
+    # None.
+    set py_exception \
+       [multi_line \
+            "Traceback\[^\r\n\]+" \
+            "\\s+File \"\[^\r\n\]+/py-prettyprint.py\", line \[0-9\]+, in display_hint" \
+            "\\s+raise Exception \[^\r\n\]+" \
+            "Exception: invalid object state found in display_hint"]
+    gdb_test "print c" \
+       [multi_line \
+            " = ${py_exception}" \
+            "container \"container\" with 2 elements = {" \
+            "\\s+\\\[0\\\] = 23," \
+            "\\s+\\\[1\\\] = 72" \
+            "}"] \
+       "print c, pretty printing on, exception raised from display_hint"
+
+    # Unset is_array_p so that display_hint no longer raises an
+    # exception.
+    gdb_test_no_output "set variable c.is_array_p=0"
+
     gdb_test "print c" " = container \"container\" with 2 elements = \{$nl  \\\[23\\\] = 72$nl\}" \
        "print c, pretty printing on, display hint is now map"
 
index 5f09ea8944bd3b5c0ca22ab86b65de9ed95b942e..fab03a653b7a3fe0a37e26a18657041e3473e2de 100644 (file)
@@ -57,8 +57,13 @@ class ContainerPrinter (object):
         return _iterator(self.val['elements'], self.val['len'])
 
     def display_hint (self):
+        if (self.val['is_map_p'] and self.val['is_array_p']):
+            raise Exception ("invalid object state found in display_hint")
+
         if (self.val['is_map_p']):
             return 'map'
+        elif (self.val['is_array_p']):
+            return 'array'
         else:
             return None