gdb/testsuite: more testing of pretty printer 'array' display_hint

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'.
This commit is contained in:
Andrew Burgess
2021-03-02 14:19:56 +00:00
parent b4b1a226df
commit b1f3973b9c
4 changed files with 45 additions and 0 deletions

View 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;
}

View 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"

View 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