If I have the following program written in C (compiled with GCC on Debian 8.7), I am able to call atexit()
as you would expect:
#include <stdlib.h>
void exit_handler(void) {
return;
}
int main () {
atexit(exit_handler);
return 0;
}
And when I compile and run it:
$ gcc test.c
$ ./a.out
Outputs nothing, just as you would expect. In fact, when I run ldd
, I get:
$ ldd a.out
linux-vdso.so.1 (0x00007fffbe592000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe07d3a8000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe07d753000)
However, libc
does not seem to have any symbols for atexit
, amd only has__cxa_atexit
and __cxa_threaded_atexit_impl
:
$ nm --dynamic /lib/x86_64-linux-gnu/libc.so.6 | grep 'atexit'
0000000000037d90 T __cxa_atexit
0000000000037fa0 T __cxa_thread_atexit_impl
As you would then expect, if I try to link to libc
dynamically, I cannot actually call atexit()
, such as in the following Racket program which links to libc
and tries to find atexit
:
#lang racket
(require ffi/unsafe)
(get-ffi-obj 'atexit (ffi-lib "libc" '("6")) (_fun (_fun -> _void) -> _int))
Giving the output:
$ racket findatexit.rkt
ffi-obj: couldn't get "atexit" from "libc.so.6" (/lib/x86_64-linux-gnu/libc.so.6: undefined symbol: atexit)
What I want to know here is:
- If
libc
does not have any symbol foratexit
on Linux, why can I still call it from a C program? - Is there any way I can call
atexit
or a similar function dynamically on Linux?
(I should note that atexit
does appear to be a symbol on OS X, so its just Linux that seems unusual here.)
Edit:
At the suggestion of @Jonathan, I also ran:
$ gcc -c test.c
$ nm test.o
U atexit
0000000000000000 T exit_handler
0000000000000007 T main
Which seems to indicate the atexit
symbol is there somewhere, but it does not appear in any of the libraries ldd
is showing.
gcc -c test.c; nm test.o
and see what symbols are referenced there. – Burkeyatexit()
somehow. Have you looked inld.so.1
(or, for you, perhaps/lib64/ld-linux-x86-64.so.2
) for the symbol? Or perhapscrt0.o
, or whatever is linked? You may need to rungcc -v test.c
to see exactly what libraries and object files are linked. – Burkey$ nm --dynamic /lib64/ld-linux-x86-64.so.2 | grep 'atexit'
– Fenugreek