Skip to content

fix(foundation): the pyshark engine raises a spurious TSharkCrashException on Python 3.9–3.12 #2633

Closed

Description

@JarryShaw

extract(engine='pyshark') on Python 3.9–3.12 can raise a spurious TSharkCrashException: TShark (pid N) seems to have crashed (retcode: 255). It happens on roughly 1 in 15–40 extractions on a loaded host. #2620 found the cause, which is CPython gh-87744. That was fixed in 3.13 and never backported. asyncio's BaseSubprocessTransport.kill goes through Popen.kill → send_signal → poll(), which reaps a tshark that has already exited. SafeChildWatcher then logs Unknown child process pid N, will report returncode 255, and pyshark's close() raises. #2620 only makes the tests rerun; users are still exposed.

Needs deciding: the library-level mitigation.

  1. In PyShark.close(), swallow a TSharkCrashException only when it reports retcode: 255 and the capture has reached EOF, then clear its _running_processes. A prototype ran 60 extractions with 0 failures. Risks: it depends on pyshark's message text and private attributes, it would hide a genuine tshark exit 255, and the real exit status stays lost.
  2. Swap in ThreadedChildWatcher while the engine runs. A prototype gave 0 failures in 60. Risks: it changes process-global state, uses a deprecated API, and overrides pyshark's own choice.
  3. Patch BaseSubprocessTransport.kill to signal with os.kill, as 3.13 does. This is a global monkeypatch of the stdlib.
  4. Document the race and do nothing in the library.

Recommendation: 1, gated to 3.9–3.12. The fix touches only pcapkit's own engine, and the condition is narrow. Separately, pyshark could be asked upstream not to kill a tshark that has already reached EOF. Filing that is your call, since it posts to a third-party repository.

Activity

  1. added this to the PyPCAPKit v1.6 milestone on Nov 2, 2026
  2. added
    bugIssues reporting a defect (set by the bug report template; a default, not an assessment)
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Nov 2, 2026
  3. JarryShaw commented on Nov 2, 2026

    @JarryShaw
    OwnerAuthor

    Take 1

  4. JarryShaw commented on Nov 2, 2026

    @JarryShaw
    OwnerAuthor

    The owner chose 1, paraphrased: pcapkit's own PyShark.close() absorbs the spurious crash. The condition is kept as narrow as possible:

    • TSharkCrashException with retcode: 255;
    • the capture has already reached EOF;
    • Python 3.9–3.12.

    Anything else still raises. The crashed capture is cleared so that its __del__ cannot raise later. The swallowed crash is logged at a handled level, not CRITICAL. A worker is on it. Nothing is filed upstream with pyshark.

  5. added
    wipWork in flight - a covering PR is open or an agent is actively on it
    and removed
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Nov 2, 2026
  6. removed
    wipWork in flight - a covering PR is open or an agent is actively on it
    on Nov 2, 2026
  7. JarryShaw commented on Nov 2, 2026

    @JarryShaw
    OwnerAuthor

    A correction to the paraphrase above: in review of #2642, the owner then ruled that the absorption has no Python version gate. The merged fix (ce88220c0) applies on every Python, and the earlier 3.9–3.12 window survives only as background on why the status is lost.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIssues reporting a defect (set by the bug report template; a default, not an assessment)

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions