2016-12-09 6 views
0

私はレガシープログラム(Linux上)をデバッグしています。それを別のプロセスと同期させるために、私は素直にraise(SIGSTOP)を追加しようとしました。しかし、sudoの下で実行されたとき、私は機能していない(ゾンビ)プロセスとハングターミナルを手に入れました。誰かがここで何が起きているのか、それをどう避けることができるのか説明できますか?終了時にこのプログラムがハングアップするのはなぜですか? (信号とsudoのやりとり)

私は、次のような単純なCプログラム(selfstop.c)に問題を低減しました:通常通り実行した場合には、「停止しよう」を表示し、SIGSTOPで自身を停止し

#include <signal.h> 
#include <stdio.h> 

int main(void) 
{ 
    printf("about to stop\n"); 
    (void)raise(SIGSTOP); 
    printf("resumed\n"); 
    return 0; 
} 

kill -18 <pid>は「再開」を表示し、必要に応じて終了します。それは、「再開」が表示され

sudo kill -18 <pid> 

とリターンが端末に制御しますが、私は故人となったプロセスが残っています:私は別の端末でsudoすなわち

sudo ./selfstop 

の下でそれを実行する場合は

、 :

>ps aux | grep [s]elf 
root  7619 0.0 0.0 215476 4136 pts/4 T 18:16 0:00 sudo ./selfstop 
root  7623 0.0 0.0  0  0 pts/4 Z 18:16 0:00 [selfstop] <defunct> 

プログラムがスクリプト(runse lfstop):

#!/bin/sh 
sudo ./selfstop 

ここでプロセスが終了すると、端末がハングアップします。 どちらの場合も、通常のサービスは、「7619 =須藤./selfstop」この場合には(sudoのプロセスを殺すことで再開されます。

sudo kill -9 7619 

我々はゾンビを入手できますし、どのように我々はそれを避けるなぜ私の質問がある

注:。。。sudoを使用する理由はここに無関係であることは、レガシー・アプリケーションに関連し、それが実行しているコマンドは、それ自体を中断した場合

答えて

1

sudoが自身を一時停止しますこれは、例えば、起動するsudo -sを実行することができますシェルの場合は、そのシェルにsuspendと入力して最上位のシェルに戻ります。 sudoのソースコードがある場合は、suspend_parent関数を見て、これがどのように行われているかを確認することができます。

sudo(または任意のプロセス)が中断されている場合、再開するにはSIGCONTシグナルを送信するしかありません。 SIGCONTをセルフ・ストップ・プロセスに送ることはそれをしません。

selfstopが終了したが、まだその親によってのために wait編されていないことを示し
>ps aux | grep [s]elf 
root  7619 0.0 0.0 215476 4136 pts/4 T 18:16 0:00 sudo ./selfstop 
root  7623 0.0 0.0  0  0 pts/4 Z 18:16 0:00 [selfstop] <defunct> 

。 sudoが再開されるか殺されるまで、ゾンビのままになります。

どうすれば対処できますか? sudoとselfstopは同じプロセスグループになります(selfstopが何かを変更しない限り)。だから、あなたはkill -CONT -the-pid-of-sudo(pgrpを示すためにpidの前にマイナス記号があることに注意してください)を実行することによって、両方のプロセスを再開するsudoのプロセスグループにSIGCONTを送ることができます。

+0

私が欠けていた重要なビットは、子供が止まったときに自分自身を中断するsudoでした。マニュアルページによってのみ間接的に暗示されています。 –

関連する問題