in reply to Re: Stopped child hangs parent
in thread Stopped child hangs parent

The command is arsload which is a document ingestion utility for IBM DB2 OnDemand Content Manager. I am forcing an error condition which causes this situation. When I run the same command on the command line I get a message telling the pid was stopped. When running my script I am sing top and see the parent and child threads in 'stop' state. If I do not send the SIGCONT signal nothing happens. The processes remain in the 'stop' state. If I send the signal just to the child, the parent remains stopped. I have to signal the parent as well.

As for the parent, the while loop at the end of the script should output every 5 seconds to show it is waiting. Nothing is output even if I signal the child to continue which ends the child.

I tried SIG{STOP} = sub {print STDERR "$$ stopped\n";}; in the child and nothing was output. I then tried it in the parent and nothing was output.

Maybe I am being mislead by the stop state thinking it is the stop signal? For debug purposes only, I have been toying with the idea of putting in a signal handler for almost every signal.

Replies are listed 'Best First'.
Re^3: Stopped child hangs parent
by ig (Vicar) on Aug 10, 2009 at 20:49 UTC

    When the error condition occurs I expect you will have three processes: a parent perl process, a child perl process and an arsload process. Are all three stopped?

    SIGSTOP can't be caught or ignored but SIGTSTP, SIGTTIN and SIGTTOU can. All four signals stop a process by default. The latter two are usually generated only for processes running in the background. Are you running your program in the background?

    You could initiate a separate process group in your child process: see Complete Dissociation of Child from Parent. If you do this then any signals sent from the arsload process to all processes in the process group should not affect the parent process.

    Your parent process should receive a SIGCHLD when its child is stopped. If it is not stopped itself then it can send a SIGCONT.

      Yes you are correct. The arsload process is also stopped. I was concentrating on the Perl processes so intently I completely missed the arsload process.

      When I am testing I am running in the background. When run for real it will run from cron. I was not at a point where I was ready to test it for real yet but based on your question I ran it in the foreground. Everything worked perfectly.

      I will look into daemonize'ing the child process as well. Unless there is something else anyone can think of I may be doing wrong, I believe I am good as long as I do not test in the background.

      Thank you for everything.

        Unless there is something else anyone can think of...

        If the issue is that the terminal is sending SIGTTOU stopping the process when it's trying to write to the terminal from the background (as indicated by ig), you could try  stty -tostop to disable that behavior (most terminals allow it to be controlled):

        $ stty tostop $ echo foo & [1] 7746 [1]+ Stopped echo foo $ stty -tostop $ echo foo & foo [2] 7748 [2]- Done echo foo

        As you can see, in the first case, the background process is being stopped (via SIGTTOU), while in the latter case, the process is allowed to output "foo" (as if being run in the foreground), and the process can terminate normally.

        The most likely cause of the stop is that arsload is trying to read or write the terminal and, while being run in the background, is receiving SIGTTIN or SIGTTOU. You have redirected STDERR to a log file. You should do the same for STDOUT and open STDIN from /dev/null. Then you will probably be able to run in the background.

        Rather than doing this in your script, you can do it from the command line:

        ./script.pl >/tmp/script.log </dev/null &