bpo-31009: Fix support.fd_count() on Windows (#2862)
* bpo-31009: Fix support.fd_count() on Windows On Windows, test.support.fd_count() now calls msvcrt.CrtSetReportMode() to not kill the process nor log any error on stderr on os.dup(fd) if the file descriptor is invalid. * Fix for release mode
This commit is contained in:
parent
90addd6d1c
commit
302bbbe9ba
|
@ -2649,12 +2649,6 @@ def disable_faulthandler():
|
||||||
faulthandler.enable(file=fd, all_threads=True)
|
faulthandler.enable(file=fd, all_threads=True)
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
MAXFD = os.sysconf("SC_OPEN_MAX")
|
|
||||||
except Exception:
|
|
||||||
MAXFD = 256
|
|
||||||
|
|
||||||
|
|
||||||
def fd_count():
|
def fd_count():
|
||||||
"""Count the number of open file descriptors.
|
"""Count the number of open file descriptors.
|
||||||
"""
|
"""
|
||||||
|
@ -2665,16 +2659,48 @@ def fd_count():
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
count = 0
|
old_modes = None
|
||||||
for fd in range(MAXFD):
|
if sys.platform == 'win32':
|
||||||
|
# bpo-25306, bpo-31009: Call CrtSetReportMode() to not kill the process
|
||||||
|
# on invalid file descriptor if Python is compiled in debug mode
|
||||||
try:
|
try:
|
||||||
# Prefer dup() over fstat(). fstat() can require input/output
|
import msvcrt
|
||||||
# whereas dup() doesn't.
|
msvcrt.CrtSetReportMode
|
||||||
fd2 = os.dup(fd)
|
except (AttributeError, ImportError):
|
||||||
except OSError as e:
|
# no msvcrt or a release build
|
||||||
if e.errno != errno.EBADF:
|
pass
|
||||||
raise
|
|
||||||
else:
|
else:
|
||||||
os.close(fd2)
|
old_modes = {}
|
||||||
count += 1
|
for report_type in (msvcrt.CRT_WARN,
|
||||||
|
msvcrt.CRT_ERROR,
|
||||||
|
msvcrt.CRT_ASSERT):
|
||||||
|
old_modes[report_type] = msvcrt.CrtSetReportMode(report_type, 0)
|
||||||
|
|
||||||
|
MAXFD = 256
|
||||||
|
if hasattr(os, 'sysconf'):
|
||||||
|
try:
|
||||||
|
MAXFD = os.sysconf("SC_OPEN_MAX")
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
count = 0
|
||||||
|
for fd in range(MAXFD):
|
||||||
|
try:
|
||||||
|
# Prefer dup() over fstat(). fstat() can require input/output
|
||||||
|
# whereas dup() doesn't.
|
||||||
|
fd2 = os.dup(fd)
|
||||||
|
except OSError as e:
|
||||||
|
if e.errno != errno.EBADF:
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
os.close(fd2)
|
||||||
|
count += 1
|
||||||
|
finally:
|
||||||
|
if old_modes is not None:
|
||||||
|
for report_type in (msvcrt.CRT_WARN,
|
||||||
|
msvcrt.CRT_ERROR,
|
||||||
|
msvcrt.CRT_ASSERT):
|
||||||
|
msvcrt.CrtSetReportMode(report_type, old_modes[report_type])
|
||||||
|
|
||||||
return count
|
return count
|
||||||
|
|
|
@ -835,22 +835,10 @@ class ArgsTestCase(BaseTestCase):
|
||||||
import os
|
import os
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
# Issue #25306: Disable popups and logs to stderr on assertion
|
|
||||||
# failures in MSCRT
|
|
||||||
try:
|
|
||||||
import msvcrt
|
|
||||||
msvcrt.CrtSetReportMode
|
|
||||||
except (ImportError, AttributeError):
|
|
||||||
# no Windows, o release build
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]:
|
|
||||||
msvcrt.CrtSetReportMode(m, 0)
|
|
||||||
|
|
||||||
class FDLeakTest(unittest.TestCase):
|
class FDLeakTest(unittest.TestCase):
|
||||||
def test_leak(self):
|
def test_leak(self):
|
||||||
fd = os.open(__file__, os.O_RDONLY)
|
fd = os.open(__file__, os.O_RDONLY)
|
||||||
# bug: never cloes the file descriptor
|
# bug: never close the file descriptor
|
||||||
""")
|
""")
|
||||||
self.check_leak(code, 'file descriptors')
|
self.check_leak(code, 'file descriptors')
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue