What is the expected result for an std::bitset using -enable-pretty-printing in gdb/mi. Following happens to me: (gdb) -var-create - * bits ^error,msg="Returned value is not iterable" (gdb) whatis bits &"whatis bits\n" ~"type = std::bitset<8ul>\n" Normal print or -data-evaluate-expression works as expected print bits &"print bits\n" ~"$2 = std::bitset = {[0] = 1" ~", [2] = 1" ~", [4] = 1" ~", [6] = 1" What I expected was a result like the print of a std::map with the given index to the bit that is set.
I can't reproduce this. I used this test program: #include <bitset> std::bitset<8> bits; int main() { bits[1] = 1; } I get: (gdb) -var-create - * bits ^done,name="var1",numchild="1",value="{...}",type="std::bitset<8ul>",has_more="0" What version of g++ are you using? The libstdc++ printers actually live there.
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2) 7.4-2012.04 STL Support Implementation -> http://sourceware.org/gdb/wiki/STLSupport -------------------------------------------------------------------------------- That should be your printer implementation -------------------------------------------------------------------------------- class StdBitsetPrinter: "Print a std::bitset" def __init__(self, typename, val): self.typename = typename self.val = val def to_string (self): # If template_argument handled values, we could print the # size. Or we could use a regexp on the type. return '%s' % (self.typename) def children (self): words = self.val['_M_w'] wtype = words.type # The _M_w member can be either an unsigned long, or an # array. This depends on the template specialization used. # If it is a single long, convert to a single element list. if wtype.code == gdb.TYPE_CODE_ARRAY: tsize = wtype.target ().sizeof else: words = [words] tsize = wtype.sizeof nwords = wtype.sizeof / tsize result = [] byte = 0 while byte < nwords: w = words[byte] bit = 0 while w != 0: if (w & 1) != 0: # Another spot where we could use 'set'? result.append(('[%d]' % (byte * tsize * 8 + bit), 1)) bit = bit + 1 w = w >> 1 byte = byte + 1 return result -------------------------------------------------------------------------------- That's my source file -------------------------------------------------------------------------------- #include <bitset> int main() { const int bitsetsize = 8; std::bitset<bitsetsize> bits; for(int i = 0; i < bitsetsize; i++) { if(i%2 == 0 || i == 0) {bits[i].flip(); } } return 0; } -------------------------------------------------------------------------------- My Debug Commands -------------------------------------------------------------------------------- -enable-pretty-printing -break-insert 10 -exec-run -var-create - * bits Thanks for your reply
(In reply to comment #2) > -enable-pretty-printing Oops, somehow I forgot this step. Thanks for the very clear directions. I can reproduce it now.
The bug is that varobj.c calls PyIter_Check. It should just try to get the iterator and possibly fail. Arguably this is a bug in Python, in that PyIter_Check returns 0 if its argument is a Python list.
Sorry, I'm missing the routine in coding C. Just learned many languages, but none of them perfect. There is still so much I have to learn. I tried to watch varobj.c and found your line for the PyIter Check, but couldn't find the impl of the error function, just think that i will cause an exception. The thing is, that the message for -var-list-children is correct, because the returned value is not iterable. As much as i know bitset doesn't have an iterator. The question that I have is more or less, why there is an implemented methode for children. I thought this methode should be used to resolve the output for -var-list-children and the to_string should resolve the object for the print and -data-evaluate-expression of gdb. But now I see that children is used to print the items, and appends them to the to _string methode. Is there a way to leave the output for the var-list-children methode as it was but using the new output for print and -data-eval... Would be nice to have some workaround, but bitset is not iterable is the worst output i can get, even the old is better. Really appreciate your work. Made debugging much easier.
(In reply to comment #5) > The thing is, that the message for -var-list-children is correct, because the > returned value is not iterable. As much as i know bitset doesn't have an > iterator. This message does not refer to the bitset in your program, but rather to a Python object created by the pretty-printer for the bitset. > The question that I have is more or less, why there is an implemented methode > for children. This approach lets MI clients decide how many children to show (consider, e.g., a vector of 1000 elements), and it lets the CLI apply various "set print" settings, like "set print elements", to pretty-printed values. > Is there a way to leave the output for the > var-list-children methode as it was but using the new output for print and > -data-eval... MI clients can disable pretty-printing per-varobj. See the manual for details. > Would be nice to have some workaround, but bitset is not iterable is the worst > output i can get, even the old is better. If you encounter a pretty-printer bug you can bypass the Python code with "print/r"
CVSROOT: /cvs/src Module name: src Changes by: tromey@sourceware.org 2012-08-06 18:44:45 Modified files: gdb : ChangeLog varobj.c gdb/testsuite : ChangeLog gdb/testsuite/gdb.python: py-mi.exp py-prettyprint.c py-prettyprint.py Log message: PR python/14386: * varobj.c (update_dynamic_varobj_children): Don't call PyIter_Check. gdb/testsuite * gdb.python/py-mi.exp: Add test for printer whose children are a list. * gdb.python/py-prettyprint.c (struct children_as_list): New. (main): New variable children_as_list. * gdb.python/py-prettyprint.py (class pp_children_as_list): New. (register_pretty_printers): Register new printer. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/ChangeLog.diff?cvsroot=src&r1=1.14561&r2=1.14562 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/varobj.c.diff?cvsroot=src&r1=1.199&r2=1.200 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/ChangeLog.diff?cvsroot=src&r1=1.3324&r2=1.3325 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.python/py-mi.exp.diff?cvsroot=src&r1=1.16&r2=1.17 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.python/py-prettyprint.c.diff?cvsroot=src&r1=1.15&r2=1.16 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.python/py-prettyprint.py.diff?cvsroot=src&r1=1.14&r2=1.15
Fixed.
CVSROOT: /cvs/src Module name: src Branch: gdb_7_5-branch Changes by: tromey@sourceware.org 2012-08-16 17:08:44 Modified files: gdb : ChangeLog varobj.c gdb/testsuite : ChangeLog gdb/testsuite/gdb.python: py-mi.exp py-prettyprint.c py-prettyprint.py Log message: PR python/14386: * varobj.c (update_dynamic_varobj_children): Don't call PyIter_Check. gdb/testsuite * gdb.python/py-mi.exp: Add test for printer whose children are a list. * gdb.python/py-prettyprint.c (struct children_as_list): New. (main): New variable children_as_list. * gdb.python/py-prettyprint.py (class pp_children_as_list): New. (register_pretty_printers): Register new printer. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/ChangeLog.diff?cvsroot=src&only_with_tag=gdb_7_5-branch&r1=1.14469.2.21&r2=1.14469.2.22 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/varobj.c.diff?cvsroot=src&only_with_tag=gdb_7_5-branch&r1=1.196&r2=1.196.2.1 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/ChangeLog.diff?cvsroot=src&only_with_tag=gdb_7_5-branch&r1=1.3295.2.19&r2=1.3295.2.20 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.python/py-mi.exp.diff?cvsroot=src&only_with_tag=gdb_7_5-branch&r1=1.16&r2=1.16.2.1 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.python/py-prettyprint.c.diff?cvsroot=src&only_with_tag=gdb_7_5-branch&r1=1.15&r2=1.15.2.1 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.python/py-prettyprint.py.diff?cvsroot=src&only_with_tag=gdb_7_5-branch&r1=1.14&r2=1.14.2.1