Repository: nvaccess/nvda

Issue:
NVDA Alpha crashes  while selecting files in windows 7 explorer 
You have arrived at a default issue template (bug report).
It is preferable to [choose the type of issue](https://github.com/nvaccess/nvda/issues/new/choose) to submit.
Hint: Swap to the preview tab to be able to click the links.
Direct links to the templates:

- [Bug report](https://github.com/nvaccess/nvda/issues/new?template=bug_report.md)
- [Feature request](https://github.com/nvaccess/nvda/issues/new?template=feature_request.md)

<!--
Please thoroughly read NVDA's wiki article on how to fill in this template, including how to provide the required files.
Issues may be closed if the required information is not present.
https://github.com/nvaccess/nvda/blob/master/devDocs/githubIssueTemplateExplanationAndExamples.md
Please also note that the NVDA project has a Citizen and Contributor Code of Conduct which can be found at https://github.com/nvaccess/nvda/blob/master/CODE_OF_CONDUCT.md. NV Access expects that all contributors and other community members read and abide by the rules set out in this document while participating or contributing to this project. This includes creating or commenting on issues and pull requests. 

Each of the questions and sections below start with multiple hash symbols (#). Place your answers and information on the blank line below each question.
-->

### Steps to reproduce:
In windows 7, use control cursor and space to select  or deselect a number of items to be copied. 
### Actual behavior:
After some time it stops with an error and no further sound comes from nvda, one has to reboot nvda to get back in.
### Expected behavior:
It sould work like the latest stable release 2021.1, and simply add to the selected  files as normal
### System configuration
#### NVDA installed/portable/running from source:
Portable, Latest alpha as per 21st July 2021 Windows 7 Pro.
#### NVDA version:
 NVDA version alpha-23387,723fe074


As above Windows 7 pro up to date.#### Windows version:

#### Name and version of other software in use when reproducing the issue:
Windows Explorer, though  other software was loaded, it normally runs like this in the stable version. The main one being Goldwave 32 bit
#### Other information about your system:
Nothing out of the ordinary, but I'm using Espeak Quincy on an external sound box and  the machine is Intel based 4 cores with 8gig of ram.
### Other questions
#### Does the issue still occur after restarting your computer?
Yes but times vary
#### Have you tried any other versions of NVDA? If so, please report their behaviors.
Yes it functions perfectly in the latest stable 2021.1.
#### If add-ons are disabled, is your problem still occurring?
Yes as far as I can tell though the fault can be a very long time coming.
#### Does the issue still occur after you run the COM Registration Fixing Tool in NVDA's tools menu?
Yes
Last part of log reads.
IO - inputCore.InputManager.executeGesture (09:03:56.043) - winInputHook (3148):
Input: kb(desktop):control+downArrow
ERROR - stderr (09:03:56.086) - MainThread (3572):
Exception ignored in:
ERROR - stderr (09:03:56.099) - MainThread (3572):
<function _collectionCallback at 0x022846F0>
ERROR - stderr (09:03:56.116) - MainThread (3572):
Traceback (most recent call last):
ERROR - stderr (09:03:56.137) - MainThread (3572):
  File "garbageHandler.pyc", line 46, in _collectionCallback
ERROR - stderr (09:03:56.155) - MainThread (3572):
RecursionError
ERROR - stderr (09:03:56.160) - MainThread (3572):
:
ERROR - stderr (09:03:56.164) - MainThread (3572):
maximum recursion depth exceeded in comparison



Discussion:
I can confirm this, but for me it occurs mostly when backspacing text in edit controls using DisplayModel. The end of the log for me is:
```

ERROR - stderr (21:11:10.487) - winInputHook (2324):
Exception ignored in:
ERROR - stderr (21:11:10.497) - winInputHook (2324):
<function _collectionCallback at 0x01054858>
ERROR - stderr (21:11:10.517) - winInputHook (2324):
Traceback (most recent call last):
ERROR - stderr (21:11:10.537) - winInputHook (2324):
  File "garbageHandler.pyc", line 47, in _collectionCallback
ERROR - stderr (21:11:10.557) - winInputHook (2324):
  File "threading.pyc", line 1233, in current_thread
ERROR - stderr (21:11:10.577) - winInputHook (2324):
RecursionError
ERROR - stderr (21:11:10.597) - winInputHook (2324):
:
ERROR - stderr (21:11:10.617) - winInputHook (2324):
maximum recursion depth exceeded while calling a Python object

```

cc @michaelDCurran  @seanbudd  This should be added to 2021.2 since it does not occur in the current stable.
Possible regression caused by #12610 
AH interesting, @lukaszgo1's log mentions the win input hook thread, but @Brian1Gaff's log doesn't. Can one of you comfirm whether this issue is away with versions of NVDA Alpha from before today?
I have also had some issues when running NVDA from source at least for one week or two with errors in the log beginning with
`ERROR - stderr `
However, I have not identified in which circumstance it was occuring and thus, I did not bother to open an issue.
If I remember well it was happening when typing in Windows console (cmd) or in Matlab console.

Next time I get it, I will report it here.

My log snipped has been from alpha-23364,b7dd32fc so before #12610 got merged.
One reporter on the dev list was talking about it before that version, so I 
strongly suspect that it has been in older snaps, but I'm a bit busy or I'd 
download some and see, but its very much hit and miss when it happens.
 So the time to find it in each version could  be quite long. Has anyone 
found a definite set of actions that causes it? I could not, except that it 
has to have been running for over an hour. Not very helpful, sorry!

Brian

***@***.***
Sent via blueyonder.
Please address personal E-mail to:-
***@***.***, putting 'Brian Gaff'
in the display name field.
News 


As NV Access is internally having a lot of trouble reproducing this isue, we would very much appreciate if anyone who can reproduce the issue themselves, can test past alpha snapshots and try to more clearly pin-point when the issue started occuring please?
Possible points at which it got introduced:
* July 20, More robust keyboard modifier tracking (PR #12610)
* July 12, Fix Enum Cyclic Ref (PR #12617)
* June 30, Backwards compatible control types refactor (#12510)

Technical thoughts so far:
Perhaps Python is getting stuck in an infinit recursion maybe by calling an NvDAObject's next or parent over and over again) but it just happens that garbage collection happens one frame before the recursion limit, so that the recursion limit happens within the garbage handler callback.

Full log files are always appreciated here if that is possible. Can be sent to me privately if necessary.
I thus far have not had time to do this myself. The issue as you rightly say 
is defining an exact sequence that always will achieve the  error,, I only 
had it once more since the  one I started with, and it was very hard, even 
looking through the whole of that error to figure out any pattern at all.

 I  will have to do a lot of file selection and moving later this week, so 
it might show up again then.
 I'm using the latest snap now and have not had it today so far.
 Brian

***@***.***
Sent via blueyonder.
Please address personal E-mail to:-
***@***.***, putting 'Brian Gaff'
in the display name field.
Newsgroup monitored: alt.comp.blind-users 



>     * July 20, More robust keyboard modifier tracking (PR [Fix tracking of keyboard modifiers when watchdog is attempting recovery #12610](https://github.com/nvaccess/nvda/pull/12610))

This cannot be the cause - the first report on NVDA Devel dates back to July 18-th.

> Full log files are always appreciated here if that is possible. Can be sent to me privately if necessary.

I've send you a log file and crashdump generated from Task Manager from the crashed NVDA process.


The biggest problem with testing previous Alpha versions is that this issue is very rare. Before today I haven't experienced this problem for around a week and today it happened three times already. I also haven't managed to create a reliable reproduction steps sofar.
I have made a try build that hopefully catches the RecursionError and then logs the full stack:
https://ci.appveyor.com/api/buildjobs/ss2hq4c2ik3jcn94/artifacts/output%2Fnvda_snapshot_try-test_i12666-23470%2Cc7954370.exe
 Note that this does not fix the issue, but rather just provides some more information in the log when it happens.
If people who can reproduce the issue can test this try build, and provide me with the stack and traceback from the log that would be much appreciated. 

[RecursionwinVersion.txt](https://github.com/nvaccess/nvda/files/6892121/RecursionwinVersion.txt)
@michaelDCurran  Thanks for the try build. The  file with the stack trace is attached.
@michaelDCurran I've opened #12696 which hopefully fixes at least a part of this issue.
I've also been able to reproduce the crash which ends with `maximum recursion depth exceeded while calling a Python object`. the log fragment is as follows:
```
ERROR - garbageHandler._collectionCallback (14:14:16.608) - MainThread (3344):
Hit recursion depth in gc callback
Stack trace:
  File "nvda.pyw", line 362, in <module>
  File "core.pyc", line 746, in main
  File "wx\core.pyc", line 2237, in MainLoop
  File "gui\__init__.pyc", line 830, in Notify
  File "core.pyc", line 707, in run
  File "IAccessibleHandler\__init__.pyc", line 959, in pumpAll
  File "IAccessibleHandler\__init__.pyc", line 608, in processFocusWinEvent
  File "IAccessibleHandler\__init__.pyc", line 468, in winEventToNVDAEvent
  File "_UIAHandler.pyc", line 807, in isUIAWindow
  File "_UIAHandler.pyc", line 720, in _isUIAWindowHelper
  File "appModules\explorer.pyc", line 420, in isGoodUIAWindow
  File "winVersion.pyc", line 176, in getWinVer
  File "winVersion.pyc", line 47, in _getRunningVersionNameFromWinReg
  File "winVersion.pyc", line 176, in getWinVer
  File "winVersion.pyc", line 47, in _getRunningVersionNameFromWinReg
  File "winVersion.pyc", line 176, in getWinVer
  File "winVersion.pyc", line 47, in _getRunningVersionNameFromWinReg
  File "winVersion.pyc", line 176, in getWinVer
  File "winVersion.pyc", line 47, in _getRunningVersionNameFromWinReg
  File "winVersion.pyc", line 176, in getWinVer
  File "winVersion.pyc", line 47, in _getRunningVersionNameFromWinReg
  File "winVersion.pyc", line 176, in getWinVer
  File "winVersion.pyc", line 47, in _getRunningVersionNameFromWinReg
  File "garbageHandler.pyc", line 48, in _collectionCallback
Traceback (most recent call last):
  File "garbageHandler.pyc", line 46, in _collectionCallback
  File "garbageHandler.pyc", line 54, in _collectionCallback_helper
  File "threading.pyc", line 1233, in current_thread
RecursionError: maximum recursion depth exceeded while calling a Python object
```
So the same underlying cause. therefore I'm going to mark #12696 as fixing this issue.

Resolving patch:
diff --git a/source/winVersion.py b/source/winVersion.py
--- a/source/winVersion.py
+++ b/source/winVersion.py
@@ -43,9 +43,6 @@ def _getRunningVersionNameFromWinReg() -> str:
 	"""Returns the Windows release name defined in Windows Registry.
 	This is applicable on Windows 10 Version 1511 (build 10586) and later.
 	"""
-	# Release name is recorded in Windows Registry from Windows 10 Version 1511 (build 10586) onwards.
-	if getWinVer() < WIN10_1511:
-		raise RuntimeError("Release name is not recorded in Windows Registry on this version of Windows")
 	# Cache the version in use on the system.
 	with winreg.OpenKey(
 		winreg.HKEY_LOCAL_MACHINE, r"Software\Microsoft\Windows NT\CurrentVersion"
@@ -58,7 +55,9 @@ def _getRunningVersionNameFromWinReg() -> str:
 			try:
 				releaseId = winreg.QueryValueEx(currentVersion, "ReleaseID")[0]
 			except OSError:
-				releaseId = ""
+				raise RuntimeError(
+					"Release name is not recorded in Windows Registry on this version of Windows"
+				) from None
 	return releaseId
 
 
@@ -158,6 +157,7 @@ def __ge__(self, other):
 WIN11 = WIN11_21H2 = WinVersion(major=10, minor=0, build=22000)
 
 
+@functools.lru_cache(maxsize=1)
 def getWinVer():
 	"""Returns a record of current Windows version NVDA is running on.
 	"""


Test patch: