Python builtin signal handler not working consistently when dealing with signal related to segmentation fault. By using kill command to send SIGSEGV to the process, it works correctly. But when an illegal memory access inside the process happens, which is also a SIGSEGV signal, cannot be handled by the custom signal handler.
import ctypes
import os
import signal
import time
if __name__ == '__main__':
def receiveSignal(signalNumber, frame):
print('Received:', signalNumber)
return
print('My PID is:', os.getpid())
# register the signals to be caught
signal.signal(signal.SIGSEGV, receiveSignal)
# raise a segmentation fault internally
ctypes.string_at(0)
# wait in an endless loop for signals
while True:
print('Waiting...')
time.sleep(3)
I expect the segmentation fault(SIGSEGV) raised by ctypes.string_at(0) is caught by the signal handler, but it didn't, and the process stops responding to ctrl+c, kill -2 PID and kill -11 PID.
However, I comment the ctypes.string_at(0) line, and send SIGSEGV with kill -11 PID, the signal is handled by my handler as expected. Besides, I don't understand that although the process doesn't respond, it keeps a 100% CPU usage.
What is the difference between these two cases?
Python can’t be executed in actual signal handlers (because there are very few actions they can take), so the underlying signal handler always returns. That’s fine for asynchronous signals and “optional errors” like SIGPIPE, but for an actual program fault it’s meaningless because there is no valid execution to resume. On some platforms, returning in such a situation just causes the same signal to be raised again, and an infinite loop results (without ever reaching the code that executes the Python-level handler).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With