Imported Scudo Standalone changes:

  - f7b1489ffc5106aff3135b3ed664c99cf9a57481 [scudo][standalone] Get statistics in a char buffer by Kostya Kortchinsky <kostyak@google.com>
  - cf25242daaf876085f6f665c26fa3aa3cd502040 scudo: Update TLS_SLOT_SANITIZER value. by Peter Collingbourne <peter@pcc.me.uk>

GitOrigin-RevId: cf25242daaf876085f6f665c26fa3aa3cd502040
Change-Id: Ibabed6e73d107acae41364bdd6d23ca064e130be
diff --git a/standalone/primary64.h b/standalone/primary64.h
index f56387b..8f443ea 100644
--- a/standalone/primary64.h
+++ b/standalone/primary64.h
@@ -147,7 +147,7 @@
     }
   }
 
-  void printStats() const {
+  void getStats(ScopedString *Str) const {
     // TODO(kostyak): get the RSS per region.
     uptr TotalMapped = 0;
     uptr PoppedBlocks = 0;
@@ -159,12 +159,13 @@
       PoppedBlocks += Region->Stats.PoppedBlocks;
       PushedBlocks += Region->Stats.PushedBlocks;
     }
-    Printf("Stats: Primary64: %zuM mapped (%zuM rss) in %zu allocations; "
-           "remains %zu\n",
-           TotalMapped >> 20, 0, PoppedBlocks, PoppedBlocks - PushedBlocks);
+    Str->append("Stats: SizeClassAllocator64: %zuM mapped (%zuM rss) in %zu "
+                "allocations; remains %zu\n",
+                TotalMapped >> 20, 0, PoppedBlocks,
+                PoppedBlocks - PushedBlocks);
 
     for (uptr I = 0; I < NumClasses; I++)
-      printStats(I, 0);
+      getStats(Str, I, 0);
   }
 
   uptr releaseToOS() {
@@ -269,10 +270,12 @@
       if (UNLIKELY(RegionBase + MappedUser + UserMapSize > RegionSize)) {
         if (!Region->Exhausted) {
           Region->Exhausted = true;
-          printStats();
-          Printf(
+          ScopedString Str(1024);
+          getStats(&Str);
+          Str.append(
               "Scudo OOM: The process has Exhausted %zuM for size class %zu.\n",
               RegionSize >> 20, Size);
+          Str.output();
         }
         return nullptr;
       }
@@ -322,21 +325,21 @@
     return B;
   }
 
-  void printStats(uptr ClassId, uptr Rss) const {
+  void getStats(ScopedString *Str, uptr ClassId, uptr Rss) const {
     RegionInfo *Region = getRegionInfo(ClassId);
     if (Region->MappedUser == 0)
       return;
     const uptr InUse = Region->Stats.PoppedBlocks - Region->Stats.PushedBlocks;
     const uptr TotalChunks = Region->AllocatedUser / getSizeByClassId(ClassId);
-    Printf("%s %02zu (%6zu): mapped: %6zuK popped: %7zu pushed: %7zu inuse: "
-           "%6zu total: %6zu rss: %6zuK releases: %6zu last released: %6zuK "
-           "region: 0x%zx (0x%zx)\n",
-           Region->Exhausted ? "F" : " ", ClassId, getSizeByClassId(ClassId),
-           Region->MappedUser >> 10, Region->Stats.PoppedBlocks,
-           Region->Stats.PushedBlocks, InUse, TotalChunks, Rss >> 10,
-           Region->ReleaseInfo.RangesReleased,
-           Region->ReleaseInfo.LastReleasedBytes >> 10, Region->RegionBeg,
-           getRegionBaseByClassId(ClassId));
+    Str->append("%s %02zu (%6zu): mapped: %6zuK popped: %7zu pushed: %7zu "
+                "inuse: %6zu total: %6zu rss: %6zuK releases: %6zu last "
+                "released: %6zuK region: 0x%zx (0x%zx)\n",
+                Region->Exhausted ? "F" : " ", ClassId,
+                getSizeByClassId(ClassId), Region->MappedUser >> 10,
+                Region->Stats.PoppedBlocks, Region->Stats.PushedBlocks, InUse,
+                TotalChunks, Rss >> 10, Region->ReleaseInfo.RangesReleased,
+                Region->ReleaseInfo.LastReleasedBytes >> 10, Region->RegionBeg,
+                getRegionBaseByClassId(ClassId));
   }
 
   NOINLINE uptr releaseToOSMaybe(RegionInfo *Region, uptr ClassId,