Memory leak: the shared `validation_aborted_error` keeps every traceback it is raised through
Bewertung
- Schwierigkeit
- 2/5
- Geschätzter Aufwand
- 1-3 Stunden
- Anfängerfreundlichkeit
- 78/100
Rechercherichtung
Beginne in graphql/validation/validate.py, wo der gemeinsame validation_aborted_error ausgelöst wird, und lies nach, wie validate() das Erreichen von max_errors behandelt. Die Reproduktion im Issue zeigt den Traceback und das Speicherwachstum; führe sie vor und nach der Änderung aus, um zu bestätigen, dass wiederholte Aufrufe keine anwachsenden Tracebacks mehr behalten. Fertig ist es, wenn jeder Validierungsaufruf seinen eigenen Fehler auslöst und das Speicherwachstum sich stabilisiert.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Since aab6d50 (first released in 3.3.0a3), validate() raises one shared, module-level ValidationAbortedError once max_errors is reached. When an existing exception object is raised again, Python adds the new frames to its existing __traceback__. So every aborted validation lengthens the singleton's traceback, and that traceback keeps those frames, and with them each request's document and validation context, alive for the life of the process.
Any client can trigger this by sending a query with more than 100 validation errors. In a long-running server, memory grows with every such request.
Reproduction (graphql-core 3.3.0, CPython 3.12):
import gc, tracemalloc
from graphql import build_schema, parse, validate
from graphql.validation.validate import validation_aborted_error
schema = build_schema("type Query { a: Int }")
document = parse("{ " + " ".join(f"f{i}" for i in range(101)) + " }")
tracemalloc.start()
validate(schema, document)
gc.collect()
base = tracemalloc.get_traced_memory()[0]
for _ in range(200):
validate(schema, document)
gc.collect()
tb, n = validation_aborted_error.__traceback__, 0
while tb:
n, tb = n + 1, tb.tb_next
print(n, (tracemalloc.get_traced_memory()[0] - base) // 1024, "KiB")
Result:
| Repeated calls | Traceback entries | Memory retained |
|---|---|---|
| 1 | 16 | 147 KiB |
| 10 | 88 | 1,389 KiB |
| 100 | 808 | 12,549 KiB |
| 200 | 1,608 | 24,820 KiB |
That is about 124 KiB more per aborted validation, with no upper limit. The same script on 3.2.13, which creates a new error each time, levels off at about 259 KiB.
Suggested fix: create a new ValidationAbortedError on each validate() call instead of reusing the module-level instance. Clearing __traceback__ before each raise would also work, but every caller's error list would still share one mutable error object.
- Vorherrschende Sprache
- Python
- Sterne
- 532
- Forks
- 154
- Ø Merge
- 1 T. 9 Std.
- Gemergte PRs (30 T.)
- 6
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Hat eine Pull-Request-Vorlage
- Kein Beitragsleitfaden
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus graphql-python/graphql-core
-
`collect_subfields` memoization keyed on `id()` of `FieldDetails` that are not kept alive returns another field's subfieldsEvtl. vergeben @jadenfix hat das vor 5 Tagen übernommen. Offen
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 72/100
graphql-python/graphql-core#284 · 1 Kommentar ·
-
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 35/100
graphql-python/graphql-core#278 ·
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 45/100
graphql-python/graphql-core#257 ·
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 35/100
graphql-python/graphql-core#223 · 1 Kommentar ·
-
documentation good first issue
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 35/100
graphql-python/graphql-core#220 · 4 Kommentare ·
Alle Issues in graphql-python/graphql-core
Ähnliche Issues
-
Schwierigkeit 1/5 1-3 Stunden Anfängerfreundlichkeit 85/100
WLAN-Pi/wlanpi-profiler#341 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 67/100
roman-corgi/ctc-dip#160 ·
Maintainer antworten meist innerhalb von 1 Tag
-
type-bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
Maintainer antworten meist innerhalb von 1 Tag
-
render_findings.py reads and writes in the host's default encoding, so findings.html breaks on a cp1252 Windows hostEvtl. vergeben @Aaqibhafeezkhan hat das heute übernommen. Offenbug good first issue mentored python size: XS up-for-grabs
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
dheerajjha/mcp-migrate#366 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
Maintainer antworten meist innerhalb von 1 Tag