python / python/cpython

Sending many signals to a Python process crashes the interpreter

Open
#118,143 9 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type-bug
Dominant language
Python
Stars
77.2k
Forks
36k
PR merge metrics
PR metrics pending

Description

Bug report

Bug description:

Consider the following simple program (test-breakage.py):

from time import sleep
import os
import signal


class Foreman:
    def __init__(self):
        signal.signal(signal.SIGUSR1, self.handle_sigusr1)
        pid = os.getpid()
        print("Test script created, my pid is %s", pid)
        with open("/tmp/test-breakage.pid", "w") as f:
            f.write(str(pid))

    def handle_sigusr1(self, sig, frame):
        print("handle_sigusr1")

    def run_forever(self):
        sleep(3600)


Foreman().run_forever()

Now, a tool to send "a lot" of signal to it:

import os
import sys
import signal


pid = int(sys.argv[1])
iterations = int(sys.argv[2])

for i in range(iterations):
    os.kill(pid, signal.SIGUSR1)

Or, if you want the signals to be sent more quickly, implemented in c:

#include <stdlib.h>
#include <signal.h>


int main(int argc, char*argv[]) {
    long pid, iterations;
    if (argc > 2) {
        pid = strtol(argv[1], NULL, 0);
        iterations = strtol(argv[2], NULL, 0);

        for (int i = 0; i < iterations; i++) {
            kill(pid, SIGUSR1);
        }
   }
   return 0;
}

Running these scripts with "sufficiently high" numbers results in various crashes in test-breakage

  • Exit with "User defined signal 1" (shouldn't happen, we've defined a handler)
  • RuntimeError without any further information
  • Exit without any printed string
  • RuntimeError: reentrant call inside <_io.BufferedWriter name=''>

(In all cases, after repeating "handle_sigusr1" a number of times first)

tested on Linux w. Python 3.10

CPython versions tested on:

3.10

Operating systems tested on:

Linux

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the failure with the test-breakage.py signal handler and the Python or C signal-sending scripts on Linux. Compare the reported outcomes under sustained SIGUSR1 delivery; done means the interpreter remains stable and the registered handler continues to behave correctly without the listed crashes or unintended termination.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.