Re: [patch] on_exit.3: Add example code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




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
> 



[Index of Archives]     [Kernel Documentation]     [Netdev]     [Linux Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux