Как я могу показать лямбда-функции на обратных трассировках?

Я пишу программное обеспечение C++11 и использую лямбда-выражения. Когда я печатаю обратную трассировку с помощью backtrace_symbols_fd, все функции разбираются, кроме лямбда. Это немного очевидно, потому что это анонимные функции, но есть ли способ получить больше информации вместо необработанного указателя?

Я использую GCC 4.8 в Linux.


person Luca Marturana    schedule 10.04.2015    source источник
comment
Вероятно, полезно упомянуть, в каком контексте (отладчик? набор инструментов?) вы хотите это увидеть.   -  person MSalters    schedule 10.04.2015
comment
Да, какой компилятор и отладчик вы используете?   -  person LThode    schedule 10.04.2015
comment
@MSalters сделал, спасибо   -  person Luca Marturana    schedule 10.04.2015


Ответы (2)


Некоторая полезная информация существует в двоичном файле, потому что GDB может отображать более полезные имена для лямбда-функций, например.

(gdb) bt
#0  <lambda()>::operator()(void) const (__closure=0x7fffffffd5ef) at ll.cc:3
#1  0x00000000004005e7 in main () at ll.cc:3

(Хотя, возможно, в отладочной информации просто указано, что это тип закрытия, поскольку GDB показывает все такие функции как <lambda()>::operator())

Искаженное имя шаблона, созданного с типом замыкания, включает уникальное имя, например.

#3  0x0000000000400712 in func<main()::<lambda()> >(<lambda()>) (t=...) at l.cc:4

но, возможно, это имя используется только тогда, когда оно необходимо в других искаженных именах.

С помощью GCC вы также можете распечатать имя замыкания operator(), распечатав предопределенную переменную __PRETTY_FUNCTION__, которая показывает что-то вроде main()::<lambda()>

Используя Python API GDB, я могу получить еще одно имя для того же замыкания, например.

(gdb) python import gdb; print gdb.block_for_pc(0x8048591).function.name
__lambda0::operator()() const

Так что это как минимум три разных имени! Поэтому я думаю, что это, возможно, ограничение backtrace_symbols_fd, что он не может найти имена для лямбда-функций.

person Jonathan Wakely    schedule 11.04.2015

Согласно стандарту С++:

§5.1.2/3 гласит:

Тип лямбда-выражения (который также является типом объекта замыкания) является уникальным безымянным типом класса без объединения.

Я не думаю, что есть способ получить больше полезной информации. По сути, лямбды — это просто экземпляры анонимных классов.

person szulak    schedule 11.04.2015
comment
Им по-прежнему нужно какое-то имя для связи и искажения имен, даже если это имя не может быть произнесено пользователями. например если вы создаете экземпляр шаблона с типом замыкания, компилятору необходимо закодировать тип замыкания в искаженном имени специализации шаблона. - person Jonathan Wakely; 11.04.2015