Provided by: manpages-ru-dev_4.18.1-1_all bug

ИМЯ

       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.

ВЕРСИИ

       backtrace(),  backtrace_symbols(),  and  backtrace_symbols_fd()   are provided since glibc
       2.1.

АТРИБУТЫ

       Описание терминов данного раздела смотрите в attributes(7).

       ┌───────────────────────────────────────────────────────┬──────────────────────┬──────────┐
       │ИнтерфейсАтрибутЗначение │
       ├───────────────────────────────────────────────────────┼──────────────────────┼──────────┤
       │backtrace(), backtrace_symbols(),                      │ Безвредность в нитях │ MT-Safe  │
       │backtrace_symbols_fd()                                 │                      │          │
       └───────────────────────────────────────────────────────┴──────────────────────┴──────────┘

СТАНДАРТЫ

       Эти функции являются расширениями GNU.

ЗАМЕЧАНИЯ

       Поведение  данных  функций  основано  на  предположении,  что  адреса  возврата из функций
       хранятся в стеке. Заметим следующее:

       •  Отсутствие указателей кадров (происходит при  указании 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() вернула %d адресов\n", nptrs);

           /* При вызове backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
              получилось бы подобное следующему: */

           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 количество-вызовов\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 версии 3 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ или более позднюю, чтобы
       узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

       Если  вы  обнаружите  ошибки  в  переводе этой страницы руководства, пожалуйста, отправьте
       электронное письмо на ⟨man-pages-ru-talks@lists.sourceforge.net⟩.