The gdb/mi command "-var-update" may return an incorrect value for "type_changed" when pretty-printers are used. Consider the following example. The struct "printMePretty" should be pretty-printed by using the Python TestPrinter class from below. It should be printed as an integer "array" (it doesn't actually makes sense here, it's just for testing) if the structure's "printAsInt" member is true, and as a floating point "array" otherwise. ****************** File: main.cpp ***************** struct printMePretty { bool printAsInt; int intMember; float floatMember; printMePretty() : printAsInt(true), intMember(0xFF), floatMember(3.1415) { } }; void main() { printMePretty pretty; pretty.printAsInt = false; } ****************** File: printer.py ***************** [...] class TestPrinter: class _iterator: def __init__(self, val): self.val = val self.index = 0 def __iter__(self): return self def next(self): if self.index == 1: raise StopIteration if self.val['printAsInt']: childValue = self.val['intMember'] else: childValue = self.val['floatMember'] self.index += 1 return ('Value', childValue) def __init__(self, val): self.val = val def children(self): return self._iterator(self.val) def display_hint(self): return 'array' ****************** End of file ***************** Using Eclipse CDT to trace gdb/mi commands, one encounters the following until the line "pretty.printAsInt = false;": -var-create --thread 1 --frame 0 - * pretty ^done,name="var1",numchild="0",value="{...}",type="printMePretty",thread-id="1",displayhint="array",dynamic="1",has_more="1" -var-list-children var1 0 1 ^done,numchild="1",displayhint="array",children=[child={name="var1.Value",exp="Value",numchild="0",type="int",thread-id="1"}],has_more="0" OK, so "var1.Value" has type "int". Now, stepping over the line "pretty.printAsInt = false;" results in: -var-update 1 var1 ^done,changelist=[{name="var1.Value",value="3.1415",in_scope="true",type_changed="false",displayhint="array",dynamic="1",has_more="0"}] It now says that "var1.Value" would have a "value" of "3.1415" - that's obviously a strange value for an "int" (since "type_changed" reports "false" - I suppose it should actually report that the type has changed to "float"). This seems like a bug within gdb to me. The same problem may also apply if a pretty-printer's toString() method returns gdb.Values which have different gdb.Types, depending on the data members of the structure which should be pretty-printed.
-var-update was created to keep track of standard situations, like watching data members of C style structures. They can conceptually not work for "complex" pretty-printing in the presence of arbitrary changes to the environment like the value of global variables or the return value of function calls. The only safe approach for a gdb frontend is to not rely on -var-update (or varobj at all for that matter) and re-run all pretty printers everytime something could have changed.
Well, the -var-update command apparently successfully recognizes the updated pretty printer expression, since we can see the updated value "3.1415". If -var-update can recognize the updated value of the gdb.Value returned from the pretty printer, then it must also be able to recognize a type change of that gdb.Value, correct?
Your particular problem might be indeed fixable, as all "state" is locally available. However, this does not solve the general problem, see http://sourceware.org/bugzilla/show_bug.cgi?id=14854
I understand that -var-update can't work if the pretty printer depends on non-local data, as described in bug 14854. However, I don't think this bug is related to that problem. The problem here is that -var-update apparently doesn't handle type changes of childs of array-printed types, but only value changes. Note that this doesn't apply to string types, as they can't change their types when pretty-printed. As an example, printing the above "printMePretty" structure as string type results in: If printAsInt is true: Type is "printMePretty", value is "255" If printAsInt is false: Type is "printMePretty", value is "3.1415" Everything OK here, the type will always just be "printMePretty" and won't change. However, printing the same structure in array form results in: If printAsInt is true: Parent type is "printMePretty", child type is "int", child value is "255" If printAsInt is false: Parent type is "printMePretty", child type is "float", child value is "3.1415" -var-update recognizes a value change of the child, but fails to recognize the type change.
I've changed the bug title in order to improve the description of the problem.