backtrace(3) Library Functions Manual backtrace(3)

backtrace, backtrace_symbols, backtrace_symbols_fd - suport pentru auto-depanarea aplicației

Biblioteca C standard (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() returnează un traseu de urmărire pentru programul apelant, în matricea indicată de buffer. Un traseu de urmărire reprezintă seria de apeluri de funcții active în acel moment pentru program. Fiecare element din matricea indicată de buffer este de tip void * și reprezintă adresa de returnare din cadrul stivei corespunzătoare. Argumentul size specifică numărul maxim de adrese care pot fi stocate în buffer. Dacă traseul de urmărire este mai mare decât size, atunci sunt returnate adresele corespunzătoare celor mai recente apeluri de funcție size; pentru a obține traseul complet, asigurați-vă că buffer și size sunt suficient de mari.

Având în vedere setul de adrese returnate de backtrace() în buffer, backtrace_symbols() traduce adresele într-o matrice de șiruri care descriu simbolic adresele. Argumentul size specifică numărul de adrese din buffer. Reprezentarea simbolică a fiecărei adrese constă în numele funcției (dacă acesta poate fi determinat), un decalaj hexazecimal în interiorul funcției și adresa reală de returnare (în hexazecimal). Adresa matricei de indicatori de șiruri este returnată ca rezultat al funcției backtrace_symbols(). Această matrice este alocată în memorie „malloc(3)” de backtrace_symbols() și trebuie eliberată de către apelant; (șirurile indicate de matricea de indicatori nu au nevoie și nu trebuie să fie eliberate).

backtrace_symbols_fd() primește aceleași argumente buffer și size ca și backtrace_symbols(), dar în loc să returneze o matrice de șiruri către apelant, scrie șirurile, câte unul pe linie, în descriptorul de fișier fd. backtrace_symbols_fd() nu apelează malloc(3) și, prin urmare, poate fi utilizată în situații în care această din urmă funcție ar putea eșua, dar a se vedea secțiunea NOTE.

backtrace() returnează numărul de adrese returnate în buffer, care nu este mai mare decât size. Dacă valoarea returnată este mai mică decât size, atunci a fost stocat întregul traseu de urmărire; dacă este egală cu size, atunci este posibil să fi fost trunchiat, caz în care adresele celor mai vechi cadre din stivă nu sunt returnate.

În caz de succes, backtrace_symbols() returnează un indicator la matricea malloc(3) creată prin apel; în caz de eroare, se returnează NULL.

Pentru o explicație a termenilor folosiți în această secțiune, a se vedea attributes(7).

Interfață Atribut Valoare
backtrace(), backtrace_symbols(), backtrace_symbols_fd() Siguranța firelor MT-Safe

GNU.

glibc 2.1.

Aceste funcții fac unele presupuneri cu privire la modul în care adresa de returnare a unei funcții este stocată în stivă. Rețineți următoarele:

Omiterea indicatorilor de cadre (așa cum implică oricare dintre nivelurile de optimizare diferite de zero ale gcc(1)) poate duce la încălcarea acestor presupuneri.
Funcțiile inserate în linie „inlined” nu au cadre de stivă.
Optimizarea apelului din coadă „tail-call” face ca un cadru de stivă să înlocuiască un altul.
backtrace() și backtrace_symbols_fd() nu apelează explicit malloc(), dar fac parte din libgcc, care se încarcă dinamic la prima utilizare. Încărcarea dinamică declanșează, de obicei, un apel la malloc(3). Dacă aveți nevoie ca anumite apeluri la aceste două funcții să nu aloce memorie (în gestionarii de semnal, de exemplu), trebuie să vă asigurați că libgcc este încărcată în prealabil.

Este posibil ca numele simbolurilor să nu fie disponibile fără utilizarea unor opțiuni speciale ale editorului de legături. Pentru sistemele care utilizează editorul de legături GNU, este necesar să se utilizeze opțiunea -rdynamic. Rețineți că numele funcțiilor „statice” nu sunt expuse și nu vor fi disponibile în traseul de urmărire.

Programul de mai jos demonstrează utilizarea backtrace() și backtrace_symbols(). Următoarea sesiune shell arată ce am putea vedea la rularea programului:


$ cc -rdynamic prog.c -o prog
$ ./prog 3
backtrace() a returnat 8 adrese
./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() a returnat %d adree\n", nptrs);
    /* Apelul backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
       ar produce o ieșire similară cu cea de mai jos: */
    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” înseamnă că nu exportă simbolul... */
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)

Traducerea în limba română a acestui manual a fost făcută de Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>

Această traducere este documentație gratuită; citiți Licența publică generală GNU Versiunea 3 sau o versiune ulterioară cu privire la condiții privind drepturile de autor. NU se asumă NICIO RESPONSABILITATE.

Dacă găsiți erori în traducerea acestui manual, vă rugăm să trimiteți un e-mail la translation-team-ro@lists.sourceforge.net.

2 mai 2024 Pagini de manual de Linux 6.8