@@ -241,8 +241,6 @@ static LeakSuppressionContext *GetSuppressionContext() {
241
241
return suppression_ctx;
242
242
}
243
243
244
- static InternalMmapVectorNoCtor<Region> root_regions;
245
-
246
244
void InitCommonLsan () {
247
245
if (common_flags ()->detect_leaks ) {
248
246
// Initialization which can fail or print warnings should only be done if
@@ -523,15 +521,33 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
523
521
524
522
# endif // SANITIZER_FUCHSIA
525
523
526
- bool HasRootRegions () { return !root_regions.empty (); }
524
+ // A map that contains [region_begin, region_end) pairs.
525
+ using RootRegions = DenseMap<detail::DenseMapPair<uptr, uptr>, uptr>;
526
+
527
+ static RootRegions &GetRootRegionsLocked () {
528
+ global_mutex.CheckLocked ();
529
+ static RootRegions *regions = nullptr ;
530
+ alignas (RootRegions) static char placeholder[sizeof (RootRegions)];
531
+ if (!regions)
532
+ regions = new (placeholder) RootRegions ();
533
+ return *regions;
534
+ }
535
+
536
+ bool HasRootRegions () { return !GetRootRegionsLocked ().empty (); }
527
537
528
538
void ScanRootRegions (Frontier *frontier,
529
539
const InternalMmapVectorNoCtor<Region> &mapped_regions) {
530
540
if (!flags ()->use_root_regions )
531
541
return ;
532
542
543
+ InternalMmapVector<Region> regions;
544
+ GetRootRegionsLocked ().forEach ([&](const auto &kv) {
545
+ regions.push_back ({kv.first .first , kv.first .second });
546
+ return true ;
547
+ });
548
+
533
549
InternalMmapVector<Region> intersection;
534
- Intersect (mapped_regions, root_regions , intersection);
550
+ Intersect (mapped_regions, regions , intersection);
535
551
536
552
for (const Region &r : intersection) {
537
553
LOG_POINTERS (" Root region intersects with mapped region at %p-%p\n " ,
@@ -1011,7 +1027,7 @@ void __lsan_register_root_region(const void *begin, uptr size) {
1011
1027
CHECK_LT (b, e);
1012
1028
1013
1029
Lock l (&global_mutex);
1014
- root_regions. push_back ( {b, e}) ;
1030
+ ++ GetRootRegionsLocked ()[ {b, e}] ;
1015
1031
#endif // CAN_SANITIZE_LEAKS
1016
1032
}
1017
1033
@@ -1021,18 +1037,14 @@ void __lsan_unregister_root_region(const void *begin, uptr size) {
1021
1037
uptr b = reinterpret_cast <uptr>(begin);
1022
1038
uptr e = b + size;
1023
1039
CHECK_LT (b, e);
1040
+ VReport (1 , " Unregistered root region at %p of size %zu\n " , begin, size);
1024
1041
1025
1042
{
1026
1043
Lock l (&global_mutex);
1027
- for (uptr i = 0 ; i < root_regions.size (); i++) {
1028
- Region region = root_regions[i];
1029
- if (region.begin == b && region.end == e) {
1030
- uptr last_index = root_regions.size () - 1 ;
1031
- root_regions[i] = root_regions[last_index];
1032
- root_regions.pop_back ();
1033
- VReport (1 , " Unregistered root region at %p of size %zu\n " , begin, size);
1034
- return ;
1035
- }
1044
+ if (auto *f = GetRootRegionsLocked ().find ({b, e})) {
1045
+ if (--(f->second ) == 0 )
1046
+ GetRootRegionsLocked ().erase (f);
1047
+ return ;
1036
1048
}
1037
1049
}
1038
1050
Report (
0 commit comments