nm(1)
Development tool
Lists the symbols of a .o or a library: defined functions (T), symbols expected from elsewhere (U), variables (D, B). The tool for undefined reference errors.
nm [options] file...Description
nm reads an object file (.o), a library (.a, .so) or an executable, and prints its symbol table: the global functions and variables it defines, and the ones it uses without defining them. Each line gives the symbol's address within its section, a letter for its type, then its name. This is the linker's view of your program, and the fastest way to understand an undefined reference or multiple definition error.
Reading the letter
| Letter | Meaning |
|---|---|
T | function defined in this file (code section) |
U | symbol used here but defined elsewhere, to be provided by another file or a library |
D | global variable initialized with a nonzero value |
B | global variable left uninitialized, or initialized to zero |
R | read-only data, such as a const array |
W | weak symbol, which another definition can replace |
An uppercase letter marks a global symbol, visible to other files. A lowercase letter marks a local symbol: a static function or variable, which the linker will never offer to another file.
Useful options
| Option | Effect |
|---|---|
-u | shows only the undefined symbols (U) |
-g | shows only the global symbols |
-D | reads the dynamic symbols of a shared library (.so) |
-A | prefixes each line with the file name, handy with grep |
Example
#include <stdio.h>
int best = 20;int last;const char title[] = "Scores";
static int twice(int n){ return 2 * n;}
void show(int n){ printf("%s: %d\n", title, twice(n));}$ gcc -c score.c$ nm score.o0000000000000000 D best0000000000000000 B last U printf0000000000000018 T show0000000000000000 R title0000000000000000 t twice$ nm -u score.o U printfEvery declaration is there: best initialized (D), last without a value (B), title read-only (R), show global (T), twice in lowercase because it is static. printf is expected (U): the C library will provide it at link time.
To find out which shared library defines a function, -D and grep are enough. On Debian, sqrt lives in libm, not in libc, hence the -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 sqrtPitfalls
The addresses in a
.oare relative to each section and are often0: they only become final after linking.A
staticfunction shows up in lowercase (t). If another file calls it, linking fails even though nm lists it.A shared library passed to
nmwithout-Dcan answerno symbolswhen its regular symbol table has been stripped: use-D.Library paths depend on the distribution and the architecture. The example comes from a 64-bit ARM machine.
The full method for fixing an
undefined referenceis in undefined reference to in C.