Skip to content

SystemExit raised in signal handler not propagated to running threads, killing them instead #107170

@sandrinr

Description

@sandrinr

Bug report

It seems to me that threads running when sys.exit() is called during signal handling are killed immediately. It further seems that the try ... finally contract is adhered to on the main thread but broken in other threads.

Consider the following pice of Python code:

import signal
import sys
import time
from threading import Thread


def termination_signal_handler(_, __):
    print("termination_signal_handler")
    sys.exit()


def f():
    try:
        print("Begin f")
        time.sleep(1000)
    except SystemExit:
        print("Got SystemExit in f")
        raise
    finally:
        print("End f")


signal.signal(signal.Signals.SIGINT, termination_signal_handler)
signal.signal(signal.Signals.SIGTERM, termination_signal_handler)

try:
    t = Thread(target=f, daemon=False)
    t.start()
    t.join()
except SystemExit:
    print("Got SystemExit in main")
    raise
finally:
    print("End main")

When running this code and hitting CTRL-C after a short while I get the following output:

$ python testthread.py 
Begin f
^Ctermination_signal_handler
Got SystemExit in main
End main

The output indicates that the thread t was killed right away, leaving the finally (and the except SystemExit clause in f) unexecuted.

My expectation would have been that either (XOR)

  • (a) SystemExit would be propagated to all threads
  • (b) SystemExit raised on the main thread and the other threads are left running
  • (c) Nothing happens

According to the Python doc, non daemonic threads should not be killed when the main thread exits. Also, according to several SO posts, the expected behavior would more be in the area of (b).

Note: The same code without the signal handling is behaving in a similar way. The only difference there is that the KeyboardInterupt trace is also logged to the console.

Am I missing something?

Your environment

  • CPython versions tested on: 3.11.4
  • Operating system and architecture: macOS-13.4.1-arm64-arm-64bit

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.10only security fixes3.11only security fixes3.12only security fixestype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions