Write record allocs from interrupt handler.

There are many cases where there are no more allocations
when a dump of the record allocs might occur. Move the entries
being written to file in the interrupt handler.

Update the unit tests for this new functionality and add a new
unit test that verifies no allocations occur while the entries
are being written.

Fix the unit tests so that the record allocs files get deleted
properly.

Test: All unit tests pass.
Test: Ran 1000 iterations of unit tests to verify no flakes.
Change-Id: I20941596c1dda5a761522050dc155b06f3f3e735
diff --git a/libc/malloc_debug/RecordData.h b/libc/malloc_debug/RecordData.h
index 3d37529..43dba6a 100644
--- a/libc/malloc_debug/RecordData.h
+++ b/libc/malloc_debug/RecordData.h
@@ -29,12 +29,15 @@
 #pragma once
 
 #include <pthread.h>
+#include <signal.h>
 #include <stdint.h>
 #include <unistd.h>
 
 #include <atomic>
+#include <memory>
 #include <mutex>
 #include <string>
+#include <vector>
 
 #include <platform/bionic/macros.h>
 
@@ -43,7 +46,7 @@
   RecordEntry();
   virtual ~RecordEntry() = default;
 
-  virtual std::string GetString() const = 0;
+  virtual bool Write(int fd) const = 0;
 
  protected:
   pid_t tid_;
@@ -57,7 +60,7 @@
   ThreadCompleteEntry() = default;
   virtual ~ThreadCompleteEntry() = default;
 
-  std::string GetString() const override;
+  bool Write(int fd) const override;
 
  private:
   BIONIC_DISALLOW_COPY_AND_ASSIGN(ThreadCompleteEntry);
@@ -80,7 +83,7 @@
   MallocEntry(void* pointer, size_t size);
   virtual ~MallocEntry() = default;
 
-  std::string GetString() const override;
+  bool Write(int fd) const override;
 
  protected:
   size_t size_;
@@ -94,7 +97,7 @@
   explicit FreeEntry(void* pointer);
   virtual ~FreeEntry() = default;
 
-  std::string GetString() const override;
+  bool Write(int fd) const override;
 
  private:
   BIONIC_DISALLOW_COPY_AND_ASSIGN(FreeEntry);
@@ -105,7 +108,7 @@
   CallocEntry(void* pointer, size_t size, size_t nmemb);
   virtual ~CallocEntry() = default;
 
-  std::string GetString() const override;
+  bool Write(int fd) const override;
 
  protected:
   size_t nmemb_;
@@ -119,7 +122,7 @@
   ReallocEntry(void* pointer, size_t size, void* old_pointer);
   virtual ~ReallocEntry() = default;
 
-  std::string GetString() const override;
+  bool Write(int fd) const override;
 
  protected:
   void* old_pointer_;
@@ -134,7 +137,7 @@
   MemalignEntry(void* pointer, size_t size, size_t alignment);
   virtual ~MemalignEntry() = default;
 
-  std::string GetString() const override;
+  bool Write(int fd) const override;
 
  protected:
   size_t alignment_;
@@ -155,19 +158,18 @@
   void AddEntry(const RecordEntry* entry);
   void AddEntryOnly(const RecordEntry* entry);
 
-  void SetToDump() { dump_ = true; }
-
   pthread_key_t key() { return key_; }
 
  private:
-  void Dump();
+  static void WriteData(int, siginfo_t*, void*);
+  static RecordData* record_obj_;
 
-  std::mutex dump_lock_;
+  void WriteEntries();
+
+  std::mutex entries_lock_;
   pthread_key_t key_;
-  const RecordEntry** entries_ = nullptr;
-  size_t num_entries_ = 0;
-  std::atomic_uint cur_index_;
-  std::atomic_bool dump_;
+  std::vector<std::unique_ptr<const RecordEntry>> entries_;
+  size_t cur_index_;
   std::string dump_file_;
 
   BIONIC_DISALLOW_COPY_AND_ASSIGN(RecordData);