Am 13.06.2019 21:39, schrieb Sami Kerola: > On Wed, 12 Jun 2019 at 23:20, Michael Kerrisk (man-pages) > <mtk.manpages@xxxxxxxxx> wrote: >> On Tue, 7 May 2019 at 23:17, Sami Kerola <kerolasa@xxxxxx> wrote: >>> >>> Example tries to clarify one should not refer to variables that are not in >>> on_exit() scope. Such variables include heap in main(). In short only >> >> I must confess I never thought about this one at length. Why are heap >> variable not in scope for fcuntions registered with >> on_exit()/atexit()? > > Hello Michael, > > To be honest I do not know why heap variables do not work. If I must guess > I would say probably something to do with when during execution main() heap > is returned back to free memory - that is before on_exit() runs. > The memory of i in brocken.c is allocated in main() and freed when you leave main. Because on_exit() is running after main(), game over. hope that helps, re, wh > Any way the following shell script will print 42 when on_exit() refers > variable that is allocated. At least with up to date (2019-06-13) arch > linux (glibc 2.29-1) compiled either gcc or clang will print 0 when > executing broken version. I suppose zero is just co-incident. More > probably value does not have any guarantees. > > Whether on_exit() update should example code showing how to use function > properly, or a warning in BUGS section is matter of taste. Either way it > would be nice if others would not need wonder what is this function doing. > > -- snip > #!/bin/sh > > cat > ./broken.c <<EOF > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > #include <unistd.h> > > static void run_on_exit(int exit_val, void *arg) > { > int *i = (int *)arg; > > printf("%d\n", *i); > _exit(exit_val); > } > > int main(int argc, char **argv) > { > int i = 42; > > on_exit(run_on_exit, &i); > return 0; > } > EOF > > cat > ./works.c <<EOF > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > #include <unistd.h> > > static void run_on_exit(int exit_val, void *arg) > { > int *i = (int *)arg; > > printf("%d\n", *i); > free(i); > _exit(exit_val); > } > > int main(int argc, char **argv) > { > int *i = malloc(sizeof(int)); > > *i = 42; > on_exit(run_on_exit, i); > return 0; > } > EOF > > gcc -Wall -pedantic -o broken broken.c > gcc -Wall -pedantic -o works works.c > set -x > ./broken > ./works > -- snip > > $ ./snip.sh > + ./broken > 0 > + ./works > 42 >