1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #pragma once
30 
31 #include <pthread.h>
32 #include <stdint.h>
33 #include <unistd.h>
34 
35 #include <atomic>
36 #include <mutex>
37 #include <string>
38 
39 #include <platform/bionic/macros.h>
40 
41 class RecordEntry {
42  public:
43   RecordEntry();
44   virtual ~RecordEntry() = default;
45 
46   virtual std::string GetString() const = 0;
47 
48  protected:
49   pid_t tid_;
50 
51  private:
52   BIONIC_DISALLOW_COPY_AND_ASSIGN(RecordEntry);
53 };
54 
55 class ThreadCompleteEntry : public RecordEntry {
56  public:
57   ThreadCompleteEntry() = default;
58   virtual ~ThreadCompleteEntry() = default;
59 
60   std::string GetString() const override;
61 
62  private:
63   BIONIC_DISALLOW_COPY_AND_ASSIGN(ThreadCompleteEntry);
64 };
65 
66 class AllocEntry : public RecordEntry {
67  public:
68   explicit AllocEntry(void* pointer);
69   virtual ~AllocEntry() = default;
70 
71  protected:
72   void* pointer_;
73 
74  private:
75   BIONIC_DISALLOW_COPY_AND_ASSIGN(AllocEntry);
76 };
77 
78 class MallocEntry : public AllocEntry {
79  public:
80   MallocEntry(void* pointer, size_t size);
81   virtual ~MallocEntry() = default;
82 
83   std::string GetString() const override;
84 
85  protected:
86   size_t size_;
87 
88  private:
89   BIONIC_DISALLOW_COPY_AND_ASSIGN(MallocEntry);
90 };
91 
92 class FreeEntry : public AllocEntry {
93  public:
94   explicit FreeEntry(void* pointer);
95   virtual ~FreeEntry() = default;
96 
97   std::string GetString() const override;
98 
99  private:
100   BIONIC_DISALLOW_COPY_AND_ASSIGN(FreeEntry);
101 };
102 
103 class CallocEntry : public MallocEntry {
104  public:
105   CallocEntry(void* pointer, size_t size, size_t nmemb);
106   virtual ~CallocEntry() = default;
107 
108   std::string GetString() const override;
109 
110  protected:
111   size_t nmemb_;
112 
113  private:
114   BIONIC_DISALLOW_COPY_AND_ASSIGN(CallocEntry);
115 };
116 
117 class ReallocEntry : public MallocEntry {
118  public:
119   ReallocEntry(void* pointer, size_t size, void* old_pointer);
120   virtual ~ReallocEntry() = default;
121 
122   std::string GetString() const override;
123 
124  protected:
125   void* old_pointer_;
126 
127  private:
128   BIONIC_DISALLOW_COPY_AND_ASSIGN(ReallocEntry);
129 };
130 
131 // aligned_alloc, posix_memalign, memalign, pvalloc, valloc all recorded with this class.
132 class MemalignEntry : public MallocEntry {
133  public:
134   MemalignEntry(void* pointer, size_t size, size_t alignment);
135   virtual ~MemalignEntry() = default;
136 
137   std::string GetString() const override;
138 
139  protected:
140   size_t alignment_;
141 
142  private:
143   BIONIC_DISALLOW_COPY_AND_ASSIGN(MemalignEntry);
144 };
145 
146 class Config;
147 
148 class RecordData {
149  public:
150   RecordData();
151   virtual ~RecordData();
152 
153   bool Initialize(const Config& config);
154 
155   void AddEntry(const RecordEntry* entry);
156   void AddEntryOnly(const RecordEntry* entry);
157 
SetToDump()158   void SetToDump() { dump_ = true; }
159 
key()160   pthread_key_t key() { return key_; }
161 
162  private:
163   void Dump();
164 
165   std::mutex dump_lock_;
166   pthread_key_t key_;
167   const RecordEntry** entries_ = nullptr;
168   size_t num_entries_ = 0;
169   std::atomic_uint cur_index_;
170   std::atomic_bool dump_;
171   std::string dump_file_;
172 
173   BIONIC_DISALLOW_COPY_AND_ASSIGN(RecordData);
174 };
175