1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdint.h>
18 #include <unistd.h>
19
20 #include <string>
21
22 #include <gtest/gtest.h>
23
24 #include <android-base/file.h>
25 #include <memory_trace/MemoryTrace.h>
26
TEST(MemoryTraceReadTest,malloc_valid)27 TEST(MemoryTraceReadTest, malloc_valid) {
28 std::string line = "1234: malloc 0xabd0000 20";
29 memory_trace::Entry entry{.start_ns = 1, .end_ns = 1};
30 std::string error;
31 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
32 EXPECT_EQ(memory_trace::MALLOC, entry.type);
33 EXPECT_EQ(1234, entry.tid);
34 EXPECT_EQ(0xabd0000U, entry.ptr);
35 EXPECT_EQ(20U, entry.size);
36 EXPECT_EQ(0U, entry.u.align);
37 EXPECT_EQ(0U, entry.start_ns);
38 EXPECT_EQ(0U, entry.end_ns);
39
40 line += " 1000 1020";
41 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
42 EXPECT_EQ(memory_trace::MALLOC, entry.type);
43 EXPECT_EQ(1234, entry.tid);
44 EXPECT_EQ(0xabd0000U, entry.ptr);
45 EXPECT_EQ(20U, entry.size);
46 EXPECT_EQ(0U, entry.u.align);
47 EXPECT_EQ(1000U, entry.start_ns);
48 EXPECT_EQ(1020U, entry.end_ns);
49 }
50
TEST(MemoryTraceReadTest,malloc_invalid)51 TEST(MemoryTraceReadTest, malloc_invalid) {
52 // Missing size
53 std::string line = "1234: malloc 0xabd0000";
54 memory_trace::Entry entry;
55 std::string error;
56 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
57 EXPECT_EQ("Failed to read malloc data: 1234: malloc 0xabd0000", error);
58
59 // Missing pointer and size
60 line = "1234: malloc";
61 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
62 EXPECT_EQ("Failed to process line: 1234: malloc", error);
63
64 // Missing end time
65 line = "1234: malloc 0xabd0000 10 100";
66 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
67 EXPECT_EQ("Failed to read timestamps: 1234: malloc 0xabd0000 10 100", error);
68 }
69
TEST(MemoryTraceReadTest,free_valid)70 TEST(MemoryTraceReadTest, free_valid) {
71 std::string line = "1235: free 0x5000";
72 memory_trace::Entry entry{.start_ns = 1, .end_ns = 1};
73 std::string error;
74 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
75 EXPECT_EQ(memory_trace::FREE, entry.type);
76 EXPECT_EQ(1235, entry.tid);
77 EXPECT_EQ(0x5000U, entry.ptr);
78 EXPECT_EQ(0U, entry.size);
79 EXPECT_EQ(0U, entry.u.align);
80 EXPECT_EQ(0U, entry.start_ns);
81 EXPECT_EQ(0U, entry.end_ns);
82
83 line += " 540 2000";
84 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
85 EXPECT_EQ(memory_trace::FREE, entry.type);
86 EXPECT_EQ(1235, entry.tid);
87 EXPECT_EQ(0x5000U, entry.ptr);
88 EXPECT_EQ(0U, entry.size);
89 EXPECT_EQ(0U, entry.u.align);
90 EXPECT_EQ(540U, entry.start_ns);
91 EXPECT_EQ(2000U, entry.end_ns);
92 }
93
TEST(MemoryTraceReadTest,free_invalid)94 TEST(MemoryTraceReadTest, free_invalid) {
95 // Missing pointer
96 std::string line = "1234: free";
97 memory_trace::Entry entry;
98 std::string error;
99 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
100 EXPECT_EQ("Failed to process line: 1234: free", error);
101
102 // Missing end time
103 line = "1234: free 0x100 100";
104 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
105 EXPECT_EQ("Failed to read timestamps: 1234: free 0x100 100", error);
106 }
107
TEST(MemoryTraceReadTest,calloc_valid)108 TEST(MemoryTraceReadTest, calloc_valid) {
109 std::string line = "1236: calloc 0x8000 50 30";
110 memory_trace::Entry entry{.start_ns = 1, .end_ns = 1};
111 std::string error;
112 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
113 EXPECT_EQ(memory_trace::CALLOC, entry.type);
114 EXPECT_EQ(1236, entry.tid);
115 EXPECT_EQ(0x8000U, entry.ptr);
116 EXPECT_EQ(30U, entry.size);
117 EXPECT_EQ(50U, entry.u.n_elements);
118 EXPECT_EQ(0U, entry.start_ns);
119 EXPECT_EQ(0U, entry.end_ns);
120
121 line += " 700 1000";
122 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
123 EXPECT_EQ(memory_trace::CALLOC, entry.type);
124 EXPECT_EQ(1236, entry.tid);
125 EXPECT_EQ(0x8000U, entry.ptr);
126 EXPECT_EQ(30U, entry.size);
127 EXPECT_EQ(50U, entry.u.n_elements);
128 EXPECT_EQ(700U, entry.start_ns);
129 EXPECT_EQ(1000U, entry.end_ns);
130 }
131
TEST(MemoryTraceReadTest,calloc_invalid)132 TEST(MemoryTraceReadTest, calloc_invalid) {
133 // Missing number of elements
134 std::string line = "1236: calloc 0x8000 50";
135 memory_trace::Entry entry;
136 std::string error;
137 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
138 EXPECT_EQ("Failed to read calloc data: 1236: calloc 0x8000 50", error);
139
140 // Missing size and number of elements
141 line = "1236: calloc 0x8000";
142 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
143 EXPECT_EQ("Failed to read calloc data: 1236: calloc 0x8000", error);
144
145 // Missing pointer, size and number of elements
146 line = "1236: calloc";
147 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
148 EXPECT_EQ("Failed to process line: 1236: calloc", error);
149
150 // Missing end time
151 line = "1236: calloc 0x8000 50 20 100";
152 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
153 EXPECT_EQ("Failed to read timestamps: 1236: calloc 0x8000 50 20 100", error);
154 }
155
TEST(MemoryTraceReadTest,realloc_valid)156 TEST(MemoryTraceReadTest, realloc_valid) {
157 std::string line = "1237: realloc 0x9000 0x4000 80";
158 memory_trace::Entry entry{.start_ns = 1, .end_ns = 1};
159 std::string error;
160 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
161 EXPECT_EQ(memory_trace::REALLOC, entry.type);
162 EXPECT_EQ(1237, entry.tid);
163 EXPECT_EQ(0x9000U, entry.ptr);
164 EXPECT_EQ(80U, entry.size);
165 EXPECT_EQ(0x4000U, entry.u.old_ptr);
166 EXPECT_EQ(0U, entry.start_ns);
167 EXPECT_EQ(0U, entry.end_ns);
168
169 line += " 3999 10020";
170 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
171 EXPECT_EQ(memory_trace::REALLOC, entry.type);
172 EXPECT_EQ(1237, entry.tid);
173 EXPECT_EQ(0x9000U, entry.ptr);
174 EXPECT_EQ(80U, entry.size);
175 EXPECT_EQ(0x4000U, entry.u.old_ptr);
176 EXPECT_EQ(3999U, entry.start_ns);
177 EXPECT_EQ(10020U, entry.end_ns);
178 }
179
TEST(MemoryTraceReadTest,realloc_invalid)180 TEST(MemoryTraceReadTest, realloc_invalid) {
181 // Missing size
182 std::string line = "1237: realloc 0x9000 0x4000";
183 memory_trace::Entry entry;
184 std::string error;
185 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
186 EXPECT_EQ("Failed to read realloc data: 1237: realloc 0x9000 0x4000", error);
187
188 // Missing size and old pointer
189 line = "1237: realloc 0x9000";
190 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
191 EXPECT_EQ("Failed to read realloc data: 1237: realloc 0x9000", error);
192
193 // Missing new pointer, size and old pointer
194 line = "1237: realloc";
195 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
196 EXPECT_EQ("Failed to process line: 1237: realloc", error);
197
198 // Missing end time
199 line = "1237: realloc 0x9000 0x4000 10 500";
200 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
201 EXPECT_EQ("Failed to read timestamps: 1237: realloc 0x9000 0x4000 10 500", error);
202 }
203
TEST(MemoryTraceReadTest,memalign_valid)204 TEST(MemoryTraceReadTest, memalign_valid) {
205 std::string line = "1238: memalign 0xa000 16 89";
206 memory_trace::Entry entry{.start_ns = 1, .end_ns = 1};
207 std::string error;
208 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
209 EXPECT_EQ(memory_trace::MEMALIGN, entry.type);
210 EXPECT_EQ(1238, entry.tid);
211 EXPECT_EQ(0xa000U, entry.ptr);
212 EXPECT_EQ(89U, entry.size);
213 EXPECT_EQ(16U, entry.u.align);
214 EXPECT_EQ(0U, entry.start_ns);
215 EXPECT_EQ(0U, entry.end_ns);
216
217 line += " 900 1000";
218 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
219 EXPECT_EQ(memory_trace::MEMALIGN, entry.type);
220 EXPECT_EQ(1238, entry.tid);
221 EXPECT_EQ(0xa000U, entry.ptr);
222 EXPECT_EQ(89U, entry.size);
223 EXPECT_EQ(16U, entry.u.align);
224 EXPECT_EQ(900U, entry.start_ns);
225 EXPECT_EQ(1000U, entry.end_ns);
226 }
227
TEST(MemoryTraceReadTest,memalign_invalid)228 TEST(MemoryTraceReadTest, memalign_invalid) {
229 // Missing size
230 std::string line = "1238: memalign 0xa000 16";
231 memory_trace::Entry entry;
232 std::string error;
233 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
234 EXPECT_EQ("Failed to read memalign data: 1238: memalign 0xa000 16", error);
235
236 // Missing alignment and size
237 line = "1238: memalign 0xa000";
238 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
239 EXPECT_EQ("Failed to read memalign data: 1238: memalign 0xa000", error);
240
241 // Missing pointer, alignment and size
242 line = "1238: memalign";
243 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
244 EXPECT_EQ("Failed to process line: 1238: memalign", error);
245
246 // Missing end time
247 line = "1238: memalign 0xa000 16 10 800";
248 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
249 EXPECT_EQ("Failed to read timestamps: 1238: memalign 0xa000 16 10 800", error);
250 }
251
TEST(MemoryTraceReadTest,thread_done_valid)252 TEST(MemoryTraceReadTest, thread_done_valid) {
253 std::string line = "1239: thread_done 0x0";
254 memory_trace::Entry entry{.start_ns = 1, .end_ns = 1};
255 std::string error;
256 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
257 EXPECT_EQ(memory_trace::THREAD_DONE, entry.type);
258 EXPECT_EQ(1239, entry.tid);
259 EXPECT_EQ(0U, entry.ptr);
260 EXPECT_EQ(0U, entry.size);
261 EXPECT_EQ(0U, entry.u.old_ptr);
262 EXPECT_EQ(0U, entry.start_ns);
263 EXPECT_EQ(0U, entry.end_ns);
264
265 line += " 290";
266 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
267 EXPECT_EQ(memory_trace::THREAD_DONE, entry.type);
268 EXPECT_EQ(1239, entry.tid);
269 EXPECT_EQ(0U, entry.ptr);
270 EXPECT_EQ(0U, entry.size);
271 EXPECT_EQ(0U, entry.u.old_ptr);
272 EXPECT_EQ(0U, entry.start_ns);
273 EXPECT_EQ(290U, entry.end_ns);
274 }
275
TEST(MemoryTraceReadTest,thread_done_invalid)276 TEST(MemoryTraceReadTest, thread_done_invalid) {
277 // Missing pointer
278 std::string line = "1240: thread_done";
279 memory_trace::Entry entry;
280 std::string error;
281 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
282 EXPECT_EQ("Failed to process line: 1240: thread_done", error);
283 }
284
285 class MemoryTraceOutputTest : public ::testing::Test {
286 protected:
SetUp()287 void SetUp() override {
288 tmp_file_ = new TemporaryFile();
289 ASSERT_TRUE(tmp_file_->fd != -1);
290 }
291
TearDown()292 void TearDown() override { delete tmp_file_; }
293
WriteAndReadString(const memory_trace::Entry & entry,std::string & str)294 void WriteAndReadString(const memory_trace::Entry& entry, std::string& str) {
295 EXPECT_EQ(lseek(tmp_file_->fd, 0, SEEK_SET), 0);
296 EXPECT_TRUE(memory_trace::WriteEntryToFd(tmp_file_->fd, entry));
297 EXPECT_EQ(lseek(tmp_file_->fd, 0, SEEK_SET), 0);
298 EXPECT_TRUE(android::base::ReadFdToString(tmp_file_->fd, &str));
299 }
300
WriteAndGetString(const memory_trace::Entry & entry)301 std::string WriteAndGetString(const memory_trace::Entry& entry) {
302 std::string str;
303 WriteAndReadString(entry, str);
304 return str;
305 }
306
VerifyEntry(const memory_trace::Entry & entry,const std::string expected)307 void VerifyEntry(const memory_trace::Entry& entry, const std::string expected) {
308 EXPECT_EQ(expected, memory_trace::CreateStringFromEntry(entry));
309 // The WriteEntryToFd always appends a newline, but string creation doesn't.
310 EXPECT_EQ(expected + "\n", WriteAndGetString(entry));
311 }
312
313 TemporaryFile* tmp_file_ = nullptr;
314 };
315
TEST_F(MemoryTraceOutputTest,malloc_output)316 TEST_F(MemoryTraceOutputTest, malloc_output) {
317 memory_trace::Entry entry{.tid = 123, .type = memory_trace::MALLOC, .ptr = 0x123, .size = 50};
318 VerifyEntry(entry, "123: malloc 0x123 50");
319
320 entry.start_ns = 10;
321 entry.end_ns = 200;
322 VerifyEntry(entry, "123: malloc 0x123 50 10 200");
323 }
324
TEST_F(MemoryTraceOutputTest,calloc_output)325 TEST_F(MemoryTraceOutputTest, calloc_output) {
326 memory_trace::Entry entry{
327 .tid = 123, .type = memory_trace::CALLOC, .ptr = 0x123, .size = 200, .u.n_elements = 400};
328 VerifyEntry(entry, "123: calloc 0x123 400 200");
329
330 entry.start_ns = 15;
331 entry.end_ns = 315;
332 VerifyEntry(entry, "123: calloc 0x123 400 200 15 315");
333 }
334
TEST_F(MemoryTraceOutputTest,memalign_output)335 TEST_F(MemoryTraceOutputTest, memalign_output) {
336 memory_trace::Entry entry{
337 .tid = 123, .type = memory_trace::MEMALIGN, .ptr = 0x123, .size = 1024, .u.align = 0x10};
338 VerifyEntry(entry, "123: memalign 0x123 16 1024");
339
340 entry.start_ns = 23;
341 entry.end_ns = 289;
342 VerifyEntry(entry, "123: memalign 0x123 16 1024 23 289");
343 }
344
TEST_F(MemoryTraceOutputTest,realloc_output)345 TEST_F(MemoryTraceOutputTest, realloc_output) {
346 memory_trace::Entry entry{
347 .tid = 123, .type = memory_trace::REALLOC, .ptr = 0x123, .size = 300, .u.old_ptr = 0x125};
348 VerifyEntry(entry, "123: realloc 0x123 0x125 300");
349
350 entry.start_ns = 45;
351 entry.end_ns = 1000;
352 VerifyEntry(entry, "123: realloc 0x123 0x125 300 45 1000");
353 }
354
TEST_F(MemoryTraceOutputTest,free_output)355 TEST_F(MemoryTraceOutputTest, free_output) {
356 memory_trace::Entry entry{.tid = 123, .type = memory_trace::FREE, .ptr = 0x123};
357 VerifyEntry(entry, "123: free 0x123");
358
359 entry.start_ns = 60;
360 entry.end_ns = 2000;
361 VerifyEntry(entry, "123: free 0x123 60 2000");
362 }
363
TEST_F(MemoryTraceOutputTest,thread_done_output)364 TEST_F(MemoryTraceOutputTest, thread_done_output) {
365 memory_trace::Entry entry{.tid = 123, .type = memory_trace::THREAD_DONE};
366 VerifyEntry(entry, "123: thread_done 0x0");
367
368 entry.start_ns = 0;
369 entry.end_ns = 2500;
370 VerifyEntry(entry, "123: thread_done 0x0 2500");
371 }
372