backtrace(3)

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

BIBLIOTECA
Biblioteca C standard (libc, -lc)

SINOPSIS
#include <execinfo.h>

int backtrace(int size;
              void *buffer[size], int size);

char **backtrace_symbols(int size;
              void *const buffer[size], int size);
void backtrace_symbols_fd(int size;
              void *const buffer[size], int size, int fd);

DESCRIERE
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.

VALOAREA RETURNATĂ
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.

ATRIBUTE
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

STANDARDE
GNU.

ISTORIC
glibc 2.1.

NOTE
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.

EXEMPLE
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]

  Sursa programului
    #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);
    }

CONSULTAȚI ȘI
addr2line(1), gcc(1), gdb(1), ld(1), dlopen(3), malloc(3)

TRADUCERE
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 (https://www.gnu.org/licenses/gpl-3.0.html) 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.