Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit64856ad

Browse files
vstinnershibturn
andauthored
bpo-18174: regrtest -R 3:3 now also detects FD leak (#7409)
"python -m test --huntrleaks ..." now also checks for leak of filedescriptors.Co-Authored-By: Richard Oudkerk <shibturn@gmail.com>
1 parent2705819 commit64856ad

File tree

3 files changed

+117
-20
lines changed

3 files changed

+117
-20
lines changed

‎Lib/test/regrtest.py‎

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,37 +1416,59 @@ def run_the_test():
14161416
nwarmup,ntracked,fname=huntrleaks
14171417
fname=os.path.join(support.SAVEDCWD,fname)
14181418
repcount=nwarmup+ntracked
1419+
rc_deltas= [0]*ntracked
1420+
fd_deltas= [0]*ntracked
1421+
14191422
print>>sys.stderr,"beginning",repcount,"repetitions"
14201423
print>>sys.stderr, ("1234567890"*(repcount//10+1))[:repcount]
14211424
dash_R_cleanup(fs,ps,pic,zdc,abcs)
1425+
# initialize variables to make pyflakes quiet
1426+
rc_before=fd_before=0
14221427
foriinrange(repcount):
1423-
rc_before=sys.gettotalrefcount()
14241428
run_the_test()
14251429
sys.stderr.write('.')
14261430
dash_R_cleanup(fs,ps,pic,zdc,abcs)
14271431
rc_after=sys.gettotalrefcount()
1432+
fd_after=support.fd_count()
14281433
ifi>=nwarmup:
1429-
deltas.append(rc_after-rc_before)
1434+
rc_deltas[i-nwarmup]=rc_after-rc_before
1435+
fd_deltas[i-nwarmup]=fd_after-fd_before
1436+
rc_before=rc_after
1437+
fd_before=fd_after
14301438
print>>sys.stderr
14311439

1432-
# bpo-30776: Try to ignore false positives:
1433-
#
1434-
# [3, 0, 0]
1435-
# [0, 1, 0]
1436-
# [8, -8, 1]
1437-
#
1438-
# Expected leaks:
1439-
#
1440-
# [5, 5, 6]
1441-
# [10, 1, 1]
1442-
ifall(delta>=1fordeltaindeltas):
1443-
msg='%s leaked %s references, sum=%s'% (test,deltas,sum(deltas))
1444-
print>>sys.stderr,msg
1445-
withopen(fname,"a")asrefrep:
1446-
print>>refrep,msg
1447-
refrep.flush()
1448-
returnTrue
1449-
returnFalse
1440+
# These checkers return False on success, True on failure
1441+
defcheck_rc_deltas(deltas):
1442+
# Checker for reference counters and memomry blocks.
1443+
#
1444+
# bpo-30776: Try to ignore false positives:
1445+
#
1446+
# [3, 0, 0]
1447+
# [0, 1, 0]
1448+
# [8, -8, 1]
1449+
#
1450+
# Expected leaks:
1451+
#
1452+
# [5, 5, 6]
1453+
# [10, 1, 1]
1454+
returnall(delta>=1fordeltaindeltas)
1455+
1456+
defcheck_fd_deltas(deltas):
1457+
returnany(deltas)
1458+
1459+
failed=False
1460+
fordeltas,item_name,checkerin [
1461+
(rc_deltas,'references',check_rc_deltas),
1462+
(fd_deltas,'file descriptors',check_fd_deltas)
1463+
]:
1464+
ifchecker(deltas):
1465+
msg='%s leaked %s %s, sum=%s'% (test,deltas,item_name,sum(deltas))
1466+
print>>sys.stderr,msg
1467+
withopen(fname,"a")asrefrep:
1468+
print>>refrep,msg
1469+
refrep.flush()
1470+
failed=True
1471+
returnfailed
14501472

14511473
defdash_R_cleanup(fs,ps,pic,zdc,abcs):
14521474
importgc,copy_reg

‎Lib/test/support/__init__.py‎

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2062,6 +2062,63 @@ def _crash_python():
20622062
_testcapi._read_null()
20632063

20642064

2065+
deffd_count():
2066+
"""Count the number of open file descriptors.
2067+
"""
2068+
ifsys.platform.startswith(('linux','freebsd')):
2069+
try:
2070+
names=os.listdir("/proc/self/fd")
2071+
returnlen(names)
2072+
exceptFileNotFoundError:
2073+
pass
2074+
2075+
old_modes=None
2076+
ifsys.platform=='win32':
2077+
# bpo-25306, bpo-31009: Call CrtSetReportMode() to not kill the process
2078+
# on invalid file descriptor if Python is compiled in debug mode
2079+
try:
2080+
importmsvcrt
2081+
msvcrt.CrtSetReportMode
2082+
except (AttributeError,ImportError):
2083+
# no msvcrt or a release build
2084+
pass
2085+
else:
2086+
old_modes= {}
2087+
forreport_typein (msvcrt.CRT_WARN,
2088+
msvcrt.CRT_ERROR,
2089+
msvcrt.CRT_ASSERT):
2090+
old_modes[report_type]=msvcrt.CrtSetReportMode(report_type,0)
2091+
2092+
MAXFD=256
2093+
ifhasattr(os,'sysconf'):
2094+
try:
2095+
MAXFD=os.sysconf("SC_OPEN_MAX")
2096+
exceptOSError:
2097+
pass
2098+
2099+
try:
2100+
count=0
2101+
forfdinrange(MAXFD):
2102+
try:
2103+
# Prefer dup() over fstat(). fstat() can require input/output
2104+
# whereas dup() doesn't.
2105+
fd2=os.dup(fd)
2106+
exceptOSErrorase:
2107+
ife.errno!=errno.EBADF:
2108+
raise
2109+
else:
2110+
os.close(fd2)
2111+
count+=1
2112+
finally:
2113+
ifold_modesisnotNone:
2114+
forreport_typein (msvcrt.CRT_WARN,
2115+
msvcrt.CRT_ERROR,
2116+
msvcrt.CRT_ASSERT):
2117+
msvcrt.CrtSetReportMode(report_type,old_modes[report_type])
2118+
2119+
returncount
2120+
2121+
20652122
classSaveSignals:
20662123
"""
20672124
Save an restore signal handlers.

‎Lib/test/test_regrtest.py‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,24 @@ def test_main():
511511
""")
512512
self.check_leak(code,'references')
513513

514+
@unittest.skipUnless(Py_DEBUG,'need a debug build')
515+
deftest_huntrleaks_fd_leak(self):
516+
# test --huntrleaks for file descriptor leak
517+
code=textwrap.dedent("""
518+
import os
519+
import unittest
520+
from test import support
521+
522+
class FDLeakTest(unittest.TestCase):
523+
def test_leak(self):
524+
fd = os.open(__file__, os.O_RDONLY)
525+
# bug: never close the file descriptor
526+
527+
def test_main():
528+
support.run_unittest(FDLeakTest)
529+
""")
530+
self.check_leak(code,'file descriptors')
531+
514532
deftest_list_tests(self):
515533
# test --list-tests
516534
tests= [self.create_test()foriinrange(5)]

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2026 Movatter.jp