start-stop-daemon启动的C程序无法捕获信号

时间:2016-05-06 15:45:14

标签: c++ debian signals

以下可编译的C ++程序如果直接从shell /tmp/a.out运行,则会按预期捕获信号。

然而,如果被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

运行结果:

john@host:/tmp$ ./t.sh start
[ ok ] Starting My Program: progam
john@host:/tmp$ ps ax|grep a.out
 8911 ?        S      0:00 /tmp/a.out
 8931 pts/4    S+     0:00 grep a.out
john@host:/tmp$ ./t.sh stop
[ ok ] Stopping My Program: progam
john@host:/tmp$ ps ax|grep a.out
 8961 pts/4    S+     0:00 grep a.out
john@host:/tmp$ ./a.out&
[1] 8963
john@host:/tmp$ ps ax|grep a.out
 8963 pts/4    S      0:00 ./a.out
 8967 pts/4    S+     0:00 grep a.out
john@host:/tmp$ kill -TERM 8963
john@host:/tmp$ Caught signal# 15
Terminate
ps ax|grep a.out
 8973 pts/4    S+     0:00 grep a.out
[1]+  Done                    ./a.out
john@host:/tmp$ exit

为什么程序终止,我相信崩溃,当信号到达时,如果它是由前面提到的shell脚本启动的?

1 个答案:

答案 0 :(得分:0)

善良的灵魂帮助了我,如下所示: https://lists.debian.org/debian-user/2016/05/msg00283.html

摘录摘录如下:

程序和shell脚本都正常地完成了他们的工作。 start-stop-daemon将标准错误等重定向到/dev/null。结果,C函数signal_handler()的输出被丢弃。