gdb pretty printer to_string/children interference in CLion

Answered

I have a rather complex data structure in my application, but the idea is quite simple - it must represent a *.json configuration file. Each node has, besides of anything else, 'key' and 'value' fields and a vector of 'children'.

To ease debugging I decided to implement gdb pretty printer for my structure. The 'to_stirng' method of pretty printer was expected to print pair of 'key', 'value' in line with the variable name, and 'children'  method - the content of 'children' vector beneath.

When I implemented just a 'to_stirng' method, the result was as expected - 'key' and 'value' values were printed, but information from 'children' vector was not. But when I implemented 'children' method, I got children list beneath my variable, but the result of 'to_string' method disappeared.

I wrote a very short program to model this behaviour - files main.cpp and node_printer.py attached. The effect is the same - when method 'children' is not implemented in node_printer.py I can see 'key' and 'value':

but when it is implemented - can not:

When I try to print a variable from gdb console I got all information:

(gdb) print root
$1 = {key = "root_key", value = "root_value"} = {[0] = {key = "leaf_key", value = "leaf_value"}}

So this is a CLion problem.

Any ideas, how to overcome?

main.cpp:

#include <iostream>
#include <vector>


struct Node {
std::string key;
std::string value;
std::vector<Node> children;
};


int main() {
Node root;
root.key = "root_key";
root.value = "root_value";
Node leaf;
leaf.key = "leaf_key";
leaf.value = "leaf_value";
root.children.push_back(leaf);
return 0;
}

node_printer.py

import re
import gdb

class NodePrinter(object):
"Print a struct Node"

def __init__(self, val):
self.val = val

def to_string(self):
return "{key = %s, value = %s}" \
% (self.val['key'], self.val['value'])

def children(self):
c = []
o = self.val['children']
for i in range(0, o['_M_impl']['_M_finish'] - o['_M_impl']['_M_start']):
c.append(('[%d]' % i, ((o['_M_impl']['_M_start']+i).dereference())))
return c

def display_hint(self):
return 'Node'

def node_lookup_function(val):
"Look-up and return a pretty-printer that can print val."

type = val.type

if type.code == gdb.TYPE_CODE_REF:
type = type.target()

type = type.unqualified().strip_typedefs()
typename = type.tag
if typename == None:
return None
regex = re.compile("^Node$")
if(regex.match(typename)):
return NodePrinter(val)
return None


gdb.pretty_printers.append(node_lookup_function)

 

0
1 comment

Please sign in to leave a comment.