Skip to content

Commit a3c2940

Browse files
alexmalyshevmeta-codesync[bot]
authored andcommitted
bugfix: Fix temp file resource leak in find_missing.py
Summary: Both `find_defs()` and `find_decls()` create temporary pattern files in /tmp using a predictable name with `random.randint(0, 1024)` but never clean them up after use. This causes temp file accumulation and also risks collisions due to the small random range (only 1024 possible filenames). Replaced manual temp file creation with `tempfile.NamedTemporaryFile` for unique naming, and added `try/finally` blocks to ensure the files are always cleaned up. Also removed the now-unused `random` import. Reviewed By: yoney Differential Revision: D99294378 fbshipit-source-id: e7d194d258ff97b51587dc456dcfa16d5dbc9df7
1 parent bbf3e7f commit a3c2940

1 file changed

Lines changed: 44 additions & 34 deletions

File tree

cinderx/UpstreamBorrow/find_missing.py

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
import json
1414
import os
1515
import os.path
16-
import random
1716
import subprocess
1817
import sys
18+
import tempfile
1919
from collections import defaultdict
2020
from typing import Iterable
2121

@@ -82,24 +82,29 @@ def find_defs(syms: Iterable[str]) -> dict[str, list[str]]:
8282
# so we can search for "^symbol" to distinguish definitions from function
8383
# calls.
8484

85-
patfile = "/tmp/patterns-" + str(random.randint(0, 1024))
86-
with open(patfile, "w") as f:
85+
with tempfile.NamedTemporaryFile(
86+
mode="w", suffix=".txt", prefix="patterns_", delete=False
87+
) as f:
88+
patfile = f.name
8789
for sym in syms:
8890
f.write(f"^{sym}\\b\n")
89-
# We need to grep over the cpython base dir
90-
path = os.path.join(get_fbsource_root(), "third-party/python/3.12")
91-
ret = run(["grep", "-oHR", "-f", patfile, path])
92-
out = defaultdict(list)
93-
seen = set() # make sure each symbol has a single definition
94-
for line in ret.strip().split("\n"):
95-
file, sym = line.split(":")
96-
if not file.endswith(".c"):
97-
continue
98-
if sym in seen:
99-
raise RuntimeError(f"Multiple definitions found for {sym}")
100-
seen.add(sym)
101-
out[file.lstrip("./")].append(sym)
102-
return out
91+
try:
92+
# We need to grep over the cpython base dir
93+
path = os.path.join(get_fbsource_root(), "third-party/python/3.12")
94+
ret = run(["grep", "-oHR", "-f", patfile, path])
95+
out = defaultdict(list)
96+
seen = set() # make sure each symbol has a single definition
97+
for line in ret.strip().split("\n"):
98+
file, sym = line.split(":")
99+
if not file.endswith(".c"):
100+
continue
101+
if sym in seen:
102+
raise RuntimeError(f"Multiple definitions found for {sym}")
103+
seen.add(sym)
104+
out[file.lstrip("./")].append(sym)
105+
return out
106+
finally:
107+
os.unlink(patfile)
103108

104109

105110
def find_decls(syms: Iterable[str]) -> dict[str, list[int]]:
@@ -110,25 +115,30 @@ def find_decls(syms: Iterable[str]) -> dict[str, list[int]]:
110115
# with a pattern file. If this is an issue, modify the pattern below to use
111116
# grep character classes instead.
112117

113-
patfile = "/tmp/patterns-" + str(random.randint(0, 1024))
114-
with open(patfile, "w") as f:
118+
with tempfile.NamedTemporaryFile(
119+
mode="w", suffix=".txt", prefix="patterns_", delete=False
120+
) as f:
121+
patfile = f.name
115122
for sym in syms:
116123
f.write(rf"^(\w[\w\s*]*)?\b{sym}\b" + "\n")
117-
# We need to grep over the cpython base dir
118-
path = os.path.join(get_fbsource_root(), "third-party/python/3.12/Include")
119-
ret = run(["rg", "-n", "-f", patfile, path])
120-
if not ret:
121-
# No missing symbols found
122-
return {}
123-
out = defaultdict(list)
124-
for line in ret.strip().split("\n"):
125-
file, lineno, decl = line.split(":", 3)
126-
if not file.endswith(".h"):
127-
continue
128-
if decl.startswith(" ") or decl.startswith("PyAPI_"):
129-
continue
130-
out[file].append(int(lineno))
131-
return out
124+
try:
125+
# We need to grep over the cpython base dir
126+
path = os.path.join(get_fbsource_root(), "third-party/python/3.12/Include")
127+
ret = run(["rg", "-n", "-f", patfile, path])
128+
if not ret:
129+
# No missing symbols found
130+
return {}
131+
out = defaultdict(list)
132+
for line in ret.strip().split("\n"):
133+
file, lineno, decl = line.split(":", 3)
134+
if not file.endswith(".h"):
135+
continue
136+
if decl.startswith(" ") or decl.startswith("PyAPI_"):
137+
continue
138+
out[file].append(int(lineno))
139+
return out
140+
finally:
141+
os.unlink(patfile)
132142

133143

134144
def find_missing_symbols() -> set[str]:

0 commit comments

Comments
 (0)