|
From: Marcin Krol on 2 Jul 2008 12:08 Hello everyone, And now for something completely different: signal handling sometimes works, sometimes it doesn't. When I embed following code, it works: count = 0 def test(): global count while True: count += 1 if (count % 100000 == 0): print count if __name__ == "__main__": test() It nicely does what signal handler function tells it to do and exits. However, when I embed this code, it segfaults on receiving the signal: import time def test(): time.sleep(1) print "success" time.sleep(90) if __name__ == "__main__": test() Does it have something to do with the fact that the program receiving the signal sleeps? The C code of segfaulting program: #include <Python.h> #include <stdio.h> #include <stdlib.h> #include <syslog.h> #include <unistd.h> #include <signal.h> void userbreak(int sig) { Py_Finalize(); printf("Interrupted..\n"); exit(sig); } void terminaterun(int sig) { Py_Finalize(); printf("Received SIGTERM. Terminating.\n"); exit(sig); } int main(int argc, char **argv) { Py_Initialize(); PyObject *pyCode, *mainmodule, *maindict; mainmodule = PyImport_AddModule("__main__"); maindict = PyModule_GetDict(mainmodule); unsigned int size = 326; unsigned char python_code[] = { 0x63,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00, 0x40,0x00,0x00,0x00,0x73,0x2E,0x00,0x00,0x00,0x64, 0x00,0x00,0x6B,0x00,0x00,0x5A,0x00,0x00,0x64,0x01, 0x00,0x84,0x00,0x00,0x5A,0x01,0x00,0x65,0x02,0x00, 0x64,0x02,0x00,0x6A,0x02,0x00,0x6F,0x0B,0x00,0x01, 0x65,0x01,0x00,0x83,0x00,0x00,0x01,0x6E,0x01,0x00, 0x01,0x64,0x00,0x00,0x53,0x28,0x03,0x00,0x00,0x00, 0x4E,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x02,0x00,0x00,0x00,0x43,0x00,0x00,0x00,0x73,0x23, 0x00,0x00,0x00,0x74,0x00,0x00,0x69,0x01,0x00,0x64, 0x01,0x00,0x83,0x01,0x00,0x01,0x64,0x02,0x00,0x47, 0x48,0x74,0x00,0x00,0x69,0x01,0x00,0x64,0x03,0x00, 0x83,0x01,0x00,0x01,0x64,0x00,0x00,0x53,0x28,0x04, 0x00,0x00,0x00,0x4E,0x69,0x01,0x00,0x00,0x00,0x74, 0x07,0x00,0x00,0x00,0x73,0x75,0x63,0x63,0x65,0x73, 0x73,0x69,0x5A,0x00,0x00,0x00,0x28,0x02,0x00,0x00, 0x00,0x74,0x04,0x00,0x00,0x00,0x74,0x69,0x6D,0x65, 0x74,0x05,0x00,0x00,0x00,0x73,0x6C,0x65,0x65,0x70, 0x28,0x00,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00, 0x28,0x00,0x00,0x00,0x00,0x74,0x07,0x00,0x00,0x00, 0x74,0x65,0x73,0x74,0x2E,0x70,0x79,0x74,0x04,0x00, 0x00,0x00,0x74,0x65,0x73,0x74,0x05,0x00,0x00,0x00, 0x73,0x06,0x00,0x00,0x00,0x00,0x01,0x0D,0x01,0x05, 0x01,0x74,0x08,0x00,0x00,0x00,0x5F,0x5F,0x6D,0x61, 0x69,0x6E,0x5F,0x5F,0x28,0x03,0x00,0x00,0x00,0x52, 0x01,0x00,0x00,0x00,0x52,0x04,0x00,0x00,0x00,0x74, 0x08,0x00,0x00,0x00,0x5F,0x5F,0x6E,0x61,0x6D,0x65, 0x5F,0x5F,0x28,0x02,0x00,0x00,0x00,0x52,0x04,0x00, 0x00,0x00,0x52,0x01,0x00,0x00,0x00,0x28,0x00,0x00, 0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x52,0x03,0x00, 0x00,0x00,0x74,0x01,0x00,0x00,0x00,0x3F,0x03,0x00, 0x00,0x00,0x73,0x06,0x00,0x00,0x00,0x09,0x02,0x09, 0x05,0x0D,0x01 }; pyCode = PyMarshal_ReadObjectFromString((PyObject *) python_code, size); (void) signal(SIGINT, userbreak); (void) signal(SIGTERM, terminaterun); PyEval_EvalCode(pyCode, maindict, maindict); Py_Finalize(); }
From: Marcin Krol on 2 Jul 2008 12:46 Right, I didn't realize before that Python interpreter has its own signal handling routines. Now I am able to handle signals in Python code, but it still barfs on exit: import time import signal import sys def userBreak(sigNum, execFrame): print "Interrupted,,," sys.exit(sigNum) def terminateRun(sigNum, execFrame): print "SIGTERM received, terminating." sys.exit(sigNum) def test(): time.sleep(1) print "success" time.sleep(90) if __name__ == "__main__": signal.signal(signal.SIGTERM, terminateRun) signal.signal(signal.SIGINT, userBreak) test() The error: ../test success ( pressing Ctrl-C ) Interrupted,,, Exception exceptions.SystemExit: 2 in 'garbage collection' ignored Fatal Python error: unexpected exception during garbage collection Aborted So the real question is - how to exit cleanly from embedded Python code?
|
Pages: 1 Prev: Importing modules in embedded Python Next: Most efficient way to get pixelcolors of an image? |