Skip to content

Bug: PEP719 #2857

@CodeWhizX

Description

@CodeWhizX

Describe the bug

Software Incident Report
Report ID: SR-202512-PY313-01

Status: Open / Critical

Date: December 29, 2025, 00:12:24 AM IST

  1. Executive Summary
    A fatal runtime crash was observed in the Python 3.13 application. The process terminated via an EXC_BAD_INSTRUCTION (SIGILL) signal triggered by a threading assertion failure within the macOS system libraries. The crash occurs because a background worker thread attempted to invoke a system API (TSMGetInputSourceProperty) that macOS requires to be executed strictly on the Main Thread.

  2. System Information
    Process: Python [8137]

Path: /Library/Frameworks/Python.framework/Versions/3.13/Resources/Python.app/Contents/MacOS/Python

Python Version: 3.13.7 (Native X86-64)

OS Version: macOS 10.15.7 (Build 19H2026)

System Integrity Protection: Enabled

Uptime: 25,000 seconds (~7 hours)

  1. Failure Analysis
    3.1 Crash Signature
    Crashed Thread: 8

Exception Type: EXC_BAD_INSTRUCTION (SIGILL)

Termination Reason: Namespace SIGNAL, Code 0x4

Specific Error: BUG IN CLIENT OF LIBDISPATCH: Assertion failed: Block was expected to execute on queue [com.apple.main-thread]

3.2 Root Cause Identification
Review of the stack trace for Thread 8 identifies the exact sequence of the failure:

Thread 8 (a background thread) is running a Python generator (gen_iternext).

The generator calls a C-extension function via _ctypes.cpython-313-darwin.so.

The ctypes call invokes TSMGetInputSourceProperty within the Apple HIToolbox framework.

The macOS Grand Central Dispatch (libdispatch) detects that this system property query is happening on a background queue.

To prevent system instability, libdispatch triggers a hardware-level exception (_dispatch_assert_queue_fail), crashing the app.

3.3 Thread 0 (Main Thread) Context
The log shows the Main Thread was occupied with the Tkinter event loop (_tkinter_tkapp_mainloop_impl) and Tcl callbacks. This confirms that the application is a GUI-based program where the Main Thread is dedicated to rendering and event handling, while the logic in Thread 8 was attempting "illegal" direct system access.

  1. Impact
    Immediate Crash: The application terminates instantly without any opportunity for Python-level error handling (try/except).

Data Loss: Any unsaved state in memory is lost as the process is killed by the OS kernel.

  1. Corrective Action Plan
    Action 1: Refactor Background Queries
    Any code utilizing ctypes or libraries that query keyboard layouts (e.g., pynput, pyautogui, or custom HIToolbox wrappers) must be moved out of the background thread.

Action 2: Thread-Safe Delegation
Use the queue module or Tkinter's .after() method to delegate the system query to the main thread.

Current (Faulty): Thread 8 -> ctypes -> HIToolbox

Proposed (Stable): Thread 8 -> queue.put(request) -> Main Thread (Thread 0) -> HIToolbox -> queue.put(result)

Action 3: Library Audit
Since this is occurring on Python 3.13.7, ensure all third-party binaries (located in site-packages) are compatible with 3.13's new internal threading structures.

  1. Conclusion
    The crash is a definitive Thread Safety Violation. The application is attempting to query macOS input settings from a worker thread, which is strictly prohibited by the OS. Synchronizing these calls to the Main Thread will resolve the SIGILL error.

To Reproduce

Steps to Reproduce (STR)
Environment Setup:

Ensure you are using macOS 10.15 or higher.

Install Python 3.13.x.

Verify that System Integrity Protection is enabled (as per your log).

Create the Trigger Script: Save the following code as repro_bug.py. This script uses ctypes to call the exact function found in your crash log (TSMGetInputSourceProperty) from a background thread.

Python

import ctypes
import threading
import time

Load the framework mentioned in the crash log

hitoolbox = ctypes.cdll.LoadLibrary('/System/Library/Frameworks/Carbon.framework/Frameworks/HIToolbox.framework/HIToolbox')

def trigger_crash():
print("Thread 8: Attempting illegal system call...")
# This function requires the Main Thread queue on macOS
# Calling it here will trigger the libdispatch assertion failure
hitoolbox.TSMGetInputSourceProperty(None, None)

print("Main Thread: Starting background worker...")
thread = threading.Thread(target=trigger_crash)
thread.start()
thread.join()
Execute the Script: Open the Terminal and run:

Bash

python3 repro_bug.py
Observe the Result: The application will not exit with a Python error. Instead, it will disappear instantly, and the Terminal will display: Illegal instruction: 4

Verify the Crash Log: Open the Console.app on macOS or check /Library/Logs/DiagnosticReports/. The new log will match your original report:

Crashed Thread: 8 (or whichever worker thread was used).

Assertion: Block was expected to execute on queue [com.apple.main-thread].

Visualizing the Fault Path
The crash occurs because the execution flow crosses a "red line" established by the macOS kernel for system security and stability.

Summary for the Bug Report
Reproduction Logic: The issue is reproducible by invoking any HIToolbox or CoreFoundation property getter that interacts with the window server or input methods from a non-main dispatch queue. Python 3.13’s threading implementation exposes this immediately as it lacks the global locks that occasionally "masked" these race conditions in older versions.

Expected behavior

Feature | Actual Behavior (The Bug) | Expected Behavior (The Fix) -- | -- | -- Stability | Crashes with SIGILL immediately. | Runs indefinitely without interruption. Threading | Background thread calls System APIs. | Background thread communicates via Queue. OS Interface | Violates libdispatch assertions. | Complies with macOS Main Thread constraints. User Experience | Application disappears (Fatal). | Application remains responsive and fluid. Python Version | 3.13 triggers strict memory/thread checks. | Code is refactored to be 3.13-compliant.

URL to the issue

No response

Screenshots

"![SCREENSHOT_DESCRIPTION](SCREENSHOT_LINK.png)"

Browsers

Other

Operating System

macOS

Browser Version

No response

Relevant log output

Log Type:        Threading Assertion Failure (SIGILL)
Component:       libdispatch.dylib / HIToolbox
Assertion:       Block was expected to execute on queue [com.apple.main-thread]

--------------------------------------------------------------------------------
CRASHED THREAD: Thread 8
--------------------------------------------------------------------------------
0  libdispatch.dylib      0x00007fff7262c8f1 _dispatch_assert_queue_fail + 99
1  libdispatch.dylib      0x00007fff7262c886 dispatch_assert_queue + 122
2  com.apple.HIToolbox    0x00007fff376ffdc2 islGetInputSourceListWithAdditions + 119
3  com.apple.HIToolbox    0x00007fff377025b8 isValidateInputSourceRef + 90
4  com.apple.HIToolbox    0x00007fff37702480 TSMGetInputSourceProperty + 30 <--- [FATAL CALL]
5  libffi.dylib           0x00007fff7042f905 ffi_call_unix64 + 85
6  libffi.dylib           0x00007fff7042f244 ffi_call_int + 694
7  _ctypes.cpython-313    0x0000000107cc0eda _ctypes_callproc + 1114
8  _ctypes.cpython-313    0x0000000107cb7218 PyCFuncPtr_call + 312
9  org.python.python      0x00000001042a6e55 _PyEval_EvalFrameDefault + 51397
10 org.python.python      0x00000001041046db gen_iternext + 139
11 org.python.python      0x0000000104294ce7 builtin_next + 71
...
17 org.python.python      0x0000000104404782 thread_run + 146
18 org.python.python      0x0000000104374584 pythread_wrapper + 36

--------------------------------------------------------------------------------
REASONING FOR LOG SELECTION:
--------------------------------------------------------------------------------
1. Frame 4 shows the target: TSMGetInputSourceProperty. This is a "Main Thread Only" API.
2. Frame 0-1 shows the watchdog: libdispatch detected the call was on Thread 8.
3. Frame 17-18 confirms this was a standard Python `threading.Thread` object.

Additional context

FIX IT

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis is a bug!

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions