Re: [solved] C program launched by start-stop-daemon fails to catch signals

2016-05-07 Thread CN
On Sat, May 7, 2016, at 02:43 PM, Christian Seiler wrote:
> 
> No, it does catch the signal without a problem. But start-stop-daemon
> closes the standard filedescriptors and replaces them with /dev/null.
> 
> Try it:
> 
> /tmp/t.sh start
> ps ax | grep a.out
> lsof -p $PID
> -> look for FD = 0u, 1u and 2u, those are all /dev/null
> 
> That means that the error output is dropped, because it goes to
> /dev/null.
> 
> If you alter your test code to include #include  and replace
> the following function:
> 
> void signal_handler(int signal_number)
> {
> std::ofstream error_out("/tmp/daemon-error.out");
> error_out << "Caught signal# " << signal_number << std::endl;
> caught_signal=signal_number;
> }
> 
> Then you will see that /tmp/daemon-error.out is generated and that
> there is the text "Caught signal#15" inside, if you terminate the
> daemon via the init script.
> 

Dear Christian,

You have saved me from resorting to debuggers after days' fruitless
digging.
Big thanks to your kind enlightenment!

Best regards,
CN

-- 
http://www.fastmail.com - Does exactly what it says on the tin



Re: C program launched by start-stop-daemon fails to catch signals

2016-05-07 Thread Christian Seiler
On 05/07/2016 06:39 AM, CN wrote:
> The following compilable C++ program catches signals as expected if it
> runs directly from shell /tmp/a.out.
> 
> However, this program fails to catch any signal and silently terminates
> if it is fired by Debian's start-stop-daemon.

No, it does catch the signal without a problem. But start-stop-daemon
closes the standard filedescriptors and replaces them with /dev/null.

Try it:

/tmp/t.sh start
ps ax | grep a.out
lsof -p $PID
-> look for FD = 0u, 1u and 2u, those are all /dev/null

That means that the error output is dropped, because it goes to
/dev/null.

If you alter your test code to include #include  and replace
the following function:

void signal_handler(int signal_number)
{
std::ofstream error_out("/tmp/daemon-error.out");
error_out << "Caught signal# " << signal_number << std::endl;
caught_signal=signal_number;
}

Then you will see that /tmp/daemon-error.out is generated and that
there is the text "Caught signal#15" inside, if you terminate the
daemon via the init script.

> (My real life multiple
> threaded program does not silently terminates. Instead, segmentation
> fault occurs from pthread libray.)

Well, then your problem is likely to be a bit more complicated. :(

Regards,
Christian



signature.asc
Description: OpenPGP digital signature


C program launched by start-stop-daemon fails to catch signals

2016-05-06 Thread CN
The following compilable C++ program catches signals as expected if it
runs directly from shell /tmp/a.out.

However, this program fails to catch any signal and silently terminates
if it is fired by Debian's start-stop-daemon. (My real life multiple
threaded program does not silently terminates. Instead, segmentation
fault occurs from pthread libray.)

---
(
Better code formatted message can be found here:
http://stackoverflow.com/questions/37076470/c-program-launched-by-start-stop-daemon-fails-to-catch-signals
)

File "/tmp/t.cpp":

#include 
#include  //sigaction, signal()
#include  //sleep()
#include  //memset()
#include  //exit()
static int caught_signal=-1;

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(,0,sizeof(actions));
actions.sa_handler=signal_handler;
int result;
if(
(result=sigaction(SIGTERM,,NULL)) != 0
|| (result=sigaction(SIGHUP,,NULL)) != 0
){
std::cerr << "sigaction() failed: " << result << std::endl;
exit(EXIT_FAILURE);
}
}

int main(int argc,char ** argv)
{
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;
}

---

File "/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
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

---

Running results:

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/4S+ 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/4S+ 0:00 grep a.out
john@host:/tmp$ ./a.out&
[1] 8963
john@host:/tmp$ ps ax|grep a.out
 8963 pts/4S  0:00 ./a.out
 8967 pts/4S+ 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/4S+ 0:00 grep a.out
[1]+  Done./a.out
john@host:/tmp$ exit

---

Why the program terminates, which I believe crashes, when signals arrive
if it is launched by the aforementioned shell script?

-- 
http://www.fastmail.com - Email service worth paying for. Try it for free