NativeScript / NativeScript/ios
isImplementedInClass leaks the losing sample instance on re-entrant or racing cache population
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- JavaScript
- Estrellas
- 150
- Forks
- 43
- Merge medio
- 3 d 10 h
- PR fusionados (30 d)
- 22
Descripción
Problem
MethodMeta::isImplementedInClass (NativeScript/runtime/Metadata.mm) keeps a process-wide cache of [klass alloc]-created sample instances used to answer respondsToSelector: for classes whose alloc returns a different class or which forward messages. The cache is populated like this:
[klass alloc]runs outside the mutex — deliberately, becausealloccan trigger+initialize, which may run arbitrary code that re-enters this method (holding the lock would deadlock).- The lock is then taken and
sampleInstances.emplace(klass, instance)inserts.
When the emplace loses — the re-entrant call already populated the entry for the same class, or another thread raced — the freshly allocated instance is abandoned: one leaked object per lost race (Instruments shows these as e.g. a leaked UIAlertView / NSURLSessionConfiguration attributed to isImplementedInClass). The count varies run to run since it is timing-dependent.
Why the obvious fixes don't work
- Releasing the loser is unsafe: the instance is
alloc'd but neverinit'd, so-releaseruns-deallocagainst zero-filled ivars of an arbitrary framework class, on whatever thread the probe ran on (it demonstrably runs on worker threads). Benign for most classes, but a-deallocthat doesCFRelease/dispatch_releaseon a zero ivar traps, and UIKit teardown off the main thread is asserting territory. - Holding the lock across
allocdeadlocks via the+initializere-entry described above. - Parking losers in a static container merely converts the unreachable leak into intentional perpetual retention — it silences Instruments without reclaiming anything (tried and reverted in #458).
Potential solutions
- A re-entrancy-aware locking scheme (recursive mutex, or a reader/writer arrangement) so the populate path can be made atomic with respect to re-entrant probes without deadlocking through
+initialize. - Reuse already-
alloc-ed objects: when a sample for that Class is requested (or something else calls[thatClass alloc]through the runtime), hand out / consume the cached instance instead of allocating another, so a losing instance gets used rather than abandoned.
The leak site carries a comment pointing at this issue.
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Comienza en NativeScript/runtime/Metadata.mm, en MethodMeta::isImplementedInClass y en el comentario que apunta a este issue; sigue la población de sampleInstances, el uso del mutex y el comportamiento re-entrant de alloc. Se considera terminado cuando se eliminan las sample instances abandonadas durante una población re-entrant o con condiciones de carrera, sin provocar deadlocks, liberaciones inseguras ni una retención perpetua intencionada.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- cpp, objective-c
- Área
- mobile-dev
- Tipo de issue
- Error
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Estado de actividad
- Activo
- Claridad
- Bastante claro
- Aptitud para principiantes
- 38/100