Pretty prining c++ object from c frame fails with python exception. The bug filed in gdb bugzilla shows very simple example.
- https://sourceware.org/bugzilla/show_bug.cgi?id=27021 main.cc: #include <stdlib.h> #include <map> std::map<int, int> foo_map; int main() { foo_map[1] = 10; foo_map[2] = 20; abort(); } repros: > g++ -g main.cc > gdb a.out (gdb) run (gdb) print foo_map !! Python Exception <class 'AttributeError'> 'NoneType' object has no attribute 'pointer': $4 = std::map with 2 elements (gdb) frame 2 (gdb) print foo_map $5 = std::map with 2 elements = {[1] = 10, [2] = 20} When str(gdb.Type) is called(implicitly or explicitly) gdb returns type name differently depending on currently selected frame's language. In c++ frame, it will return just type name. But in c frame, the type name will be prepended with "class ", "union ", "enum ", and etc. e.g) # c frame (gdb) frame 0 (gdb) python print(gdb.lookup_symbol('foo_map')[0].value().type) class std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > > ^ # c++ frame (gdb) frame 2 (gdb) python print(gdb.lookup_symbol('foo_map')[0].value().type) std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > > ^ The prepended "class " is the root causes problem. But this can be easily mitigated by getting the type name explicitly by using gdb.Type.name or gdb.Type.tag. I think gdb.Type.tag is prefered because according to gdb documentation: "...The tag name is the name after struct, union, or enum in C and C++..." e.g.) # c frame (gdb) frame 0 (gdb) python print(gdb.lookup_symbol('foo_map')[0].value().type.tag) std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > > ^ libstdc++-v3/ChangeLog: 2020-12-22 Rae Kim <rae....@gmail.com> * python/libstdcxx/v6/printers.py (find_type): Use Type.tag. (lookup_templ_spec): likewise. --- libstdc++-v3/python/libstdcxx/v6/printers.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index 9c6393712a0..9f7a16174a8 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -86,7 +86,7 @@ def find_type(orig, name): typ = orig.strip_typedefs() while True: # Strip cv-qualifiers. PR 67440. - search = '%s::%s' % (typ.unqualified(), name) + search = '%s::%s' % (typ.unqualified().tag, name) try: return gdb.lookup_type(search) except RuntimeError: @@ -106,7 +106,14 @@ def lookup_templ_spec(templ, *args): """ Lookup template specialization templ<args...> """ - t = '{}<{}>'.format(templ, ', '.join([str(a) for a in args])) + args_str = [] + for a in args: + if isinstance(a, gdb.Type): + args_str.append(a.tag) + else: + args_str.append(str(a)) + + t = '{}<{}>'.format(templ, ', '.join(args_str)) try: return gdb.lookup_type(t) except gdb.error as e: -- 2.29.2