Skip to content

Downgrade to Python 3.7 due to stack corruption in Python 3.8+#12298

Merged
michaelDCurran merged 8 commits intomasterfrom
py3.7
Apr 20, 2021
Merged

Downgrade to Python 3.7 due to stack corruption in Python 3.8+#12298
michaelDCurran merged 8 commits intomasterfrom
py3.7

Conversation

@michaelDCurran
Copy link
Copy Markdown
Member

@michaelDCurran michaelDCurran commented Apr 16, 2021

Link to issue number:

Fixes #12152
Fixes #12154

Summary of the issue:

Since upgrading to Python 3.8, several serious crashes in NVDA have been reported. Specifically:

Both of these issues were traced to stack corruption after a Python callback of NVDA's was called from external libraries. In SAPI4's case, after calling NVDA's implementation of ITTSBufNotifySink::TextDataStarted, and in the Windows Server 2012 case: IUIAutomationPropertyChangedEventHandler::handlePropertyChangedEvent.

It seems as though libFFI / Python ctypes is not cleaning the stack properly after executing a Python callback with the stdcall calling convention (ctypes WINFUNCTYPE), where the callback contained at least one argument larger than 4 bytes (E.g. a long long, or a VARIANT struct), and the arguments preceding it were such that this argument was not aligned to an 8 byte boundary. E.g. the callback might be:

  • callback(void*, long long) or
  • callback(void*, void*, int, VARIANT)

See Python bug: https://bugs.python.org/issue38748
On that bug I have attached a minimal testcase.

This bug affects both Python 3.8 and Python 3.9.
The bug is most likely in the libFFI project used by Python's ctypes module. Python 3.8 switched to a much more recent and official version of libFFI I believe.

Although we do really want to move to Python 3.8+ as soon as we can, right now this bug makes it impossible to do so. We could specifically work around the currently known manifestations by moving some of that code into C++, but that brings its own risks, and we still don't know where else this issue may appear in our code. The appropriate thing to do right now is stay on Python 3.7 until we can work with Python / libFFI to get this resolved.

Description of how this pull request fixes the issue:

Downgrades to Python 3.7 by referencing Python 3.7 (rather than 3.8) in NVDA's build system.

The existing PRs that needed to be reverted were:

None of these PRs provided any user visible changes.

The rest of the Python 3.8 work, including the switch to a virtual
environment etc is all compatible with Python 3.7 and can remain.

Testing strategy:

  • Successfully Ran unit tests
  • Successfully ran system tests
  • Ran locally for a while
  • The reporters of the SAPI4 and Windows server 2012 issues report the crashes are gone when testing a try build of this branch.

Known issues with pull request:

Change log entry:

None needed.

Code Review Checklist:

This checklist is a reminder of things commonly forgotten in a new PR.
Authors, please do a self-review and confirm you have considered the following items.
Mark items you have considered by checking them.
You can do this when editing the Pull request description with an x: [ ] becomes [x].
You can also check the checkboxes after the PR is created.

  • Pull Request description is up to date.
  • Unit tests.
  • System (end to end) tests.
  • Manual tests.
  • User Documentation.
  • Change log entry.
  • Context sensitive help for GUI changes.

@michaelDCurran michaelDCurran marked this pull request as ready for review April 16, 2021 01:36
@michaelDCurran michaelDCurran added this to the 2021.1 milestone Apr 16, 2021
@XLTechie
Copy link
Copy Markdown
Collaborator

XLTechie commented Apr 16, 2021 via email

@michaelDCurran
Copy link
Copy Markdown
Member Author

michaelDCurran commented Apr 16, 2021 via email

@dpy013
Copy link
Copy Markdown
Contributor

dpy013 commented Apr 16, 2021

Assuming that this is likely to take a while to be resolved (given that they didn't before now), is it possible we could jump straight to 3.10 instead of continuing incrementally to 3.8, after this is fixed?
Support in one step

@lukaszgo1
Copy link
Copy Markdown
Contributor

Please also revert #12141.

@lukaszgo1
Copy link
Copy Markdown
Contributor

Have you considered bringing back code from #12042 which prevents people from attempting to build with Python 3.7.6? While it is unlikely someone would try the warning in the readme and in the sconscript does no harm and the code is already written.

@josephsl
Copy link
Copy Markdown
Contributor

josephsl commented Apr 16, 2021 via email

Copy link
Copy Markdown
Contributor

@feerrenrut feerrenrut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

  • As mentioned by @lukaszgo1, we should remove the lines from the userguide: #12141
  • It makes sense to reintroduce the code to check for 3.7.6 from #12042. That version of python does not work with NVDA, although it is old, people are often unaware they are on an old version.
# in sconscript
if sys.version_info.micro == 6:
	# #10696: Building with Python 3.7.6 fails. Innform user and exit.
	Py376FailMsg = "Building with Python 3.7.6 is not possible.\nPlease use more  recent version of Python 3."
	raise RuntimeError(Py376FailMsg)

@XLTechie
Copy link
Copy Markdown
Collaborator

XLTechie commented Apr 19, 2021 via email

Copy link
Copy Markdown
Contributor

@feerrenrut feerrenrut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python 3.8: Impossible to navigate in Windows Explorer under Windows Server 2012. SAPI4 crashes in alpha-21882,528d5708

6 participants