You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#64874 fixed the macOS SIGSEGV/SIGABRT crash during task execution by switching from bare os.fork() to fork + exec in the Task SDK supervisor for ActivitySubprocess. The same macOS fork-safety issue applies to the DAG processor and triggerer, which both use WatchedSubprocess and both run code paths that can trigger ObjC class initialization (DNS resolution, secret backends, HTTP clients, etc.).
Problem
WatchedSubprocess subclasses hit by this on macOS:
DagFileProcessorProcess (airflow-core/src/airflow/dag_processing/processor.py) -- parses DAG files on a forked child. DAG files frequently have top-level network calls (secret backends, connection lookups, variable fetches). We already observed the DAG processor ObjC crash during Fix macOS SIGSEGV in task execution by using fork+exec #64874 investigation -- the InProcessExecutionAPI spins up an a2wsgi background thread that initializes httpx / ssl / Security.framework.
TriggerRunnerSupervisor (airflow-core/src/airflow/jobs/triggerer_job_runner.py) -- runs user-defined triggers that poll APIs / watch queues / hit HTTP endpoints. Practically always network calls.
#64874 intentionally scoped the fix to task execution so _child_exec_main() could hardcode _subprocess_main as the entry point. Both of these callers pass different targets:
Generalize _child_exec_main() so it can rehydrate an arbitrary target across execv. Approach:
Before execv, encode the target as a module:function string in an env var (e.g., _AIRFLOW_CHILD_TARGET). Class methods can be handled as module:ClassName.method.
In _child_exec_main(), read the env var, importlib.import_module + getattr to rehydrate, then call _fork_main(..., target).
DagFileProcessorProcess.start() and TriggerRunnerSupervisor.start() compute use_exec = sys.platform in _FORK_EXEC_PLATFORMS and pass it through.
Acceptance criteria
DAG processor runs without SIGSEGV/SIGABRT on macOS when DAG files trigger DNS / httpx / Security.framework at parse time.
Triggerer runs user triggers without fork-safety crashes on macOS.
_child_exec_main() does not hardcode _subprocess_main; it accepts any importable target.
No regression on Linux (bare fork path untouched for non-_FORK_EXEC_PLATFORMS).
Context
#64874 fixed the macOS
SIGSEGV/SIGABRTcrash during task execution by switching from bareos.fork()tofork + execin the Task SDK supervisor forActivitySubprocess. The same macOS fork-safety issue applies to the DAG processor and triggerer, which both useWatchedSubprocessand both run code paths that can trigger ObjC class initialization (DNS resolution, secret backends, HTTP clients, etc.).Problem
WatchedSubprocesssubclasses hit by this on macOS:DagFileProcessorProcess(airflow-core/src/airflow/dag_processing/processor.py) -- parses DAG files on a forked child. DAG files frequently have top-level network calls (secret backends, connection lookups, variable fetches). We already observed the DAG processor ObjC crash during Fix macOSSIGSEGVin task execution by usingfork+exec#64874 investigation -- theInProcessExecutionAPIspins up ana2wsgibackground thread that initializeshttpx/ssl/Security.framework.TriggerRunnerSupervisor(airflow-core/src/airflow/jobs/triggerer_job_runner.py) -- runs user-defined triggers that poll APIs / watch queues / hit HTTP endpoints. Practically always network calls.#64874 intentionally scoped the fix to task execution so
_child_exec_main()could hardcode_subprocess_mainas the entry point. Both of these callers pass differenttargets:target=_parse_file_entrypointtarget=TriggerRunnerSupervisor.run_in_processProposed approach
Generalize
_child_exec_main()so it can rehydrate an arbitrary target acrossexecv. Approach:execv, encode the target as a module:function string in an env var (e.g.,_AIRFLOW_CHILD_TARGET). Class methods can be handled asmodule:ClassName.method._child_exec_main(), read the env var,importlib.import_module+getattrto rehydrate, then call_fork_main(..., target).DagFileProcessorProcess.start()andTriggerRunnerSupervisor.start()computeuse_exec = sys.platform in _FORK_EXEC_PLATFORMSand pass it through.Acceptance criteria
SIGSEGV/SIGABRTon macOS when DAG files trigger DNS / httpx / Security.framework at parse time._child_exec_main()does not hardcode_subprocess_main; it accepts any importable target._FORK_EXEC_PLATFORMS).Related
SIGSEGVin task execution by usingfork+exec#64874 (task execution fix, scoped this work)