2016-05-06 2 views
1

次のコンパイル可能なC++プログラムは、シェル/tmp/a.outから直接実行される場合、予期したとおりにシグナルをキャッチします。start-stop-daemonによって起動されたCプログラムがシグナルをキャッチできません

しかし、このプログラムはシグナルを捕まえることができず、Debianのstart-stop-daemonによって起動されると自動的に終了します。 (私の実際の生活の複数のスレッドプログラムは黙って終了しない代わりに、セグメンテーションフォールトがpthreadのlibrayから発生します。)

ファイル "/tmp/t.cpp":

#include <iostream> 
#include <signal.h> //sigaction, signal() 
#include <unistd.h> //sleep() 
#include <cstring> //memset() 
#include <cstdlib> //exit() 
static int caught_signal; 

void signal_handler(int signal_number) 
{ 
    std::cerr << "Caught signal# " << signal_number << std::endl; 
    caught_signal=signal_number; 
} 

void accept_signals() 
{ 
    struct sigaction actions; 
    memset(&actions,0,sizeof(actions)); 
    actions.sa_handler=signal_handler; 
    int result; 
    if(
     (result=sigaction(SIGTERM,&actions,NULL)) != 0 
     || (result=sigaction(SIGHUP,&actions,NULL)) != 0 
    ){ 
     std::cerr << "sigaction() failed: " << result << std::endl; 
     exit(EXIT_FAILURE); 
    } 
} 

int main(int argc,char ** argv) 
{ 
    caught_signal=-1; 
    accept_signals(); 
    while(true){ 
     if(caught_signal >= 0){ 
      switch(caught_signal){ 
       case SIGHUP:{ 
        std::cerr << "Reload" << std::endl; 
        break; 
       } 
       default:{ //SIGTERM 
        std::cerr << "Terminate" << std::endl; 
        return 0; 
       } 
      } 
     } 
     sleep(1); 
    } 
    return 0; 
} 

ファイル「を/ tmpを「/t.sh:

#!/bin/sh 
### BEGIN INIT INFO 
# Provides:   progam 
# Default-Start: 2 3 4 5 
# Default-Stop:  0 1 6 
# Short-Description: My Program 
# Description:  Test signals. 
### END INIT INFO 


PATH=/sbin:/bin:/usr/sbin:/usr/bin 
DAEMON=/tmp/a.out 
NAME=progam 
DESC="My Program" 
SCRIPTNAME=/etc/init.d/$NAME 
PIDFILE=/tmp/progam.pid 

test -x $DAEMON || exit 0 

#set -x 

. /lib/lsb/init-functions 

case "$1" in 
    start) 
     log_daemon_msg "Starting $DESC" $NAME 
     start-stop-daemon --start --oknodo --quiet --pidfile $PIDFILE --exec $DAEMON -b -m -- 
     log_end_msg $? 
     ;; 
    stop) 
     log_daemon_msg "Stopping $DESC" $NAME 
     start-stop-daemon --stop --retry TERM/10 --quiet --pidfile $PIDFILE --exec $DAEMON --remove-pidfile 
     log_end_msg $? 
     ;; 
    reload|force-reload) 
     log_daemon_msg "Reloading $DESC" $NAME 
     start-stop-daemon --stop --signal HUP --retry 10 --quiet --pidfile $PIDFILE --exec $DAEMON -b -m 
     log_end_msg $? 
     ;; 
    restart) 
     log_daemon_msg "Restarting $DESC" $NAME 
     $0 stop 
     $0 start 
     ;; 
    status) 
     status_of_proc -p "$PIDFILE" "$DAEMON" "$NAME" && exit 0 || exit $? 
     ;; 
    *) 
     echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload|status}" >&2 
     exit 1 
     ;; 
esac 

exit 0 

実行結果:

私はそれは、前述のシェルスクリプトによって起動された場合に信号が到着したとき、 クラッシュを信じる
[email protected]:/tmp$ ./t.sh start 
[ ok ] Starting My Program: progam 
[email protected]:/tmp$ ps ax|grep a.out 
8911 ?  S  0:00 /tmp/a.out 
8931 pts/4 S+  0:00 grep a.out 
[email protected]:/tmp$ ./t.sh stop 
[ ok ] Stopping My Program: progam 
[email protected]:/tmp$ ps ax|grep a.out 
8961 pts/4 S+  0:00 grep a.out 
[email protected]:/tmp$ ./a.out& 
[1] 8963 
[email protected]:/tmp$ ps ax|grep a.out 
8963 pts/4 S  0:00 ./a.out 
8967 pts/4 S+  0:00 grep a.out 
[email protected]:/tmp$ kill -TERM 8963 
[email protected]:/tmp$ Caught signal# 15 
Terminate 
ps ax|grep a.out 
8973 pts/4 S+  0:00 grep a.out 
[1]+ Done     ./a.out 
[email protected]:/tmp$ exit 

プログラムが終了なぜ、?ここに示されているよう

答えて

0

種類の魂は私を助けた:その悟りから https://lists.debian.org/debian-user/2016/05/msg00283.html

抜粋は次のとおりです。

をプログラムし、シェルスクリプトの両方が適切に自分の仕事をしています。 start-stop-daemonは、標準エラーなどを/dev/nullにリダイレクトします。その結果、C関数signal_handler()の出力は破棄されます。

関連する問題