[patch] Use the string returned by pretty printer for MI varobjs instead of "{...}"

xgsa
2012-04-22T20:10:19Z

[-- Attachment #1: Type: text/plain, Size: 728 bytes --]

Hi,

The documentation for -var-create says that "for a varobj whose type is some sort of aggregate (e.g., a struct), or for a dynamic varobj, the 'value' attribute will not be interesting". That's not true, as dynamic varobj could also have no children (so its value will be not "{...}" and will be interesting). However I think the string value of varobj that has pretty printer installed should always be returned via MI. It could contain such a useful information as container length or reference count for smart pointers. Moreover, it seems that this information cannot be accessed via MI in another way. This patch contains the proposed fix, documentation and test suite update.

No regressions on linux32.

Thanks,
Anton

[-- Attachment #2: dynamic_show_str3.ChangeLog --]
[-- Type: text/plain, Size: 785 bytes --]

gdb/doc/ChangeLog:

2012-04-22 Anton Gorenkov <xgsa@yandex.ru>

(GDB/MI Variable Objects): Fix the description for the "value"
attribute of -var-create MI command.

gdb/testsuite/ChangeLog:

2012-04-22 Anton Gorenkov <xgsa@yandex.ru>

* gdb.python/py-mi.exp: Use mi_create_floating_varobj_with_value
instead of mi_create_dynamic_varobj and provide the varobj value.
* lib/mi-support.exp (mi_create_floating_varobj_with_value): New function.
(mi_create_floating_varobj): updated to avoid code duplication.
(mi_create_dynamic_varobj): Remove.

gdb/ChangeLog:

2012-04-22 Anton Gorenkov <xgsa@yandex.ru>

* varobj.c (dynamic_varobj_has_child_method): Remove function.
(value_get_print_value): Remove check for dynamic varobj children
and add None return value handling.

[-- Attachment #3: dynamic_show_str3.diff --]
[-- Type: text/plain, Size: 6238 bytes --]

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 574809d..de50cca 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -29482,8 +29482,7 @@ reliable for a dynamic varobj. Instead, you must examine the

@item value
The varobj's scalar value. For a varobj whose type is some sort of
-aggregate (e.g., a @code{struct}), or for a dynamic varobj, this value
-will not be interesting.
+aggregate (e.g., a @code{struct}), this value will not be interesting.

@item type
The varobj's type. This is a string representation of the type, as
diff --git a/gdb/testsuite/gdb.python/py-mi.exp b/gdb/testsuite/gdb.python/py-mi.exp
index 8d54a8d..bf3ed72 100644
--- a/gdb/testsuite/gdb.python/py-mi.exp
+++ b/gdb/testsuite/gdb.python/py-mi.exp
@@ -51,7 +51,7 @@ mi_gdb_test "python execfile ('${remote_python_file}')" ""
mi_continue_to_line [gdb_get_line_number {MI breakpoint here} ${srcfile}] \
"step to breakpoint"

-mi_create_dynamic_varobj container c \
+mi_create_floating_varobj_with_value container c {{...}} \
"create container varobj, no pretty-printing"

mi_list_varobj_children container {
@@ -62,7 +62,7 @@ mi_list_varobj_children container {

mi_delete_varobj container "delete varobj"

-mi_create_dynamic_varobj nscont nstype \
+mi_create_floating_varobj_with_value nscont nstype {{...}} \
"create nscont varobj, no pretty-printing"

mi_list_varobj_children nscont {
@@ -89,7 +89,7 @@ mi_gdb_test "-var-update string" \
"\\^done,changelist=\\\[{name=\"string\",in_scope=\"true\",type_changed=\"false\",dynamic=\"1\",has_more=\"0\"}\\\]" \
"update string varobj after assignment"

-mi_create_dynamic_varobj container c \
+mi_create_floating_varobj_with_value container c {container \\"container\\" with 0 elements} \
"create container varobj"

mi_list_varobj_children container {
@@ -204,7 +204,7 @@ mi_next "next over update 5"

# Regression test: examine an object that has no children, then update
# it to ensure that we don't print the children.
-mi_create_dynamic_varobj container2 c2 \
+mi_create_floating_varobj_with_value container2 c2 {container \\"container2\\" with 0 elements} \
"create second container varobj"

mi_gdb_test "-var-update container2" \
@@ -225,7 +225,7 @@ mi_continue_to_line \
[gdb_get_line_number {MI outer breakpoint here} ${srcfile}] \
"step to outer breakpoint"

-mi_create_dynamic_varobj outer outer \
+mi_create_floating_varobj_with_value outer outer {x = 0} \
"create outer varobj"

mi_list_varobj_children outer {
@@ -255,7 +255,7 @@ mi_continue_to_line \
[gdb_get_line_number {break to inspect struct and union} ${srcfile}] \
"step to outer breakpoint"

-mi_create_dynamic_varobj nscont nstype \
+mi_create_floating_varobj_with_value nscont nstype {{...}} \
"create nstype varobj"

mi_list_varobj_children nscont {
@@ -277,7 +277,7 @@ mi_gdb_test "-var-set-visualizer nscont gdb.default_visualizer" \

mi_gdb_test "python exception_flag = True" ""

-mi_create_dynamic_varobj nstype2 nstype2 \
+mi_create_floating_varobj_with_value nstype2 nstype2 {{...}} \
"create nstype2 varobj"

mi_list_varobj_children nstype2 {
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
index 401565d..84ff83a 100644
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -1246,12 +1246,18 @@ proc mi_create_varobj { name expression testname } {
$testname
}

-proc mi_create_floating_varobj { name expression testname } {
+# Creates floating varobj named NAME for EXPRESSION and checks its VALUE.
+proc mi_create_floating_varobj_with_value {name expression value testname} {
mi_gdb_test "-var-create $name @ $expression" \
- "\\^done,name=\"$name\",numchild=\"\(-1\|\[0-9\]+\)\",value=\".*\",type=.*" \
+ "\\^done,name=\"$name\",numchild=\"\(-1\|\[0-9\]+\)\",value=\"$value\",type=.*" \
$testname
}

+# Same as mi_create_floating_varobj_with_value, but does not check the value.
+proc mi_create_floating_varobj { name expression testname } {
+ mi_create_floating_varobj_with_value $name $expression ".*" $testname
+}
+

# Same as mi_create_varobj, but also checks the reported type
# of the varobj.
@@ -1261,14 +1267,6 @@ proc mi_create_varobj_checked { name expression type testname } {
$testname
}

-# Same as mi_create_floating_varobj, but assumes the test is creating
-# a dynamic varobj that has children, so the value must be "{...}".
-proc mi_create_dynamic_varobj {name expression testname} {
- mi_gdb_test "-var-create $name @ $expression" \
- "\\^done,name=\"$name\",numchild=\"\(-1\|\[0-9\]+\)\",value=\"{\\.\\.\\.}\",type=.*" \
- $testname
-}
-
# Deletes the specified NAME.
proc mi_delete_varobj { name testname } {
mi_gdb_test "-var-delete $name" \
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 3086499..7bd24f5 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -1053,19 +1053,6 @@ install_dynamic_child (struct varobj *var,
}
}

-static int
-dynamic_varobj_has_child_method (struct varobj *var)
-{
- struct cleanup *back_to;
- PyObject *printer = var->pretty_printer;
- int result;
-
- back_to = varobj_ensure_python_env (var);
- result = PyObject_HasAttr (printer, gdbpy_children_cst);
- do_cleanups (back_to);
- return result;
-}
-
#endif

static int
@@ -2866,14 +2853,6 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,

if (value_formatter)
{
- /* First check to see if we have any children at all. If so,
- we simply return {...}. */
- if (dynamic_varobj_has_child_method (var))
- {
- do_cleanups (old_chain);
- return xstrdup ("{...}");
- }
-
if (PyObject_HasAttr (value_formatter, gdbpy_to_string_cst))
{
struct value *replacement;
@@ -2888,6 +2867,13 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
{
make_cleanup_py_decref (output);

+ /* Handle returned None properly. */
+ if (output == Py_None)
+ {
+ do_cleanups (old_chain);
+ return xstrdup ("{...}");
+ }
+
/* If this is a lazy string, extract it. For lazy
strings we always print as a string, so set
string_print. */