6.51 Получение адреса возврата или фрейма функции
Эти функции могут использоваться для получения информации о вызывающих функциях.
-
Встроенная функция:
void *__builtin_return_address(unsigned int level) -
Эта функция возвращает адрес возврата текущей функции или одной из её вызывающих функций. Аргумент level задаёт количество фреймов для поиска вверх по стеку вызовов. Значение
0соответствует адресу возврата текущей функции, значение1— адресу возврата вызывающей функции и так далее. При инлайнинге ожидается, что функция вернёт адрес функции, к которой происходит возврат. Для обхода этого поведения используйте атрибут функцииnoinline.Аргумент level должен быть целочисленной константой.
На некоторых машинах может быть невозможно определить адрес возврата любой функции, кроме текущей; в таких случаях или когда достигнут верх стека, эта функция возвращает неопределённое значение. Кроме того,
__builtin_frame_addressможет использоваться для определения достижения вершины стека.Дополнительная пост-обработка возвращаемого значения может потребоваться, см.
__builtin_extract_return_addr.Хранение адреса возврата в памяти может отличаться от адреса, возвращаемого
__builtin_return_address. Например, на AArch64 сохранённый адрес может быть изменён с помощью подписи адреса возврата, в то время как адрес, возвращаемый__builtin_return_address, не является таким.Вызов этой функции с ненулевым аргументом может привести к непредсказуемым последствиям, включая сбой программы. В результате вызовы, которые считаются небезопасными, диагностируются при использовании опции -Wframe-address. Такие вызовы следует использовать только в отладочных ситуациях.
На целевых платформах, где адреса кода могут быть представлены как
void *,void *addr = __builtin_extract_return_addr (__builtin_return_address (0));
возвращает адрес кода, к которому текущая функция вернётся. Например, такой адрес может использоваться с
dladdrили другими интерфейсами, работающими с адресами кода.
-
Встроенная функция:
void *__builtin_extract_return_addr(void *addr) -
Адрес, возвращаемый
__builtin_return_address, может потребоваться обработать с помощью этой функции, чтобы получить фактический закодированный адрес. Например, на 31-разрядной платформе S/390 старший бит необходимо скрыть, или на платформах SPARC необходимо добавить смещение для определения истинного следующего выполняемого инструкцию.Если корректировка не требуется, функция просто пропускает addr.
-
Встроенная функция:
void *__builtin_frob_return_addr(void *addr) Эта функция выполняет обратное действие, чем
__builtin_extract_return_addr.
-
Встроенная функция:
void *__builtin_frame_address(unsigned int level) -
Эта функция похожа на
__builtin_return_address, но возвращает адрес фрейма функции, а не адрес возврата функции. Вызов__builtin_frame_addressсо значением0возвращает адрес фрейма текущей функции, значение1— адрес фрейма вызывающей функции и так далее.Фрейм — это область в стеке, содержащая локальные переменные и сохранённые регистры. Адрес фрейма обычно является адресом первого слова, помещённого в стек функцией. Однако точное определение зависит от процессора и соглашения о вызовах. Если процессор имеет выделенный регистр указателя фрейма, и функция имеет фрейм, то
__builtin_frame_addressвозвращает значение регистра указателя фрейма.На некоторых машинах может быть невозможно определить адрес фрейма любой функции, кроме текущей; в таких случаях или при достижении вершины стека, эта функция возвращает
0, если указатель фрейма первой функции правильно инициализирован кодом запуска.Вызов этой функции с ненулевым аргументом может иметь непредсказуемые последствия, включая сбой программы. В результате вызовы, которые считаются небезопасными, диагностируются при использовании опции -Wframe-address. Такие вызовы следует использовать только в отладочных ситуациях.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-13.3.0/gcc/Return-Address.html