AbsolutePath.ReadKind allocates a new 16 KiB buffer per directory on Windows: the pooled buffer is not returned on failure
Les mainteneurs répondent en général sous 6 jours
Évaluation
- Difficulté
- 2/5
- Temps estimé
- 1-3 heures
- Accessibilité débutants
- 78/100
Piste de recherche
Commencez par TruePath/DiskUtils.cs, en particulier par TryGetReparseDataBuffer autour de la location via ArrayPool<byte>.Shared et de la restitution en cas d’échec de DeviceIoControl ; suivez ensuite comment AbsolutePath.ReadKind() l’appelle sous Windows. Reproduisez l’allocation signalée avec la boucle fournie et vérifiez les tests existants pour les types de chemins Windows. Le travail est terminé lorsque les répertoires ordinaires réutilisent le tampon loué ou évitent de le louer, et que l’allocation diminue sans modifier les résultats pour les points de réanalyse.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
AbsolutePath.ReadKind() on Windows ends up in DiskUtils.TryGetReparseDataBuffer for every directory. The method rents a 16 KiB buffer from ArrayPool<byte>.Shared, but returns it only on the success path. For anything that isn't a reparse point (i.e. almost every directory), DeviceIoControl(FSCTL_GET_REPARSE_POINT) fails, the method does an early return null, and the rented buffer is dropped. Every call then allocates a fresh 16 KiB array instead of reusing the pooled one.
Measured on ReadKind() (allocated bytes per call):
- a file: 41 B
- a directory: 16,480 B
Repro:
var dir = new AbsolutePath(Path.GetTempPath());
for (int i = 0; i < 100; i++) dir.ReadKind(); // warmup
var before = GC.GetAllocatedBytesForCurrentThread();
for (int i = 0; i < 10_000; i++) dir.ReadKind();
Console.WriteLine((GC.GetAllocatedBytesForCurrentThread() - before) / 10_000); // ~16480
This is not a correctness failure, but it defeats the pool and produces a lot of garbage in directory-walking code.
Recommendations
- Return the buffer on the
DeviceIoControlfailure path too.DeviceIoControlhas finished writing by then, so this is safe (the "abandon rather than return" advice only applies to buffers that might still be in use). - Alternatively, rent the buffer only when it is actually needed:
ReadKind()already reads the attributes, and a junction always hasFileAttributes.ReparsePointset, so the reparse query can be skipped for everything else. (A 16 KiBstackallocis not a good replacement for the pool: it is well above the ~1 KB guideline for stack buffers.)
- Langage dominant
- C#
- Étoiles
- 109
- Forks
- 26
- Merge moyen
- 5 j 13 h
- PR mergées (30 j)
- 9
Préparer son environnement
- Aucun Dockerfile ni fichier Docker Compose
- Aucun modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de ForNeVeR/TruePath
-
enhancement good first issue help wanted
Difficulté 2/5 1-3 heures Accessibilité débutants 68/100
ForNeVeR/TruePath#165 · 2 commentaires ·
Les mainteneurs répondent en général sous 6 jours
-
bug help wanted
Les mainteneurs répondent en général sous 6 jours
-
enhancement help wanted
Les mainteneurs répondent en général sous 6 jours
-
DiskUtils.TryGetReparseDataBuffer reads a struct from unzeroed pooled memory and ignores the number of bytes returnedPeut-être pris @bfs2021 l’a pris il y a 4 jours. Ouvertebug good first issue help wanted
Difficulté 3/5 Une demi-journée Accessibilité débutants 57/100
Les mainteneurs répondent en général sous 6 jours
-
enhancement help wanted
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 35/100
Les mainteneurs répondent en général sous 6 jours
Toutes les issues de ForNeVeR/TruePath
Issues similaires
-
area-multitenancy area-security p1-recommended priority-high technical-debt
Difficulté 2/5 Moins d'une heure Accessibilité débutants 75/100
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 65/100
-
help wanted needs-unity ready for a contributor
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
eyalgolan/statecraft-israel#1542 ·
Les mainteneurs répondent en général sous 1 jour
-
kind/enhancement Provider Upgrade pulumi/pulumi-azure R1 Task
Difficulté 2/5 1-3 heures Accessibilité débutants 65/100
pulumi/pulumi-azure#3669 ·
-
[BUG] FromCString causes 1 byte OOB read in native codePeut-être pris Une pull request liée à cette issue est ouverte ou déjà fusionnée. Ouvertetype/bug
Difficulté 2/5 1-3 heures Accessibilité débutants 68/100
Les mainteneurs répondent en général sous 1 jour