> >Because the parent attempted to free that memory
> >by calling free(to_free), but the child (as I explained)
> >did not store the pointer in need of freeing into to_free.
> >to_free remained NULL, and parent didn't free anything.
>
> For the record, the above is not quite correct. The child absolutely does
store the pointer into the stack variable of the parent.
What GCC has optimized out is fetching that pointer from "to_free" in order
to pass it to the free() call.
Instead the compiler simply inserts NULL instead of actually loading the
variable from memory.

Attached is a gdb session log that conclusively proves that that is what
happens.

But it is still an optimization problem and declaring to_free as volatile
should solve it.
busybox-1.37.0$ gdb sh...Reading symbols from sh...
(gdb) set detach-on-fork off
(gdb) set follow-fork-mode child
(gdb) br generate_stream_from_string
Breakpoint 1 at 0xd739: file shell/hush.c, line 7723.
(gdb) run...  including entering the command "v=$(echo 0)" (without the quotes) 
on the hush command line
Breakpoint 1, generate_stream_from_string (s=0x555555590a54 "echo 0", 
pid_p=0x7fffffffd9e0)
    at shell/hush.c:7723
7723    {
(gdb) next
7727            char **to_free = NULL;
(gdb) next
7730            xpipe(channel);
(gdb) print &to_free
$1 = (char ***) 0x7fffffffd998
(gdb) watch *0x7fffffffd998
Hardware watchpoint 2: *0x7fffffffd998
(gdb) x/x &to_free
0x7fffffffd998: 0x00000000(gdb) cont
Continuing.
[Attaching after process 402040 vfork to child process 402163]
[New inferior 2 (process 402163)]
0x55555558f4e0 line 7564: zalloc(sizeof(argv[0]) * cnt) pid 402163
[Switching to process 402163]

Thread 2.1 "sh" hit Hardware watchpoint 2: *0x7fffffffd998

Old value = 0
New value = 1431893216
re_execute_shell (to_free=0x7fffffffd998, s=0x555555590a54 "echo 0", 
    g_argv0=0x7fffffffe36b "/home/user/Downloads/busybox-1.37.0/sh", 
g_argv=0x7fffffffe040, 
    builtin_argv=0x0) at shell/hush.c:7565
7565            *pp++ = (char *) G.argv0_for_re_execing;(gdb) x/xg 
0x7fffffffd9980x7fffffffd998: 0x000055555558f4e0(gdb) cont
Continuing.
process 402163 is executing new program: /busybox-1.37.0/sh
...[Inferior 2 (process 402163) exited normally](gdb) info inferiors
  Num  Description       Executable        
  1    process 402040    /busybox-1.37.0/sh 
* 2    <null>            /busybox-1.37.0/sh 
(gdb) inferior 1
[Switching to inferior 1 [process 402040] (/busybox-1.37.0/sh)]
[Switching to thread 1.1 (process 402040)]
#0  vfork () at ../sysdeps/unix/sysv/linux/x86_64/vfork.S:62
62      ../sysdeps/unix/sysv/linux/x86_64/vfork.S: No such file or 
directory.(gdb) x/xg 0x7fffffffd998
0x7fffffffd998: 0x000055555558f4e0
(gdb) list hush.c:7823
7818    //              " G.count_SIGCHLD:%d G.handled_SIGCHLD:%d",
7819    //              getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
7820    # endif
7821            enable_restore_tty_pgrp_on_exit();
7822    # if !BB_MMU
7823            free(to_free);
7824    # endif
7825            close(channel[1]);
7826            return channel[0];
7827    }(gdb) br 7821Breakpoint 3 at 0x555555561838: /home/us 
er/Downloads/busybox-1.37.0/shell/hush.c:7821. (2 locations)
(gdb) cont
Continuing.

Thread 1.1 "sh" hit Breakpoint 3, generate_stream_from_string (s=0x555555590a54 
"echo 0", 
    pid_p=0x7fffffffd9e0) at shell/hush.c:7821
7821            enable_restore_tty_pgrp_on_exit();
(gdb) x/xg 0x7fffffffd998
0x7fffffffd998: 0x000055555558f4e0
(gdb) next
7823            free(to_free);
(gdb) x/xg 0x7fffffffd9980x7fffffffd998:        0x000055555558f4e0
(gdb) x/7i $pc-12
   0x55555556183c <generate_stream_from_string+259>:    pop    %rax
   0x55555556183d <generate_stream_from_string+260>:    add    %al,(%rax)
   0x55555556183f <generate_stream_from_string+262>:    xor    %edx,%edx
   0x555555561841 <generate_stream_from_string+264>:    mov    
%rax,0x268b0(%rip)        # 0x5555555880f8 <die_func>
=> 0x555555561848 <generate_stream_from_string+271>:    callq  0x55555555e984 
<xxfree>
   0x55555556184d <generate_stream_from_string+276>:    mov    0x24(%rsp),%edi
   0x555555561851 <generate_stream_from_string+280>:    callq  0x55555555a4e0 
<close@plt>
(gdb) info reg
rax            0x555555567089      93824992309385
rbx            0x5555555892a0      93824992449184
rcx            0x7ffff7e9c0dc      140737352679644
rdx            0x0                 0
rsi            0x555555582c46      93824992422982
rdi            0x1e8f              7823
rbp            0x1                 0x1
rsp            0x7fffffffd980      0x7fffffffd980
r8             0x55555558f2d0      93824992473808
r9             0x2b                43
r10            0x555555582891      93824992422033
r11            0x246               582
r12            0x7fffffffda70      140737488345712
r13            0xe0                224
r14            0x0                 0
r15            0x7fffffffd9f0      140737488345584
rip            0x555555561848      0x555555561848 
<generate_stream_from_string+271>
eflags         0x246               [ PF ZF IF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0
_______________________________________________
busybox mailing list
busybox@busybox.net
https://lists.busybox.net/mailman/listinfo/busybox

Reply via email to