Статические данные, упомянутые для опции -funwind-tables
, представляют собой информацию о разворачивании кадра, то есть данные, которые позволяют работающей программе проходить назад стек вызовов функций из заданной точки выполнения. Возвращение к стеку вызовов функций означает переход из контекста выполнения вызываемой функции в контекст вызывающей стороны, то есть то, что обычно происходит, когда вы возвращаете из функции, за исключением того, что информация о разворачивании кадра позволяет вам это делать. из произвольной точки внутри тела функции; Кроме того, вы не обязаны фактически выходить из вызываемой функции, вы можете просто «заглянуть» внутрь контекста вызывающей стороны (например, чтобы извлечь местоположение, из которого была вызвана вызываемая функция), также рекурсивно, но затем продолжить нормальный поток выполнения в вызываемая функция.
Чтобы сделать это, вам нужно иметь доступ к большему количеству информации о скомпилированном коде, чем то, что строго необходимо для того, чтобы программа следовала «нормальному» потоку выполнения. Эта информация (то есть информация о разворачивании фрейма) помещается компоновщиком в специальные разделы компоновщика (например, раздел .eh_frame для платформы x86 или разделы ARM.exidx и .ARM.extab для платформы ARM), предназначенные для этой цели; эти секции компоновщика такие же, которые необходимы в таких языках, как C ++, для реализации обработки исключений, когда поток выполнения может перейти от вызываемой функции к вызывающей стороне в результате возникновения исключения. Если вы отключите генерацию этих данных с помощью опции -fno-unwind-tables
, вы не сможете вернуться назад к стеку вызовов функций или использовать исключения C ++.
В частности, информация о разворачивании фрейма используется libunwind , кроссплатформенной библиотекой, которая поддерживает генерацию обратных трасс, переход к произвольным точкам в стеке вызовов и т. Д.
_Unwind_Backtrace()
- это функция, реализованная в основных библиотеках GCC (точнее, в libgcc_s), которая позволяет выполнять функцию обратного вызова (предоставляется в качестве аргумента) для каждого кадра в стеке вызовов, то есть начиная с контекста функции вызывающей стороны, переезд к своему абоненту и так далее. См. https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/baselib--unwind-backtrace.html. Опять же, для того, чтобы эта функция могла выполнять свои функции, требуется доступ к информации о разворачивании кадра из соответствующих разделов компоновщика.