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);