简体   繁体   English

Python进程未响应处理分段错误的自定义信号处理程序

[英]Python process not responding with custom signal handler dealing with segmentation fault

Python builtin signal handler not working consistently when dealing with signal related to segmentation fault. 处理与分段错误相关的信号时,Python内置的信号处理程序无法正常工作。 By using kill command to send SIGSEGV to the process, it works correctly. 通过使用kill命令将SIGSEGV发送到该进程,它可以正常工作。 But when an illegal memory access inside the process happens, which is also a SIGSEGV signal, cannot be handled by the custom signal handler. 但是,如果在进程内部发生了非法的内存访问,这也是SIGSEGV信号,那么自定义信号处理程序将无法处理该信号。

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 . 我希望ctypes.string_at(0) )引发的分段错误(SIGSEGV)被信号处理程序捕获,但是没有捕获,并且进程停止响应ctrl+ckill -2 PIDkill -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. 但是,我注释ctypes.string_at(0)行,并发送带有kill -11 PID SIGSEGV,该信号已按预期由我的处理程序处理。 Besides, I don't understand that although the process doesn't respond, it keeps a 100% CPU usage. 此外,我不了解虽然该进程没有响应,但它保持100%的CPU使用率。

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. Python不能被实际信号处理(因为有他们可以利用很少的动作)执行,所以底层的信号处理程序总是返回。 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. 对于异步信号和“可选错误”(例如SIGPIPE)而言,这很好,但是对于实际的程序错误,这是没有意义的,因为没有有效的执行可恢复。 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). 在某些平台上,在这种情况下返回只会导致再次发出相同的信号,并导致无限循环(永远不会到达执行Python级处理程序的代码)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM