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 #ifndef DEBUG_MALLOC_RECORDDATA_H
30 #define DEBUG_MALLOC_RECORDDATA_H
31 
32 #include <stdint.h>
33 #include <pthread.h>
34 #include <unistd.h>
35 
36 #include <atomic>
37 #include <mutex>
38 #include <string>
39 
40 #include <private/bionic_macros.h>
41 
42 class RecordEntry {
43  public:
44   RecordEntry();
45   virtual ~RecordEntry() = default;
46 
47   virtual std::string GetString() const = 0;
48 
49  protected:
50   pid_t tid_;
51 
52  private:
53   DISALLOW_COPY_AND_ASSIGN(RecordEntry);
54 };
55 
56 class ThreadCompleteEntry : public RecordEntry {
57  public:
58   ThreadCompleteEntry() = default;
59   virtual ~ThreadCompleteEntry() = default;
60 
61   std::string GetString() const override;
62 
63  private:
64   DISALLOW_COPY_AND_ASSIGN(ThreadCompleteEntry);
65 };
66 
67 class AllocEntry : public RecordEntry {
68  public:
69   AllocEntry(void* pointer);
70   virtual ~AllocEntry() = default;
71 
72  protected:
73   void* pointer_;
74 
75  private:
76   DISALLOW_COPY_AND_ASSIGN(AllocEntry);
77 };
78 
79 class MallocEntry : public AllocEntry {
80  public:
81   MallocEntry(void* pointer, size_t size);
82   virtual ~MallocEntry() = default;
83 
84   std::string GetString() const override;
85 
86  protected:
87   size_t size_;
88 
89  private:
90   DISALLOW_COPY_AND_ASSIGN(MallocEntry);
91 };
92 
93 class FreeEntry : public AllocEntry {
94  public:
95   FreeEntry(void* pointer);
96   virtual ~FreeEntry() = default;
97 
98   std::string GetString() const override;
99 
100  private:
101   DISALLOW_COPY_AND_ASSIGN(FreeEntry);
102 };
103 
104 class CallocEntry : public MallocEntry {
105  public:
106   CallocEntry(void* pointer, size_t size, size_t nmemb);
107   virtual ~CallocEntry() = default;
108 
109   std::string GetString() const override;
110 
111  protected:
112   size_t nmemb_;
113 
114  private:
115   DISALLOW_COPY_AND_ASSIGN(CallocEntry);
116 };
117 
118 class ReallocEntry : public MallocEntry {
119  public:
120   ReallocEntry(void* pointer, size_t size, void* old_pointer);
121   virtual ~ReallocEntry() = default;
122 
123   std::string GetString() const override;
124 
125  protected:
126   void* old_pointer_;
127 
128  private:
129   DISALLOW_COPY_AND_ASSIGN(ReallocEntry);
130 };
131 
132 // posix_memalign, memalign, pvalloc, valloc all recorded with this class.
133 class MemalignEntry : public MallocEntry {
134  public:
135   MemalignEntry(void* pointer, size_t size, size_t alignment);
136   virtual ~MemalignEntry() = default;
137 
138   std::string GetString() const override;
139 
140  protected:
141   size_t alignment_;
142 
143  private:
144   DISALLOW_COPY_AND_ASSIGN(MemalignEntry);
145 };
146 
147 struct Config;
148 
149 class RecordData {
150  public:
151   RecordData();
152   virtual ~RecordData();
153 
154   bool Initialize(const Config& config);
155 
156   void AddEntry(const RecordEntry* entry);
157   void AddEntryOnly(const RecordEntry* entry);
158 
SetToDump()159   void SetToDump() { dump_ = true; }
160 
key()161   pthread_key_t key() { return key_; }
162 
163  private:
164   void Dump();
165 
166   std::mutex dump_lock_;
167   pthread_key_t key_;
168   const RecordEntry** entries_ = nullptr;
169   size_t num_entries_ = 0;
170   std::atomic_uint cur_index_;
171   std::atomic_bool dump_;
172   std::string dump_file_;
173 
174   DISALLOW_COPY_AND_ASSIGN(RecordData);
175 };
176 
177 #endif // DEBUG_MALLOC_RECORDDATA_H
178