mgrname = m.group(1)
# FIXME need to expand 'std::string' so that gdb.lookup_type works
if 'std::string' in mgrname:
- mgrname = re.sub("std::string(?!\w)", str(gdb.lookup_type('std::string').strip_typedefs()), m.group(1))
-
- mgrtype = gdb.lookup_type(mgrname)
+ # This lookup for std::string might return the __cxx11 version,
+ # but that's not necessarily the one used by the std::any
+ # manager function we're trying to find.
+ strings = {str(gdb.lookup_type('std::string').strip_typedefs())}
+ # So also consider all the other possible std::string types!
+ s = 'basic_string<char, std::char_traits<char>, std::allocator<char> >'
+ quals = ['std::', 'std::__cxx11::', 'std::' + _versioned_namespace]
+ strings |= {q+s for q in quals} # set of unique strings
+ mgrtypes = []
+ for s in strings:
+ try:
+ x = re.sub("std::string(?!\w)", s, m.group(1))
+ # The following lookup might raise gdb.error if the
+ # manager function was never instantiated for 's' in the
+ # program, because there will be no such type.
+ mgrtypes.append(gdb.lookup_type(x))
+ except gdb.error:
+ pass
+ if len(mgrtypes) != 1:
+ # FIXME: this is unlikely in practice, but possible for
+ # programs that use both old and new string types with
+ # std::any in a single program. Can we do better?
+ # Maybe find the address of each type's _S_manage and
+ # compare to the address stored in _M_manager?
+ raise ValueError('Cannot uniquely determine std::string type used in std::any')
+ mgrtype = mgrtypes[0]
+ else:
+ mgrtype = gdb.lookup_type(mgrname)
self.contained_type = mgrtype.template_argument(0)
valptr = None
if '::_Manager_internal' in mgrname: