How to debug a forked process with pdb ?

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top