nm(1)
Outil de développement
Liste les symboles d'un .o ou d'une bibliothèque : fonctions définies (T), symboles attendus ailleurs (U), variables (D, B). L'outil des undefined reference.
nm [options] fichier...Description
nm lit un fichier objet (.o), une bibliothèque (.a, .so) ou un exécutable, et affiche la table de ses symboles : les fonctions et variables globales qu'il définit, et celles qu'il utilise sans les définir. Chaque ligne donne l'adresse du symbole dans sa section, une lettre pour son type, puis son nom. C'est la vue qu'a l'éditeur de liens de ton programme, et le moyen le plus rapide de comprendre une erreur undefined reference ou multiple definition.
Lire la lettre
| Lettre | Sens |
|---|---|
T | fonction définie dans ce fichier (section de code) |
U | symbole utilisé ici mais défini ailleurs, à fournir par un autre fichier ou une bibliothèque |
D | variable globale initialisée avec une valeur non nulle |
B | variable globale non initialisée, ou initialisée à zéro |
R | donnée en lecture seule, comme un tableau const |
W | symbole faible, qu'une autre définition peut remplacer |
Une majuscule désigne un symbole global, visible des autres fichiers. Une minuscule, un symbole local : une fonction ou une variable static, que l'éditeur de liens ne proposera jamais à un autre fichier.
Options utiles
| Option | Effet |
|---|---|
-u | n'affiche que les symboles non définis (U) |
-g | n'affiche que les symboles globaux |
-D | lit les symboles dynamiques d'une bibliothèque partagée (.so) |
-A | préfixe chaque ligne par le nom du fichier, pratique avec grep |
Exemple
#include <stdio.h>
int meilleur = 20;int dernier;const char titre[] = "Scores";
static int doubler(int n){ return 2 * n;}
void afficher(int n){ printf("%s : %d\n", titre, doubler(n));}$ gcc -c score.c$ nm score.o0000000000000018 T afficher0000000000000000 B dernier0000000000000000 t doubler0000000000000000 D meilleur U printf0000000000000000 R titre$ nm -u score.o U printfChaque déclaration se retrouve : meilleur initialisée (D), dernier sans valeur (B), titre en lecture seule (R), afficher globale (T), doubler en minuscule parce que static. printf est attendu (U) : c'est la bibliothèque C qui le fournira à l'édition de liens.
Pour savoir quelle bibliothèque partagée définit une fonction, -D et grep suffisent. Sous Debian, sqrt est dans libm et pas dans libc, d'où le -lm :
$ nm -D /lib/aarch64-linux-gnu/libm.so.6 | grep -w sqrt0000000000013840 W sqrt@@GLIBC_2.17$ nm -D /lib/aarch64-linux-gnu/libc.so.6 | grep -w sqrtPièges
Les adresses d'un
.osont relatives à chaque section et valent souvent0: elles ne deviennent définitives qu'après l'édition de liens.Une fonction
staticapparaît en minuscule (t). Si un autre fichier l'appelle, l'édition de liens échoue même si nm l'affiche.Une bibliothèque partagée passée à
nmsans-Dpeut répondreno symbolsquand sa table normale a été retirée : utilise-D.Le chemin des bibliothèques dépend de la distribution et de l'architecture. L'exemple vient d'une machine ARM 64 bits.
La méthode complète pour corriger une
undefined referenceest dans undefined reference to en C.