Why script that kill itself using a signal handler produce segmentation fault?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
0
down vote

favorite












SCRIPT GOAL: the script is invoked as ./script.sh cmd1 cmd2 ... cmdn. It should executes in background all the commands passed as arguments from the command line and check when all of them have finished their execution.
Furthermore if the SIGTERM signal is send to the script it should kill all the aforemoentioned processes (cmd1 ... cmdn) and then kill himself.



PROBLEM: All seem working except the autotermination and I can't figure out why.
I tried to use kill $$ but at runtime I get segmentation fault.
I was thinking that the problem was related to the fact that kill command is inside a function but on the other hand if I comment kill $$ and I leave kill $PIDAR[*] command, the latter work.
Could somebody explain me what I am missing?



#!/bin/bash 

# signal handler
killemall ()
echo $$
kill $PIDAR[*]
kill $$ # implicated line


PIDAR=() # pid array
STAR=() # process state array

# execute processes in bg and save their pid
for i in "$@" ; do
$i &
PIDAR+=($!)
done

trap 'killemall' SIGTERM

terminated=1 # flag to indicate when all processes are terminated
while sleep 1 && [ $terminated -eq 1 ]; do
for (( i=0; i<$#PIDAR[*]; i++ )); do
STAR[$i]=$(ps hp $PIDAR[$i] | awk ' print $3 ')
if [ -z $STAR[$i] ]; then
terminated=0
else terminated=1
fi
echo "Process state $PIDAR[$i]:$STAR[$i]" | tee -a logg
done
done

echo "All processes are terminated"


Thanks



SOLUTION: as user18197 pointed out, the problem is calling kill $$.
Indeed as the kill man page reports:




The default signal for kill is TERM




Then at each kill $$ invocation the script was calling the handler killemall which in turn was invoking again kill $$ and so on recursively.
To avoid this behaviour we can untrap SIGTERM signal. As help trap reports:




If ARG is absent (and a single SIGNAL_SPEC
is supplied) or `-', each specified signal is reset to its original
value.




So the new function body is:



killemall () 
echo $$
trap - SIGTERM
kill $PIDAR[@]
kill $$







share|improve this question

























    up vote
    0
    down vote

    favorite












    SCRIPT GOAL: the script is invoked as ./script.sh cmd1 cmd2 ... cmdn. It should executes in background all the commands passed as arguments from the command line and check when all of them have finished their execution.
    Furthermore if the SIGTERM signal is send to the script it should kill all the aforemoentioned processes (cmd1 ... cmdn) and then kill himself.



    PROBLEM: All seem working except the autotermination and I can't figure out why.
    I tried to use kill $$ but at runtime I get segmentation fault.
    I was thinking that the problem was related to the fact that kill command is inside a function but on the other hand if I comment kill $$ and I leave kill $PIDAR[*] command, the latter work.
    Could somebody explain me what I am missing?



    #!/bin/bash 

    # signal handler
    killemall ()
    echo $$
    kill $PIDAR[*]
    kill $$ # implicated line


    PIDAR=() # pid array
    STAR=() # process state array

    # execute processes in bg and save their pid
    for i in "$@" ; do
    $i &
    PIDAR+=($!)
    done

    trap 'killemall' SIGTERM

    terminated=1 # flag to indicate when all processes are terminated
    while sleep 1 && [ $terminated -eq 1 ]; do
    for (( i=0; i<$#PIDAR[*]; i++ )); do
    STAR[$i]=$(ps hp $PIDAR[$i] | awk ' print $3 ')
    if [ -z $STAR[$i] ]; then
    terminated=0
    else terminated=1
    fi
    echo "Process state $PIDAR[$i]:$STAR[$i]" | tee -a logg
    done
    done

    echo "All processes are terminated"


    Thanks



    SOLUTION: as user18197 pointed out, the problem is calling kill $$.
    Indeed as the kill man page reports:




    The default signal for kill is TERM




    Then at each kill $$ invocation the script was calling the handler killemall which in turn was invoking again kill $$ and so on recursively.
    To avoid this behaviour we can untrap SIGTERM signal. As help trap reports:




    If ARG is absent (and a single SIGNAL_SPEC
    is supplied) or `-', each specified signal is reset to its original
    value.




    So the new function body is:



    killemall () 
    echo $$
    trap - SIGTERM
    kill $PIDAR[@]
    kill $$







    share|improve this question























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      SCRIPT GOAL: the script is invoked as ./script.sh cmd1 cmd2 ... cmdn. It should executes in background all the commands passed as arguments from the command line and check when all of them have finished their execution.
      Furthermore if the SIGTERM signal is send to the script it should kill all the aforemoentioned processes (cmd1 ... cmdn) and then kill himself.



      PROBLEM: All seem working except the autotermination and I can't figure out why.
      I tried to use kill $$ but at runtime I get segmentation fault.
      I was thinking that the problem was related to the fact that kill command is inside a function but on the other hand if I comment kill $$ and I leave kill $PIDAR[*] command, the latter work.
      Could somebody explain me what I am missing?



      #!/bin/bash 

      # signal handler
      killemall ()
      echo $$
      kill $PIDAR[*]
      kill $$ # implicated line


      PIDAR=() # pid array
      STAR=() # process state array

      # execute processes in bg and save their pid
      for i in "$@" ; do
      $i &
      PIDAR+=($!)
      done

      trap 'killemall' SIGTERM

      terminated=1 # flag to indicate when all processes are terminated
      while sleep 1 && [ $terminated -eq 1 ]; do
      for (( i=0; i<$#PIDAR[*]; i++ )); do
      STAR[$i]=$(ps hp $PIDAR[$i] | awk ' print $3 ')
      if [ -z $STAR[$i] ]; then
      terminated=0
      else terminated=1
      fi
      echo "Process state $PIDAR[$i]:$STAR[$i]" | tee -a logg
      done
      done

      echo "All processes are terminated"


      Thanks



      SOLUTION: as user18197 pointed out, the problem is calling kill $$.
      Indeed as the kill man page reports:




      The default signal for kill is TERM




      Then at each kill $$ invocation the script was calling the handler killemall which in turn was invoking again kill $$ and so on recursively.
      To avoid this behaviour we can untrap SIGTERM signal. As help trap reports:




      If ARG is absent (and a single SIGNAL_SPEC
      is supplied) or `-', each specified signal is reset to its original
      value.




      So the new function body is:



      killemall () 
      echo $$
      trap - SIGTERM
      kill $PIDAR[@]
      kill $$







      share|improve this question













      SCRIPT GOAL: the script is invoked as ./script.sh cmd1 cmd2 ... cmdn. It should executes in background all the commands passed as arguments from the command line and check when all of them have finished their execution.
      Furthermore if the SIGTERM signal is send to the script it should kill all the aforemoentioned processes (cmd1 ... cmdn) and then kill himself.



      PROBLEM: All seem working except the autotermination and I can't figure out why.
      I tried to use kill $$ but at runtime I get segmentation fault.
      I was thinking that the problem was related to the fact that kill command is inside a function but on the other hand if I comment kill $$ and I leave kill $PIDAR[*] command, the latter work.
      Could somebody explain me what I am missing?



      #!/bin/bash 

      # signal handler
      killemall ()
      echo $$
      kill $PIDAR[*]
      kill $$ # implicated line


      PIDAR=() # pid array
      STAR=() # process state array

      # execute processes in bg and save their pid
      for i in "$@" ; do
      $i &
      PIDAR+=($!)
      done

      trap 'killemall' SIGTERM

      terminated=1 # flag to indicate when all processes are terminated
      while sleep 1 && [ $terminated -eq 1 ]; do
      for (( i=0; i<$#PIDAR[*]; i++ )); do
      STAR[$i]=$(ps hp $PIDAR[$i] | awk ' print $3 ')
      if [ -z $STAR[$i] ]; then
      terminated=0
      else terminated=1
      fi
      echo "Process state $PIDAR[$i]:$STAR[$i]" | tee -a logg
      done
      done

      echo "All processes are terminated"


      Thanks



      SOLUTION: as user18197 pointed out, the problem is calling kill $$.
      Indeed as the kill man page reports:




      The default signal for kill is TERM




      Then at each kill $$ invocation the script was calling the handler killemall which in turn was invoking again kill $$ and so on recursively.
      To avoid this behaviour we can untrap SIGTERM signal. As help trap reports:




      If ARG is absent (and a single SIGNAL_SPEC
      is supplied) or `-', each specified signal is reset to its original
      value.




      So the new function body is:



      killemall () 
      echo $$
      trap - SIGTERM
      kill $PIDAR[@]
      kill $$









      share|improve this question












      share|improve this question




      share|improve this question








      edited Apr 27 at 11:16
























      asked Apr 27 at 10:06









      ikeDiM

      524




      524




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          3
          down vote



          accepted










          I couldn't reproduce the seg fault, but I am guessing that sending SIGTERM to yourself will reinvoke the killemall function, which will send SIGTERM, which will invoke the killemall ...



          You actually do not need to do anything to terminate your script. The function killemall is called and when it is done the script will exit. You can add an exit 0 at the end of the function to make it more clear if you want.






          share|improve this answer





















          • A program that handles sigint and then dies is usually expected to kill itself by sigint, see for example: gnu.org/software/libc/manual/html_node/…
            – muru
            Apr 27 at 10:34










          • AFAIK, that part is handled by the shell, bash in this case.
            – user18197
            Apr 27 at 10:40










          • @user18197 not if you simply exit 0 in the trap handler.
            – muru
            Apr 27 at 10:44






          • 1




            @ikeDiM removing the trap handler using trap "" SIGINT and then kill the script.
            – muru
            Apr 27 at 10:59






          • 1




            @ikeDiM oh, sorry, I for some reason during the entire conversation I kept saying sigint instead of sigterm. What I mean it is something like: killemall () trap '' SIGTERM; kill $PIDAR[@]; kill $$;
            – muru
            Apr 27 at 11:09










          Your Answer







          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "106"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f440382%2fwhy-script-that-kill-itself-using-a-signal-handler-produce-segmentation-fault%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          3
          down vote



          accepted










          I couldn't reproduce the seg fault, but I am guessing that sending SIGTERM to yourself will reinvoke the killemall function, which will send SIGTERM, which will invoke the killemall ...



          You actually do not need to do anything to terminate your script. The function killemall is called and when it is done the script will exit. You can add an exit 0 at the end of the function to make it more clear if you want.






          share|improve this answer





















          • A program that handles sigint and then dies is usually expected to kill itself by sigint, see for example: gnu.org/software/libc/manual/html_node/…
            – muru
            Apr 27 at 10:34










          • AFAIK, that part is handled by the shell, bash in this case.
            – user18197
            Apr 27 at 10:40










          • @user18197 not if you simply exit 0 in the trap handler.
            – muru
            Apr 27 at 10:44






          • 1




            @ikeDiM removing the trap handler using trap "" SIGINT and then kill the script.
            – muru
            Apr 27 at 10:59






          • 1




            @ikeDiM oh, sorry, I for some reason during the entire conversation I kept saying sigint instead of sigterm. What I mean it is something like: killemall () trap '' SIGTERM; kill $PIDAR[@]; kill $$;
            – muru
            Apr 27 at 11:09














          up vote
          3
          down vote



          accepted










          I couldn't reproduce the seg fault, but I am guessing that sending SIGTERM to yourself will reinvoke the killemall function, which will send SIGTERM, which will invoke the killemall ...



          You actually do not need to do anything to terminate your script. The function killemall is called and when it is done the script will exit. You can add an exit 0 at the end of the function to make it more clear if you want.






          share|improve this answer





















          • A program that handles sigint and then dies is usually expected to kill itself by sigint, see for example: gnu.org/software/libc/manual/html_node/…
            – muru
            Apr 27 at 10:34










          • AFAIK, that part is handled by the shell, bash in this case.
            – user18197
            Apr 27 at 10:40










          • @user18197 not if you simply exit 0 in the trap handler.
            – muru
            Apr 27 at 10:44






          • 1




            @ikeDiM removing the trap handler using trap "" SIGINT and then kill the script.
            – muru
            Apr 27 at 10:59






          • 1




            @ikeDiM oh, sorry, I for some reason during the entire conversation I kept saying sigint instead of sigterm. What I mean it is something like: killemall () trap '' SIGTERM; kill $PIDAR[@]; kill $$;
            – muru
            Apr 27 at 11:09












          up vote
          3
          down vote



          accepted







          up vote
          3
          down vote



          accepted






          I couldn't reproduce the seg fault, but I am guessing that sending SIGTERM to yourself will reinvoke the killemall function, which will send SIGTERM, which will invoke the killemall ...



          You actually do not need to do anything to terminate your script. The function killemall is called and when it is done the script will exit. You can add an exit 0 at the end of the function to make it more clear if you want.






          share|improve this answer













          I couldn't reproduce the seg fault, but I am guessing that sending SIGTERM to yourself will reinvoke the killemall function, which will send SIGTERM, which will invoke the killemall ...



          You actually do not need to do anything to terminate your script. The function killemall is called and when it is done the script will exit. You can add an exit 0 at the end of the function to make it more clear if you want.







          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered Apr 27 at 10:22









          user18197

          461




          461











          • A program that handles sigint and then dies is usually expected to kill itself by sigint, see for example: gnu.org/software/libc/manual/html_node/…
            – muru
            Apr 27 at 10:34










          • AFAIK, that part is handled by the shell, bash in this case.
            – user18197
            Apr 27 at 10:40










          • @user18197 not if you simply exit 0 in the trap handler.
            – muru
            Apr 27 at 10:44






          • 1




            @ikeDiM removing the trap handler using trap "" SIGINT and then kill the script.
            – muru
            Apr 27 at 10:59






          • 1




            @ikeDiM oh, sorry, I for some reason during the entire conversation I kept saying sigint instead of sigterm. What I mean it is something like: killemall () trap '' SIGTERM; kill $PIDAR[@]; kill $$;
            – muru
            Apr 27 at 11:09
















          • A program that handles sigint and then dies is usually expected to kill itself by sigint, see for example: gnu.org/software/libc/manual/html_node/…
            – muru
            Apr 27 at 10:34










          • AFAIK, that part is handled by the shell, bash in this case.
            – user18197
            Apr 27 at 10:40










          • @user18197 not if you simply exit 0 in the trap handler.
            – muru
            Apr 27 at 10:44






          • 1




            @ikeDiM removing the trap handler using trap "" SIGINT and then kill the script.
            – muru
            Apr 27 at 10:59






          • 1




            @ikeDiM oh, sorry, I for some reason during the entire conversation I kept saying sigint instead of sigterm. What I mean it is something like: killemall () trap '' SIGTERM; kill $PIDAR[@]; kill $$;
            – muru
            Apr 27 at 11:09















          A program that handles sigint and then dies is usually expected to kill itself by sigint, see for example: gnu.org/software/libc/manual/html_node/…
          – muru
          Apr 27 at 10:34




          A program that handles sigint and then dies is usually expected to kill itself by sigint, see for example: gnu.org/software/libc/manual/html_node/…
          – muru
          Apr 27 at 10:34












          AFAIK, that part is handled by the shell, bash in this case.
          – user18197
          Apr 27 at 10:40




          AFAIK, that part is handled by the shell, bash in this case.
          – user18197
          Apr 27 at 10:40












          @user18197 not if you simply exit 0 in the trap handler.
          – muru
          Apr 27 at 10:44




          @user18197 not if you simply exit 0 in the trap handler.
          – muru
          Apr 27 at 10:44




          1




          1




          @ikeDiM removing the trap handler using trap "" SIGINT and then kill the script.
          – muru
          Apr 27 at 10:59




          @ikeDiM removing the trap handler using trap "" SIGINT and then kill the script.
          – muru
          Apr 27 at 10:59




          1




          1




          @ikeDiM oh, sorry, I for some reason during the entire conversation I kept saying sigint instead of sigterm. What I mean it is something like: killemall () trap '' SIGTERM; kill $PIDAR[@]; kill $$;
          – muru
          Apr 27 at 11:09




          @ikeDiM oh, sorry, I for some reason during the entire conversation I kept saying sigint instead of sigterm. What I mean it is something like: killemall () trap '' SIGTERM; kill $PIDAR[@]; kill $$;
          – muru
          Apr 27 at 11:09












           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f440382%2fwhy-script-that-kill-itself-using-a-signal-handler-produce-segmentation-fault%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          How to check contact read email or not when send email to Individual?

          Bahrain

          Postfix configuration issue with fips on centos 7; mailgun relay