https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87308
Bug ID: 87308 Summary: pretty printer for std::any fails with: Python Exception <type 'exceptions.ValueError'> Unknown manager function in std::any Product: gcc Version: 8.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: jeff at jgarrett dot org Target Milestone: --- Using g++-8.1 and gdb-8.2 both built from source on a CentOS 7.3 host, pretty printing a std::any fails with an exception for unknown manager function. $ gdb ./erased-lambda GNU gdb (GDB) 8.2 (gdb) run Starting program: .../erased-lambda Program received signal SIGILL, Illegal instruction. main () at erased-lambda.cpp:6 6 __builtin_trap(); (gdb) print a1 $1 = Python Exception <type 'exceptions.ValueError'> Unknown manager function in std::any: Python Exception <type 'exceptions.ValueError'> Unknown manager function in std::any: { _M_manager = 0x4007b2 <std::any::_Manager_internal<main()::<lambda()> >::_S_manage(std::any::_Op, const std::any *, std::any::_Arg *)>, _M_storage = {_M_ptr = 0x1, _M_buffer = {__data = "\001\000\000\000\000\000\000", __align = {<No data fields>}}}} It would appear that the printer attempts to match the manager function name with the following regex: rx = r"""({0}::_Manager_\w+<.*>)::_S_manage\({0}::_Op, {0} const\*, {0}::_Arg\*\)""".format(typename) Note that the second argument as printed by my gdb is 'const std::any *' versus the regex 'std::any const*' (east vs west const and space before *) and the third argument as printed by gdb is 'std::any::_Arg *' versus the regex 'std::any::_Arg*' (space before *). Applying the following patch "fixed" the regex for my particular set of versions: --- a/printers.py +++ b/printers.py @@ -1040,7 +1040,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter): func = gdb.block_for_pc(int(mgr.cast(gdb.lookup_type('intptr_t')))) if not func: raise ValueError("Invalid function pointer in %s" % self.typename) - rx = r"""({0}::_Manager_\w+<.*>)::_S_manage\({0}::_Op, {0} const\*, {0}::_Arg\*\)""".format(typename) + rx = r"""({0}::_Manager_\w+<.*>)::_S_manage\({0}::_Op, const {0} \*, {0}::_Arg \*\)""".format(typename) m = re.match(rx, func.function.name) if not m: raise ValueError("Unknown manager function in %s" % self.typename) However, even with that applied, pretty printing a lambda prints the wrong type due to a bad type lookup: (gdb) print a1 $1 = std::any containing <lambda()> = {[contained value] = {__j = 1, __k = 0}} (gdb) print a2 $2 = std::any containing <lambda()> = {[contained value] = {__j = 2, __k = 3}} Note that both a1 and a2 are interpreted as holding type main::{lambda()#2}, but a1 actually holds main::{lambda()#1}. GCC version: $ g++-8.1 -v Using built-in specs. COLLECT_GCC=/usr/local/gcc-8.1.0/bin/g++-8.1 COLLECT_LTO_WRAPPER=/usr/local/gcc-8.1.0/libexec/gcc/x86_64-pc-linux-gnu/8.1.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc-8.1.0/configure --program-suffix=-8.1 --prefix=/usr/local/gcc-8.1.0 --disable-multilib --enable-gold --enable-ld --enable-lto Thread model: posix gcc version 8.1.0 (GCC) Please let me know if I can provide anything else to help. == erased-lambda.cpp == // g++-8.1 -g -std=c++17 erased-lambda.cpp -o erased-lambda #include <any> int main() { std::any a1 = [i=1] {}; std::any a2 = [j=2,k=3] {}; __builtin_trap(); }