microsoft / microsoft/mssql-python

SIGSEGV in libmsodbcsql during process teardown (iconv_close) on macOS arm64 with concurrent encrypted connections

Offen
#685 2 Kommentare 0 Reaktionen 1 zugewiesene Person Auf GitHub ansehen

@bewithgaurav arbeitet bereits daran.

Seit 20.7.2026.

area: packaging-platform bug dependency: external triage done
Vorherrschende Sprache
Python
Sterne
473
Forks
60
Ø Merge
2 T. 11 Std.
Gemergte PRs (30 T.)
36

Beschreibung

Summary

On macOS arm64, the process crashes with SIGSEGV during interpreter/process teardown (exit()__cxa_finalize_ranges), inside the driver's static destructor calling iconv_close. The crash surfaces at shutdown when multiple worker threads have been using encrypted connections (Encrypt=yes) concurrently. The process terminates with exit code 139 and no Python traceback.

This appears related to, but distinct from, #668 (TLS stream corruption on concurrent encrypted reads — data corruption, no crash) and #679 (SIGSEGV in SQLFetchScroll during concurrent fetchmany). Here the faulting frame is not SQLFetchScroll but the driver's teardown path via libiconv.

Environment

  • macOS 26.5.2 (build 25F84), Apple Silicon (arm64)
  • Python 3.12.11
  • mssql-python 1.11.0 (bundled libmsodbcsql.18.dylib, mssql_python/libs/macos/arm64)
  • SQLAlchemy 2.1.0b3
  • Connection options: Encrypt=yes, TrustServerCertificate=yes, SNAPSHOT isolation
  • Concurrency: multiple worker threads. mssql-python's native connection pooling is enabled (enable_pooling=True), which uses a process-global pooling manager, so encrypted connections are pooled and reused across the process rather than being one-per-thread.

Crash

Signal: SIGSEGV / EXC_BAD_ACCESS (KERN_INVALID_ADDRESS), subtype "possible pointer authentication failure" at a wild address.

Faulting thread (from the macOS .ips crash report):

libiconv.2.dylib       _citrus_iconv_close
libiconv.2.dylib       __bsd_iconv_close
libmsodbcsql.18.dylib  <driver frame>
libsystem_c.dylib      __cxa_finalize_ranges
libsystem_c.dylib      exit
libdyld.dylib          dyld4::LibSystemHelpers::exit(int) const
dyld                   dyld4::LibSystemHelpersWrapper::exit(int) const
dyld                   start

So the crash happens while the process is exiting: exit() runs C++ static destructors (__cxa_finalize_ranges), one of which belongs to libmsodbcsql.18.dylib and calls iconv_close on what looks like an already-freed or corrupted iconv handle, producing a pointer-authentication failure.

Scenario

  1. Several worker threads read from different tables concurrently under SNAPSHOT isolation over pooled encrypted connections (Encrypt=yes).
  2. The application begins shutting down (an unrelated application-level error triggers a fail-fast exit()) while those threads/connections are still being torn down.
  3. During exit(), the driver's static-destructor cleanup segfaults in iconv_close.

The iconv involvement is notable: iconv is the character-encoding conversion layer, and #668 reports TLS/stream corruption specifically under concurrent encrypted reads on arm64. A corrupted iconv handle that only faults at driver finalization is consistent with encoding/stream state being left in a bad state under that same concurrency.

Relation to existing issues

  • #668 — TLS stream corruption on concurrent encrypted reads (arm64): data corruption / protocol errors, no hard crash.
  • #679 — SIGSEGV in SQLFetchScroll during concurrent fetchmany (arm64).

This report is a third manifestation on the same platform and connection profile (macOS arm64, Encrypt=yes, concurrent threaded reads), but the crash occurs at process teardown via libiconv, not during an active fetch. Filing separately so the teardown/iconv stack is tracked; it may share the root cause reported in #668.

Notes

  • No Python-level exception is raised for the crash itself; only the exit code (139) and the macOS crash report indicate it.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.