GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — gh-152635: Raise MemoryError rather than fail assert() when the lock allocation fails in _interpchannels.create() by stestagg · Pull Request #152642 · python/cpython Conversation
|
|
All commit authors signed the Contributor License Agreement. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
now raises MemoryError Previously, an allocation failure when creating the lock for a channel in _interpchannels would trigger an assert. Caused by `handle_channel_error` being passed an error code of -1 which is only allowed if an exception has been set. (in this case, no exception was set) `channelsmod_create` now forwards the error code from `channel_create` which `handle_channel_error` already handled. Because the only way to get a -7 error code (was `ERR_CHANNEL_MUTEX_INIT`) is via an allocation failure in `PyThread_allocate_lock`, I made `handle_channel_error` raise a `MemoryError` for this case rather than a `ChannelError`. I also renamed the constant from `ERR_CHANNEL_MUTEX_INIT` to `ERR_CHANNEL_ALLOC_LOCK` to make this clearer for future changes.
…e test method to avoid import issues, improve the syntax for handling the expected MemoryError
has been moved to immediately before the _channels.create() call to ensure we correctly target the allocation failure.
|
Sorry for the force push, I didn't realise that github would do that with no warning on a simple rebase! |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| cid = None | ||
| try: | ||
| with self.assertRaises(MemoryError): | ||
| _testcapi.set_nomemory(0, 1) |
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
The required start/stop vary by platform, for example on Linux on an unpatched main I get:
$ ./python /tmp/repro.py
Traceback (most recent call last):
File "/tmp/repro.py", line 6, in <module>
cid = _channels.create()
^^^^^^^^^
MemoryError
I'm also against testing with a loop where we try various numbers.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Aah thanks, yes that's annoying, I'd hoped that there would be enough consistency for this to just work.
I noticed that gh-151239 didn't include any tests, maybe for this reason, and that the reproducer in the linked gh-150213 didn't catch this issue, I assume only because they started with n=1.
Having a for-loop over ranges in the tests seems quite comprehensive but maybe overkill for what it is?
I'd appreciate any suggestions here!
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
In general, we just don't test this due to the associated complexity.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Something went wrong when merging, but we're only bothering Terry (who can unsubscribe in the sidebar ;-) so I don't think we need to recreate. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Yeah, sorry, I'm working on it, I'm not used to this exact workflow |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
…ailues seems to be rarely done
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
To sum up my thoughts:
MemoryError should be raised where the error happens-1 with the error setERR_CHANNEL_MUTEX_INIT handling, because it will also fail with no memory when trying to create a new exception (probably)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Just set MemoryError and return directly on alloc failure, rather than go via the handler Leave existing error constant as-is for completeness Co-authored-by: sobolevn <[email protected]>
There was an error while loading. Please reload this page.
handle_channel_error
Tested locally with:
def test_lock_allocation_failure(self):
import _testcapi
for n in range(0, 100):
cid = None
try:
_testcapi.set_nomemory(n, n+1)
cid = _channels.create()
except MemoryError:
pass
finally:
_testcapi.remove_mem_hooks()
if cid is not None:
_channels.close(cid, force=True)
_channels.destroy(cid)
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
GH-152671 is a backport of this pull request to the 3.15 branch. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
GH-152672 is a backport of this pull request to the 3.14 branch. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
GH-152673 is a backport of this pull request to the 3.13 branch. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@sobolevn - Thanks for your help guiding me! |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Happy to help! Thanks for finding this bug :) |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
… `_interpchannels.create()` (GH-152642) (#152673) gh-152635: Raise MemoryError when the lock allocation fails in `_interpchannels.create()` (GH-152642) Previously, an allocation failure when creating the lock for a channel in `_interpchannels` would trigger an assert. Caused by `handle_channel_error` being passed an error code of -1 which is only allowed if an exception has been set. (in this case, no exception was set) `channelsmod_create` now forwards the error code from `channel_create` which `handle_channel_error` already handled. (cherry picked from commit b383aa6) Co-authored-by: Steve Stagg <[email protected]> Co-authored-by: sobolevn <[email protected]>
… `_interpchannels.create()` (GH-152642) (#152671) gh-152635: Raise MemoryError when the lock allocation fails in `_interpchannels.create()` (GH-152642) Previously, an allocation failure when creating the lock for a channel in `_interpchannels` would trigger an assert. Caused by `handle_channel_error` being passed an error code of -1 which is only allowed if an exception has been set. (in this case, no exception was set) `channelsmod_create` now forwards the error code from `channel_create` which `handle_channel_error` already handled. (cherry picked from commit b383aa6) Co-authored-by: Steve Stagg <[email protected]> Co-authored-by: sobolevn <[email protected]>
… `_interpchannels.create()` (GH-152642) (#152672) gh-152635: Raise MemoryError when the lock allocation fails in `_interpchannels.create()` (GH-152642) Previously, an allocation failure when creating the lock for a channel in `_interpchannels` would trigger an assert. Caused by `handle_channel_error` being passed an error code of -1 which is only allowed if an exception has been set. (in this case, no exception was set) `channelsmod_create` now forwards the error code from `channel_create` which `handle_channel_error` already handled. (cherry picked from commit b383aa6) Co-authored-by: Steve Stagg <[email protected]> Co-authored-by: sobolevn <[email protected]>
* main: (266 commits) pythongh-151626: Fix tests that fail when PYTHONPYCACHEPREFIX is set (pythonGH-151952) pythongh-152728: IDLE - move 3 toplevel fix_xyz functions to idlelb.util (python#152729) pythongh-152711: Add pythoninfo-build command to Platforms/Android (python#152713) pythongh-152715: Add pythoninfo-build command to Platforms/Apple (python#152716) pythongh-152433: Windows: enable mmapmodule for UWP (python#152473) pythongh-152433: Windows: use GetFileSizeEx instead of GetFileSize for memory mapped files (python#152383) pythonGH-81881: Raise `SpecialFileError` for sockets and devices in `shutil.copyfile` (python#142693) pythongh-152502: Detect the curses mouse interface and is_* methods portably (pythonGH-152705) pythongh-145857: Replace `DELETE_GLOBAL` with `PUSH_NULL; STORE_GLOBAL` (pythonGH-146314) pythongh-145854: Replace `DELETE_NAME` with `PUSH_NULL; STORE_NAME` (pythonGH-146006) pythongh-152680: Detect container/VM in test.pythoninfo (python#152668) pythongh-152682: Fix NULL dereference on OOM in `symtable_visit_type_param_bound_or_default` (python#152684) pythongh-151881: Skip tk_inactive negativity check on Windows (pythonGH-152683) pythongh-152546: Refactor `mappingproxy.__new__` to use `PyDictProxy_New` (python#152547) pythongh-151126: Fix a possible crash during the startup with no memory under `Py_STACKREF_DEBUG` (python#152478) pythongh-152635: Raise MemoryError when the lock allocation fails in `_interpchannels.create()` (python#152642) pythongh-151029: Fix `test_remote_exec_deleted_static_executable` on static installed builds (pythonGH-152653) pythongh-121249: Deprecate using F/D type codes in the struct module (python#152309) pythongh-152192: Fix JUMP_BACKWARD passing a truncated oparg to the jit tracer (pythonGH-152382) Don't require the `_test{internal}capi` modules in `test_monitoring.py` (python#152311) ...
| int64_t cid = channel_create(&_globals.channels, defaults); | ||
| if (cid < 0) { | ||
| (void)handle_channel_error(-1, self, cid); | ||
| (void)handle_channel_error(cid, self, cid); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
It causes a warning when compiling CPython using MSVC on Windows x64.
e.g., in GitHub Actions:
[Build CPython: Modules/_interpchannelsmodule.c#L2938]
'function': conversion from 'int64_t' to 'int', possible loss of data [D:\a\cpython\cpython\PCbuild\pythoncore.vcxproj]
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I will fix it, thanks for the report!
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.