NativeScript / NativeScript/ios
isImplementedInClass leaks the losing sample instance on re-entrant or racing cache population
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- JavaScript
- Sterne
- 150
- Forks
- 43
- Ø Merge
- 3 T. 10 Std.
- Gemergte PRs (30 T.)
- 22
Beschreibung
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.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginnen Sie in NativeScript/runtime/Metadata.mm bei MethodMeta::isImplementedInClass und dem Kommentar, der auf dieses Issue verweist; verfolgen Sie die Befüllung von sampleInstances, die Verwendung des mutex und das Re-entrant-Verhalten von alloc. Als erledigt gilt die Aufgabe, wenn verwaiste sample instances während einer Re-entrant- oder konkurrierenden Befüllung beseitigt werden, ohne Deadlocks, unsichere Freigaben oder eine absichtliche dauerhafte Beibehaltung zu verursachen.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- cpp, objective-c
- Bereich
- mobile-dev
- Issue-Typ
- Bug
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Aktivitätsstatus
- Aktiv
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 38/100