T
Timothy Madden
Hello
I am trying to write a daemon and I call os.fork() twice to detach from
the terminal and other staff.
Problem is after the second fork() the child immediately gives an
exception and although I get a traceback displayed the process should
terminate, the child proces is still live, and its parent is waiting in
a loop for the child to either exit or send SIGUSR1 to it to indicate
the daemon has started up and is in the running state.
The problem is the daemon script has terminated with an uncaught
exception and a traceback displayed, but the process is still hanging
there. Do you know why would it not exit ?
Trying to kill the daemon process, even as root, fails silently. Do you
know why that would happen ?
I would like to debug the scrip with
python -m pdb pikantBlue.py
but after the first fork() call the debugger prompt is unusuable.
Probably the same prompt is shared by two instances of pdb, that have
forked once with my script. Do you know how can I debug a script that
forks ?
You have my script attached if you want to look it over. The child
failes and somehow freezes at the import line at the end of the file,
and its parent is livelocked in the while loop.
Thank you,
Timothy Madden
---
#!/usr/bin/env python
import sys, os, signal, time
from pikantBlueServer import PIDFile as PIDFile, pid_file as pid_file
serverRunning = False
def serverRunningSignal(usrSignal, stackFrame):
global serverRunning
if (usrSignal == signal.SIGUSR1):
serverRunning = True
wait_message = False
def waitAlarm(sigAlarm, stackFrame):
global wait_message
sys.stdout.write('Starting daemon ... ')
wait_message = True
def daemonize(loop, fileLst):
exitCode = False
sys.stdin.flush()
sys.stdout.flush()
sys.stderr.flush()
pid = os.fork()
if pid > 0:
# the main process
#
# returns with the exit code of the proxy child
print 'Proxy proces' , pid
exitCode = (os.waitpid(pid,0) == 0)
else:
# the proxy child
#
# sets cwd, umask and sid, forks the server
# waits for either it's termination or the ready signal
os.setsid()
signal.signal(signal.SIGUSR1, serverRunningSignal)
sys.stdin.flush()
sys.stdout.flush()
sys.stderr.flush()
pid = os.fork()
if pid > 0:
#proxy process waits for termination of the child or the
#ready signal
print 'Daemon process', pid
signal.signal(signal.SIGALRM, waitAlarm)
signal.alarm(1)
waitPid = True
global serverRunning
if not serverRunning:
try:
os.kill(pid, 0)
except OSError, e:
if hasattr(e, 'errno') and e.errno == errno.ESRCH:
waitPid = False
else:
raise
while waitPid and not serverRunning:
time.sleep(10)
if not serverRunning:
try:
sys.stdout.write('Checking child process ' + str(pid) + ' ... ')
os.kill(pid, 0)
print 'live.'
except OSError, e:
if hasattr(e, 'errno') and e.errno == errno.ESRCH:
waitPid = False
print 'dead'
else:
raise
signal.alarm(0)
global wait_message
if waitPid and wait_message:
print 'done'
exitCode = serverRunning
else:
# the server process
#
signal.signal(signal.SIGUSR1, signal.SIG_DFL)
os.chdir('/')
os.umask(0)
try:
import pikantBlueSever
exitCode = pikantBlueServer.start(loop, fileLst)
except:
exitCode = False
return exitCode
I am trying to write a daemon and I call os.fork() twice to detach from
the terminal and other staff.
Problem is after the second fork() the child immediately gives an
exception and although I get a traceback displayed the process should
terminate, the child proces is still live, and its parent is waiting in
a loop for the child to either exit or send SIGUSR1 to it to indicate
the daemon has started up and is in the running state.
The problem is the daemon script has terminated with an uncaught
exception and a traceback displayed, but the process is still hanging
there. Do you know why would it not exit ?
Trying to kill the daemon process, even as root, fails silently. Do you
know why that would happen ?
I would like to debug the scrip with
python -m pdb pikantBlue.py
but after the first fork() call the debugger prompt is unusuable.
Probably the same prompt is shared by two instances of pdb, that have
forked once with my script. Do you know how can I debug a script that
forks ?
You have my script attached if you want to look it over. The child
failes and somehow freezes at the import line at the end of the file,
and its parent is livelocked in the while loop.
Thank you,
Timothy Madden
---
#!/usr/bin/env python
import sys, os, signal, time
from pikantBlueServer import PIDFile as PIDFile, pid_file as pid_file
serverRunning = False
def serverRunningSignal(usrSignal, stackFrame):
global serverRunning
if (usrSignal == signal.SIGUSR1):
serverRunning = True
wait_message = False
def waitAlarm(sigAlarm, stackFrame):
global wait_message
sys.stdout.write('Starting daemon ... ')
wait_message = True
def daemonize(loop, fileLst):
exitCode = False
sys.stdin.flush()
sys.stdout.flush()
sys.stderr.flush()
pid = os.fork()
if pid > 0:
# the main process
#
# returns with the exit code of the proxy child
print 'Proxy proces' , pid
exitCode = (os.waitpid(pid,0) == 0)
else:
# the proxy child
#
# sets cwd, umask and sid, forks the server
# waits for either it's termination or the ready signal
os.setsid()
signal.signal(signal.SIGUSR1, serverRunningSignal)
sys.stdin.flush()
sys.stdout.flush()
sys.stderr.flush()
pid = os.fork()
if pid > 0:
#proxy process waits for termination of the child or the
#ready signal
print 'Daemon process', pid
signal.signal(signal.SIGALRM, waitAlarm)
signal.alarm(1)
waitPid = True
global serverRunning
if not serverRunning:
try:
os.kill(pid, 0)
except OSError, e:
if hasattr(e, 'errno') and e.errno == errno.ESRCH:
waitPid = False
else:
raise
while waitPid and not serverRunning:
time.sleep(10)
if not serverRunning:
try:
sys.stdout.write('Checking child process ' + str(pid) + ' ... ')
os.kill(pid, 0)
print 'live.'
except OSError, e:
if hasattr(e, 'errno') and e.errno == errno.ESRCH:
waitPid = False
print 'dead'
else:
raise
signal.alarm(0)
global wait_message
if waitPid and wait_message:
print 'done'
exitCode = serverRunning
else:
# the server process
#
signal.signal(signal.SIGUSR1, signal.SIG_DFL)
os.chdir('/')
os.umask(0)
try:
import pikantBlueSever
exitCode = pikantBlueServer.start(loop, fileLst)
except:
exitCode = False
return exitCode