Provided by: manpages-ru-dev_4.23.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.

АТРИБУТЫ

       Описание терминов данного раздела смотрите в 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)