FIX: Resource cleanup on Python shutdown to avoid segfaults by bewithgaurav · Pull Request #255 · microsoft/mssql-python

Work Item / Issue Reference

AB#38824

GitHub Issue: #254


Summary

This pull request addresses a critical segfault issue that occurred during Python interpreter shutdown when using the mssql_python package, especially in scenarios with unclosed cursors, syntax errors, or concurrent operations. The changes introduce robust detection of Python's shutdown state to prevent unsafe resource cleanup and improve test coverage for these edge cases.

Key changes include:

Python Shutdown Safety & Resource Cleanup

  • Added a centralized helper function is_python_finalizing() in ddbc_bindings.cpp to reliably detect when Python is shutting down or finalizing, using both Py_IsInitialized() and the sys._is_finalizing attribute for compatibility across Python versions.
  • Updated the LOG function to skip logging if Python is shutting down, and to handle exceptions gracefully to avoid crashes during interpreter cleanup. [1] [2]
  • Modified the SqlHandle::free() method to prevent freeing SQL_HANDLE_STMT handles during shutdown, as their parent DBC handles may already be freed, avoiding double-free and segfaults. Handles are marked as freed instead.

Test Coverage for Shutdown and Concurrency Edge Cases

  • Added multiple new tests in test_005_connection_cursor_lifecycle.py to ensure no segfaults occur during Python shutdown, including:
    • Tests for syntax errors without explicit resource cleanup.
    • Tests for multiple concurrent cursor operations and abrupt interpreter exits.
    • Tests for closing connections with pending results and aggressive threading scenarios.

These changes significantly improve the stability of the mssql_python package in complex and error-prone scenarios, especially during interpreter shutdown and multithreaded usage.