Re: the test shell script never returns to shell

2023-10-26 Thread wenlin



On 10/26/2023 22:08, Chet Ramey wrote:

CAUTION: This email comes from a non Wind River email account!
Do not click links or open attachments unless you recognize the sender 
and know the content is safe.


On 10/24/23 11:14 PM, Wenlin Kang wrote:

Hi

I want to report a bug, it rarely observes the problem while running 
shell

script aborting test repeatedly.
At the problem, the test shell script never returns to shell.


Thanks for the report. I think some slight code rearranging can fix this.


Hi  Chet

Thanks for your response,  can you or someone provide the fix patch, thanks.




Chet

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
    ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    c...@case.edu http://tiswww.cwru.edu/~chet/


--
--
Thanks
Wenlin Kang




the test shell script never returns to shell

2023-10-24 Thread Wenlin Kang

Hi

I want to report a bug, it rarely observes the problem while running 
shell script aborting test repeatedly.

At the problem, the test shell script never returns to shell.

1. Version:
   bash-5.1.16(but I also checked the latest codes, I think it still 
exist the problem)


2. Steps to reproduce:
  run test.sh file and ctrl-c repeatedly

3. Analysis:
During the progress, bash register a SIGINT handler 
wait_sigint_handler() in addition to original SIGINT handler of bash.
At the registration, the original SIGINT handler saved to 
old_sigint_handler pointer.(See wait_for())


When SIGINT happens by ctrl-c, wait_sigint_handler() will be invoked 
first. the wait_sigint_handler() restores the original SIGINT handler 
from old_sigint_handler pointer as primary SIGINT handler by 
restore_signal_handler(), then send kill(SIGINT) to itself.
As a consequence, the original handler will be invoked. (See 
wait_sigint_handler())


According to the ours debugging and analysis, there is a small window in 
wait_for() which causes the problem.
If SIGINT happens during the window, the original SIGINT handler is 
never be saved to old_sigint_handler.
So, restore_sigint_handler() will do nothing. Sending kill(SIGINT) to 
itself just invokes itself(wait_sigint_handler) again.
The restore_sigint_handler() and kill(SIGINT) cycle will never be 
stopped. Therefore the shell script never return to shell.




int
wait_for (pid, flags)
 pid_t pid;
 int flags;
{
...
  /* This is possibly a race condition – should it go in stop_pipeline? */
  wait_sigint_received = child_caught_sigint = 0;
  if (job_control == 0 || (subshell_environment&SUBSHELL_COMSUB))
  {
 SigHandler *temp_sigint_handler;

 temp_sigint_handler = set_signal_handler (SIGINT, 
wait_sigint_handler);


 /* Small window begin. added by the reporter */

 if (temp_sigint_handler == wait_sigint_handler)
 {
#if defined (DEBUG)
    internal_warning ("wait_for: recursively setting 
old_sigint_handler to wait_sigint_handler: running_trap = %d", 
running_trap);

#endif
 }
 else
    /* Small window end. added by the reporter */
    old_sigint_handler = temp_sigint_handler;

 waiting_for_child = 0;
 if (old_sigint_handler == SIG_IGN)
    set_signal_handler (SIGINT, old_sigint_handler);
  }
...
}

static sighandler
wait_sigint_handler (sig)
    int sig;
{
...
  /* XXX - should this be interrupt_state? If it is, the shell will act
 as if it got the SIGINT interrupt. */
  if (waiting_for_child)
    wait_sigint_received = 1;
  else
  {
 set_exit_status (128+SIGINT);
 restore_sigint_handler();
 kill (getpid (), SIGINT);
  }
...
}

static void
restore_sigint_handler ()
{
    if (old_sigint_handler != INVALID_SIGNAL_HANDLER)
    {
   set_signal_handler (SIGINT, old_sigint_handler);
   old_sigint_handler = INVALID_SIGNAL_HANDLER;
   waiting_for_child = 0;
    }
}



4. To reproduce rapidly it, you can apply the debug patch.
diff --git a/bash-5.1.16/jobs.c b/bash-5.1.16/jobs.c
index 7c3b6e8..1b4330b 100644
--- a/bash-5.1.16/jobs.c
+++ b/bash-5.1.16/jobs.c
@@ -2941,8 +2941,10 @@ wait_for (pid, flags)
  internal_warning ("wait_for: recursively setting 
old_sigint_handler to wait_sigint_handler: running_trap = %d", 
running_trap);

 #endif
    }
-  else
+  else{
+    sleep(1); /* Add this */
    old_sigint_handler = temp_sigint_handler;
+  }
   waiting_for_child = 0;
   if (old_sigint_handler == SIG_IGN)
    set_signal_handler (SIGINT, old_sigint_handler);


5. test.sh file:

#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/local/diag; 
export PATH


max=4
for ((i=0; i < $max; i++)); do
  echo "### start $i ###"
  eval "ls -liR /usr" 2>&1
  echo "#### end of $1 "
  echo
done

--
Thanks,
Wenlin Kang




Re: the test shell script never returns to shell

2023-10-27 Thread Kang Wenlin



On 10/27/2023 20:57, Chet Ramey wrote:

CAUTION: This email comes from a non Wind River email account!
Do not click links or open attachments unless you recognize the sender 
and know the content is safe.


On 10/26/23 10:10 PM, wenlin wrote:


Hi  Chet

Thanks for your response,  can you or someone provide the fix patch, 
thanks.


It will be in the next devel branch push.



OK, thanks for you effort.




--
``The lyf so short, the craft so long to lerne.'' - Chaucer
    ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    c...@case.edu http://tiswww.cwru.edu/~chet/


--
--
Thanks
Wenlin Kang