BACKTRACE(3) Manuel du programmeur Linux BACKTRACE(3)

backtrace, backtrace_symbols, backtrace_symbols_fd - Outils d'auto-débogage d'applications

#include <execinfo.h>
int backtrace(void **buffer, int size);
char **backtrace_symbols(void *const *buffer, int size);
void backtrace_symbols_fd(void *const *buffer, int size, int fd);

backtrace() renvoie une trace des appels du programme dans un tableau pointé par buffer. Une trace est une série d'appels de fonction actuellement actif d'un programme. Chaque élément du tableau pointé par buffer est de type void *, et correspond à l'adresse de retour de la « stack frame » correspondante. Le paramètre size spécifie le nombre maximum d'adresses qui peut être enregistré dans buffer. Si la trace est plus grande que size, alors les adresses correspondant aux size plus récents appels de fonction sont retournées. Pour obtenir une trace complète, soyez sûre que buffer et size sont assez grand.

À partir des adresses renvoyées par backtrace() dans le buffer, backtrace_symbols() traduit les adresses en un tableau de chaînes qui donne les symboles associés à ces adresses. Le paramètre size indique le nombre d'adresses dans le buffer. La représentation symbolique de chaque adresse consiste en un nom de fonction (s'il peut être déterminé), un décalage hexadécimal à l'intérieur de la fonction, et l'adresse (hexadécimale) de retour. L'adresse du tableau de chaînes est renvoyé comme résultat de la fonction backtrace_symbols(). Ce tableau est alloué avec malloc(3) par backtrace_symbols() et doit être libéré par l'appelant. Les chaînes pointées par le tableau de pointeurs n'ont pas et ne devraient pas être libérées.

backtrace_symbols_fd() takes the same buffer and size arguments as backtrace_symbols(), but instead of returning an array of strings to the caller, it writes the strings, one per line, to the file descriptor fd. backtrace_symbols_fd() does not call malloc(3), and so can be employed in situations where the latter function might fail, but see NOTES.

backtrace() fournit le nombre d'adresses renvoyées dans le buffer, qui ne sera pas supérieur à size. Si la valeur de retour est inférieure à size, alors toute la trace a pu être sauvée ; si elle est égale à size, alors il se peut qu'elle ait été tronquée et les adresses des trames les plus anciennes sur la pile ne sont pas renvoyées.

En cas de succès, backtrace_symbols() renvoie un pointeur vers le tableau alloué avec malloc(3). En cas d'erreur NULL est renvoyé.

backtrace(), backtrace_symbols() et backtrace_symbols_fd() sont fournies par la glibc depuis la version 2.1.

Pour une explication des termes utilisés dans cette section, consulter attributes(7).

Interface Attribut Valeur
backtrace(), backtrace_symbols(), backtrace_symbols_fd() Sécurité des threads MT-Safe

Ces fonctions sont des extensions GNU.

Ces fonctions font des suppositions sur la façon dont l'adresse de retour d'une fonction est sauvegardée dans la pile. Prenez note des points suivants :

  • L'omission du pointeur de trame (comme le fait gcc(1) avec les niveaux d'optimisation différents de zéro) peut être incompatible avec ces suppositions.
  • Les fonctions en lignes (« inline ») n'apparaissent pas sur la pile.
  • Avec les optimisations de type Tail-call une trame sur la pile peut être remplacée par une autre.
  • backtrace() and backtrace_symbols_fd() don't call malloc() explicitly, but they are part of libgcc, which gets loaded dynamically when first used. Dynamic loading usually triggers a call to malloc(3). If you need certain calls to these two functions to not allocate memory (in signal handlers, for example), you need to make sure libgcc is loaded beforehand.

Le nom des symboles peut ne pas être disponible si certaines options de l'éditeur de liens n'ont pas été utilisées. Pour les systèmes qui utilisent l'éditeur de liens GNU, il faut utiliser l'option -rdynamic. Notez que les noms des fonctions statiques (avec le mot clef « static ») ne sont pas exposés, et ne seront pas disponibles pour la trace.

Le programme ci-dessous explique l'utilisation de backtrace() et backtrace_symbols(). Les sessions d'interpréteur de commandes montrent ce que produira l'exécution du programme :


$ 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 (int 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)

Cette page fait partie de la publication 5.13 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies et la dernière version de cette page peuvent être trouvées à l'adresse https://www.kernel.org/doc/man-pages/.

La traduction française de cette page de manuel a été créée par Christophe Blaess https://www.blaess.fr/christophe/, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org> et David Prévot <david@tilapin.org>

Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.

22 mars 2021 GNU