microsoft / microsoft/mssql-python

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

Abierto
#685 2 comentarios 0 reacciones 1 asignado Ver en GitHub

@bewithgaurav ya está trabajando en esto.

Desde el 20/7/2026.

area: packaging-platform bug dependency: external triage done
Lenguaje dominante
Python
Estrellas
473
Forks
60
Merge medio
2 d 11 h
PR fusionados (30 d)
36

Descripción

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.

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.