Provided by: manpages-ru-dev_4.23.1-1_all 

ИМЯ
backtrace, backtrace_symbols, backtrace_symbols_fd - поддержка самоотладки в приложении
LIBRARY
Standard C library (libc, -lc)
СИНТАКСИС
#include <execinfo.h>
int backtrace(void *buffer[.size], int size);
char **backtrace_symbols(void *const buffer[.size], int size);
void backtrace_symbols_fd(void *const buffer[.size], int size, int fd);
ОПИСАНИЕ
Функция backtrace() возвращает список запущенных функций вызвавшей программы в массив, на который
указывает buffer. Список вызванных функций (backtrace) — это последовательность в данный момент активных
вызовов функций программы. Каждый элемент в массиве, на который указывает buffer, имеет тип void * и
указывает на адрес возврата из соответствующего стекового кадра (stack frame). В аргументе size задаётся
максимальное количество адресов, которые могут храниться в buffer. Если список вызванных функций больше
size, то возвращаются size адресов функций, вызванных последними; чтобы получить полный список вызванных
функций, сделайте buffer и size достаточно большими.
Набор адресов, полученных от backtrace() через buffer, функция backtrace_symbols() транслирует в массив
строк, в которых адреса представлены в символическом виде. В аргументе size передаётся количество адресов
в buffer. Символический вид каждого адреса содержит имя функции (если его можно определить),
шестнадцатеричное смещение в функции и реальный адрес возврата (в шестнадцатеричном виде). Результатом
функции backtrace_symbols() является адрес массива указателей на строки. Этот массив выделяется
backtrace_symbols() с помощью malloc(3) и должен освобождаться вызывающим (строки, на которые указывают
указатели в массиве, освобождаться не должны).
Функция backtrace_symbols_fd() ожидает аргументы buffer и size как у backtrace_symbols(), но вместо
записи строк в массив вызывающему, она записывает строки, одну в строке, в файловый дескриптор fd.
Функция backtrace_symbols_fd() не вызывает malloc(3) и поэтому может применяться в случаях, когда вызов
malloc(3) может завершаться ошибкой, но смотрите ЗАМЕЧАНИЯ.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Функция backtrace() возвращает количество адресов, записанных в buffer, и не может быть больше size. Если
возвращаемое значение меньше size, то был сохранён полный список вызванных функций; если значение равно
size, то список может быть не полным, то есть адреса самых старых кадров стека могут отсутствовать.
При успешном выполнении backtrace_symbols() возвращает указатель на массив, выделенный malloc(3); при
ошибке возвращается NULL.
АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).
┌─────────────────────────────────────────────────────────────────────┬──────────────────────┬──────────┐
│ Интерфейс │ Атрибут │ Значение │
├─────────────────────────────────────────────────────────────────────┼──────────────────────┼──────────┤
│ backtrace(), backtrace_symbols(), backtrace_symbols_fd() │ Безвредность в нитях │ MT-Safe │
└─────────────────────────────────────────────────────────────────────┴──────────────────────┴──────────┘
СТАНДАРТЫ
GNU.
ИСТОРИЯ
glibc 2.1.
ПРИМЕЧАНИЯ
Поведение данных функций основано на предположении, что адреса возврата из функций хранятся в стеке.
Заметим следующее:
• Отсутствие указателей кадров (происходит при указании gcc(1) любого ненулевого уровня оптимизации)
может вызвать нарушение этих предположений.
• Встраиваемые (inlined) функции не имеют стековых кадров.
• Оптимизация хвостовых вызовов приводит к замещению одного стекового кадра другим.
• Функция backtrace() и backtrace_symbols_fd() не вызывает malloc() явным образом, но они являются
частью libgcc, которая загружается динамически при первом использовании. Обычно, динамическая загрузка
вызывает malloc(3). Если вам нужно, чтобы работа с этими функциями не приводила к выделению памяти
(например, в обработчиках сигналов), то перед обращением загрузите libgcc самостоятельно.
Символьные имена могут быть недоступны, если не указаны специальные параметра компоновщика. В системах с
компоновщиком GNU необходимо использовать параметр -rdynamic. Заметим, что имена «статических» функций не
показываются, и недоступны в списке вызовов функций.
ПРИМЕРЫ
Программа, представленная далее, демонстрирует использование backtrace() и backtrace_symbols(). В
следующем сеансе оболочки показано, что может получиться при запуске программы:
$ cc -rdynamic prog.c -o prog
$ ./prog 3
backtrace() returned 8 addresses
./prog(myfunc3+0x5c) [0x80487f0]
./prog [0x8048871]
./prog(myfunc+0x21) [0x8048894]
./prog(myfunc+0x1a) [0x804888d]
./prog(myfunc+0x1a) [0x804888d]
./prog(main+0x65) [0x80488fb]
/lib/libc.so.6(__libc_start_main+0xdc) [0xb7e38f9c]
./prog [0x8048711]
Исходный код программы
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define BT_BUF_SIZE 100
void
myfunc3(void)
{
int nptrs;
void *buffer[BT_BUF_SIZE];
char **strings;
nptrs = backtrace(buffer, BT_BUF_SIZE);
printf("backtrace() returned %d addresses\n", nptrs);
/* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
would produce similar output to the following: */
strings = backtrace_symbols(buffer, nptrs);
if (strings == NULL) {
perror("backtrace_symbols");
exit(EXIT_FAILURE);
}
for (size_t j = 0; j < nptrs; j++)
printf("%s\n", strings[j]);
free(strings);
}
static void /* "static" means don't export the symbol... */
myfunc2(void)
{
myfunc3();
}
void
myfunc(int ncalls)
{
if (ncalls > 1)
myfunc(ncalls - 1);
else
myfunc2();
}
int
main(int argc, char *argv[])
{
if (argc != 2) {
fprintf(stderr, "%s num-calls\n", argv[0]);
exit(EXIT_FAILURE);
}
myfunc(atoi(argv[1]));
exit(EXIT_SUCCESS);
}
СМОТРИТЕ ТАКЖЕ
addr2line(1), gcc(1), gdb(1), ld(1), dlopen(3), malloc(3)
ПЕРЕВОД
Русский перевод этой страницы руководства разработал Artyom Kunyov <artkun@guitarplayer.ru>, Azamat
Hackimov <azamat.hackimov@gmail.com>, Dmitriy Ovchinnikov <dmitriyxt5@gmail.com>, Dmitry Bolkhovskikh
<d20052005@yandex.ru>, ITriskTI <ITriskTI@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов
<pavia00@gmail.com>
Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной
лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или
более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.
Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом
разработчику по его адресу электронной почты или по адресу списка рассылки русских переводчиков.
Linux man-pages 6.8 2 мая 2024 г. backtrace(3)