bug-bash
[Top][All Lists]
Advanced

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

Re: Possible race condition in bash


From: Nikolay Borisov
Subject: Re: Possible race condition in bash
Date: Sat, 21 Nov 2020 20:35:12 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0


On 21.11.20 г. 20:09 ч., Chet Ramey wrote:
> On 11/21/20 3:06 AM, Nikolay Borisov wrote:
> 
>> The output is:
>>
>> my pid 12186
>> 12186 subfun xxx 0
>> funpid=12186 twopid=12187 mypid=12185
>> killing 12186 12187
>> waiting on everything
>> my pid 12187
>> 12187 subfun yyy 0
>> received term for xxx
>> 12187 subfun yyy 1
>> 12187 subfun yyy 2
>> 12187 subfun yyy 3
>>
>>
>> and 12187 keeps printing. It would seem there $! can return a pid of the
>> subshell before it's in a state that it can be killed. 
> 
> This is a potential race condition, but it's not with the shell. The
> parent shell sets $! as soon as the child pid returns from fork(), and
> that doesn't have anything to do with when the child gets scheduled or
> runs. You might have better luck running this under strace or truss and
> seeing what happens with the timing: whether the child sets SIGTERM to
> the trap handler before the signal arrives, or whether the child resets
> the SIGTERM handler to what the parent had before the trap before the
> signal arrives.

So I straced the execution of a run which hangs (keeps printing) and here is 
what I see 
(full log can be found at https://termbin.com/umhnv): 


12392 write(1, "funpid=12393 twopid=12394 mypid="..., 38) = 38                  
12392 write(1, "killing 12393 12394\n", 20) = 20                                
12392 kill(12393, SIGTERM)              = 0                                     
12392 kill(12394, SIGTERM)              = 0                                     
12392 write(1, "waiting on everything\n", 22) = 22       

So 12392 is the pid of the main  shell which spawns 2 subshells 
with pids 12393 and 12394, sends SIGTERM to them. 
And they seem  to receive the signal but ignore it: 


2392 wait4(-1,  <unfinished ...>                                               
12394 --- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=12392, si_uid=0} 
---
12393 --- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=12392, si_uid=0} 
---
12394 rt_sigreturn({mask=[INT CHLD]} <unfinished ...>                           
12393 rt_sigreturn({mask=[INT CHLD]} <unfinished ...>                           
12394 <... rt_sigreturn resumed> )      = 0                                     
12393 <... rt_sigreturn resumed> )      = 0                                     
12394 getpid()                          = 12394                                 
12393 getpid( <unfinished ...>                                                  
12394 close(255 <unfinished ...>                                                
12393 <... getpid resumed> )            = 12393                                 
12394 <... close resumed> )             = 0                                     
12394 rt_sigprocmask(SIG_SETMASK, [],  <unfinished ...>                         
12393 close(255 <unfinished ...>                                                
12394 <... rt_sigprocmask resumed> NULL, 8) = 0                                 
12393 <... close resumed> )             = 0                                     
12394 rt_sigaction(SIGTSTP, {sa_handler=SIG_DFL, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0},             <unfinished ...>
12393 rt_sigprocmask(SIG_SETMASK, [],  <unfinished ...>                         
12394 <... rt_sigaction resumed> {sa_handler=SIG_DFL, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0}, 8) = 0
12393 <... rt_sigprocmask resumed> NULL, 8) = 0                                 
12394 rt_sigaction(SIGTTIN, {sa_handler=SIG_DFL, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0},             <unfinished ...>
12393 rt_sigaction(SIGTSTP, {sa_handler=SIG_DFL, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0},             <unfinished ...>
12394 <... rt_sigaction resumed> {sa_handler=SIG_DFL, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0}, 8) = 0
12393 <... rt_sigaction resumed> {sa_handler=SIG_DFL, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0}, 8) = 0
12394 rt_sigaction(SIGTTOU, {sa_handler=SIG_DFL, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0},             <unfinished ...>
12393 rt_sigaction(SIGTTIN, {sa_handler=SIG_DFL, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0},             <unfinished ...>
12394 <... rt_sigaction resumed> {sa_handler=SIG_DFL, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0}, 8) = 0
12393 <... rt_sigaction resumed> {sa_handler=SIG_DFL, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0}, 8) = 0
12394 rt_sigaction(SIGHUP, {sa_handler=0x55b5e4479d80, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0},       <unfinished ...>
12393 rt_sigaction(SIGTTOU, {sa_handler=SIG_DFL, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0},             <unfinished ...>
12394 <... rt_sigaction resumed> {sa_handler=0x55b5e4476400, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0}, 8) = 0
12393 <... rt_sigaction resumed> {sa_handler=SIG_DFL, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0}, 8) = 0
12394 rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0},              
{sa_handler=0x55b5e4476400, sa_mask=[], sa_flags=SA_RESTORER, 
sa_restorer=0x7f8c881fdfd0}, 8) = 0
12394 rt_sigaction(SIGQUIT, {sa_handler=SIG_DFL, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0},             <unfinished ...>
12393 rt_sigaction(SIGHUP, {sa_handler=0x55b5e4479d80, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0},       <unfinished ...>
12394 <... rt_sigaction resumed> {sa_handler=0x55b5e4476400, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0}, 8) = 0
12393 <... rt_sigaction resumed> {sa_handler=0x55b5e4476400, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0}, 8) = 0
12394 rt_sigaction(SIGTERM, {sa_handler=0x55b5e4479d80, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0},      <unfinished ...>
12393 rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0},              <unfinished ...>
12394 <... rt_sigaction resumed> {sa_handler=0x55b5e4476400, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0}, 8) = 0
12393 <... rt_sigaction resumed> {sa_handler=0x55b5e4476400, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0}, 8) = 0
12394 rt_sigaction(SIGCHLD, {sa_handler=SIG_DFL, sa_mask=[], 
sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f8c881fdfd0},  <unfinished ...>
12393 rt_sigaction(SIGQUIT, {sa_handler=SIG_DFL, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0},             <unfinished ...>
12394 <... rt_sigaction resumed> {sa_handler=0x55b5e445cb40, sa_mask=[], 
sa_flags=SA_RESTORER|SA_RESTART,                   sa_restorer=0x7f8c881fdfd0}, 
8) = 0
12393 <... rt_sigaction resumed> {sa_handler=0x55b5e4476400, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0}, 8) = 0
12394 openat(AT_FDCWD, "/dev/null", O_RDONLY <unfinished ...>                   
12393 rt_sigaction(SIGTERM, {sa_handler=0x55b5e4479d80, sa_mask=[], 
sa_flags=SA_RESTORER, sa_restorer=0x7f8c881fdfd0},      <unfinished ...>


I can see setting of SIGTERM handler for both 2 subshells _after_ receiving the 
signal. What exactly should I be looking at?



reply via email to

[Prev in Thread] Current Thread [Next in Thread]