Nuitka/Nuitka

signal.signal() not triggering when using --onefile, and signal is being sent by kill

Open

#2491 aperta il 12 ott 2023

Vedi su GitHub
 (3 commenti) (0 reazioni) (1 assegnatario)Python (565 fork)batch import
delayedduplicatehelp wanted

Metriche repository

Star
 (10.351 star)
Metriche merge PR
 (Merge medio 5g 12h) (6 PR mergiate in 30 g)

Descrizione

When signal.signal() is used in a program to register a signal handler and --onefile to compile, the signal handler does not get called when the program gets signaled by kill command. It does work in --standalone.

This bug is a possible duplicate of https://github.com/Nuitka/Nuitka/issues/2156 , however, the behavior I am getting is different than the behavior in that ticket.

Reproduction steps

create signal_debug.py test program:

# ./signal_debug.py
import signal
import sys
import time
from types import FrameType
from typing import Optional

def handle_signal(signal: int, frame: Optional[FrameType]):
    print(f"\n{signal} signal handled", flush=True)
    sys.exit(0)

signal.signal(signal.SIGINT, handle_signal)

while True:
    print(".", end="", flush=True)
    time.sleep(0.35)

create ./test.sh script:

#!/bin/bash
# ./test.sh
python3.11 -m venv .venv
./.venv/bin/python3 -m pip install nuitka==1.8.4
#./.venv/bin/python3 -m pip install Nuitka-develop.zip
./.venv/bin/python3 -m nuitka --version
./.venv/bin/python3 -m pip freeze
## show standalone execution
# compile
./.venv/bin/python3 -m nuitka --standalone signal_debug.py
# test binary
echo "Starting signal_debug.dist/signal_debug.bin"
./signal_debug.dist/signal_debug.bin &
SIGNAL_DEBUG_PID=$!
sleep 1
kill -s SIGINT $SIGNAL_DEBUG_PID
echo "kill -s SIGINT $SIGNAL_DEBUG_PID sent"
wait $SIGNAL_DEBUG_PID
echo "./signal_debug.dist/signal_debug.bin exited."
## show onefile execution
# compile
./.venv/bin/python3 -m nuitka --onefile signal_debug.py
# test binary
echo "Starting signal_debug.bin"
./signal_debug.bin &
SIGNAL_DEBUG_PID=$!
sleep 1
kill -s SIGINT $SIGNAL_DEBUG_PID
echo "kill -s SIGINT $SIGNAL_DEBUG_PID sent"
## does behavior change the second time?
#sleep 1
#kill -s SIGINT $SIGNAL_DEBUG_PID
#echo "kill -s SIGINT $SIGNAL_DEBUG_PID sent"
wait $SIGNAL_DEBUG_PID
echo "./signal_debug.bin exited."

standalone output

Starting signal_debug.dist/signal_debug.bin
...kill -s SIGINT 3419343 sent

2 signal handled
./signal_debug.dist/signal_debug.bin exited.

onefile output

Starting signal_debug.bin
...kill -s SIGINT 3419661 sent
.............../signal_debug.bin exited.

Environment Information

./.venv/bin/python3 -m nuitka --version

1.9rc5
Commercial: None
Python: 3.11.4 (main, Jun 13 2023, 16:07:53) [GCC 8.5.0 20210514 (Red Hat 8.5.0-16)]
Flavor: Unknown
Executable: /home/<redacted>/scratchpad/signal-reproducer/.venv/bin/python3
OS: Linux
Arch: x86_64
Distribution: Rhel (based on Fedora) 8.7
Version C compiler: /usr/bin/gcc (gcc).

installation method

python3.11 -m venv .venv
#./.venv/bin/python3 -m pip install nuitka==1.8.4
./.venv/bin/python3 -m pip install Nuitka-develop.zip

./.venv/bin/python3 -m pip freeze

Nuitka==1.8.4
ordered-set==4.1.0
zstandard==0.21.0

Additional testing

  • behavior is same in 1.8.4 and develop branch (1.9rc5)
  • behavior also occurs when using asyncio.get_event_loop().add_signal_handler(signal.SIGINT, ...)
  • sending multiple SIGINT's does not help
  • ctrl-c on the command line DOES work:
     ./signal_debug.bin
     ....^C
     2 signal handled
    
  • behavior is same when using --onefile-child-grace-time=20000, but more dots appear before the program exits
    Starting signal_debug.bin
    ...kill -s SIGINT 3424398 sent
    ........................................................../signal_debug.bin exited.
    

Guida contributor