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(-1, entry.present_bytes);
38 EXPECT_EQ(0U, entry.start_ns);
39 EXPECT_EQ(0U, entry.end_ns);
40
41 line += " 1000 1020";
42 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
43 EXPECT_EQ(memory_trace::MALLOC, entry.type);
44 EXPECT_EQ(1234, entry.tid);
45 EXPECT_EQ(0xabd0000U, entry.ptr);
46 EXPECT_EQ(20U, entry.size);
47 EXPECT_EQ(0U, entry.u.align);
48 EXPECT_EQ(-1, entry.present_bytes);
49 EXPECT_EQ(1000U, entry.start_ns);
50 EXPECT_EQ(1020U, entry.end_ns);
51 }
52
TEST(MemoryTraceReadTest,malloc_invalid)53 TEST(MemoryTraceReadTest, malloc_invalid) {
54 // Missing size
55 std::string line = "1234: malloc 0xabd0000";
56 memory_trace::Entry entry;
57 std::string error;
58 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
59 EXPECT_EQ("Failed to read malloc data: 1234: malloc 0xabd0000", error);
60
61 // Missing pointer and size
62 line = "1234: malloc";
63 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
64 EXPECT_EQ("Failed to process line: 1234: malloc", error);
65
66 // Missing end time
67 line = "1234: malloc 0xabd0000 10 100";
68 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
69 EXPECT_EQ("Failed to read timestamps: 1234: malloc 0xabd0000 10 100", error);
70 }
71
TEST(MemoryTraceReadTest,free_valid)72 TEST(MemoryTraceReadTest, free_valid) {
73 std::string line = "1235: free 0x5000";
74 memory_trace::Entry entry{.start_ns = 1, .end_ns = 1};
75 std::string error;
76 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
77 EXPECT_EQ(memory_trace::FREE, entry.type);
78 EXPECT_EQ(1235, entry.tid);
79 EXPECT_EQ(0x5000U, entry.ptr);
80 EXPECT_EQ(0U, entry.size);
81 EXPECT_EQ(0U, entry.u.align);
82 EXPECT_EQ(-1, entry.present_bytes);
83 EXPECT_EQ(0U, entry.start_ns);
84 EXPECT_EQ(0U, entry.end_ns);
85
86 line += " 540 2000";
87 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
88 EXPECT_EQ(memory_trace::FREE, entry.type);
89 EXPECT_EQ(1235, entry.tid);
90 EXPECT_EQ(0x5000U, entry.ptr);
91 EXPECT_EQ(0U, entry.size);
92 EXPECT_EQ(0U, entry.u.align);
93 EXPECT_EQ(-1, entry.present_bytes);
94 EXPECT_EQ(540U, entry.start_ns);
95 EXPECT_EQ(2000U, entry.end_ns);
96
97 line += " 234";
98 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
99 EXPECT_EQ(memory_trace::FREE, entry.type);
100 EXPECT_EQ(1235, entry.tid);
101 EXPECT_EQ(0x5000U, entry.ptr);
102 EXPECT_EQ(0U, entry.size);
103 EXPECT_EQ(234, entry.present_bytes);
104 EXPECT_EQ(540U, entry.start_ns);
105 EXPECT_EQ(2000U, entry.end_ns);
106 }
107
TEST(MemoryTraceReadTest,free_invalid)108 TEST(MemoryTraceReadTest, free_invalid) {
109 // Missing pointer
110 std::string line = "1234: free";
111 memory_trace::Entry entry;
112 std::string error;
113 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
114 EXPECT_EQ("Failed to process line: 1234: free", error);
115
116 // Missing end time
117 line = "1234: free 0x100 100";
118 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
119 EXPECT_EQ("Failed to read timestamps: 1234: free 0x100 100", error);
120 }
121
TEST(MemoryTraceReadTest,calloc_valid)122 TEST(MemoryTraceReadTest, calloc_valid) {
123 std::string line = "1236: calloc 0x8000 50 30";
124 memory_trace::Entry entry{.start_ns = 1, .end_ns = 1};
125 std::string error;
126 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
127 EXPECT_EQ(memory_trace::CALLOC, entry.type);
128 EXPECT_EQ(1236, entry.tid);
129 EXPECT_EQ(0x8000U, entry.ptr);
130 EXPECT_EQ(30U, entry.size);
131 EXPECT_EQ(50U, entry.u.n_elements);
132 EXPECT_EQ(-1, entry.present_bytes);
133 EXPECT_EQ(0U, entry.start_ns);
134 EXPECT_EQ(0U, entry.end_ns);
135
136 line += " 700 1000";
137 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
138 EXPECT_EQ(memory_trace::CALLOC, entry.type);
139 EXPECT_EQ(1236, entry.tid);
140 EXPECT_EQ(0x8000U, entry.ptr);
141 EXPECT_EQ(30U, entry.size);
142 EXPECT_EQ(50U, entry.u.n_elements);
143 EXPECT_EQ(-1, entry.present_bytes);
144 EXPECT_EQ(700U, entry.start_ns);
145 EXPECT_EQ(1000U, entry.end_ns);
146 }
147
TEST(MemoryTraceReadTest,calloc_invalid)148 TEST(MemoryTraceReadTest, calloc_invalid) {
149 // Missing number of elements
150 std::string line = "1236: calloc 0x8000 50";
151 memory_trace::Entry entry;
152 std::string error;
153 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
154 EXPECT_EQ("Failed to read calloc data: 1236: calloc 0x8000 50", error);
155
156 // Missing size and number of elements
157 line = "1236: calloc 0x8000";
158 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
159 EXPECT_EQ("Failed to read calloc data: 1236: calloc 0x8000", error);
160
161 // Missing pointer, size and number of elements
162 line = "1236: calloc";
163 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
164 EXPECT_EQ("Failed to process line: 1236: calloc", error);
165
166 // Missing end time
167 line = "1236: calloc 0x8000 50 20 100";
168 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
169 EXPECT_EQ("Failed to read timestamps: 1236: calloc 0x8000 50 20 100", error);
170 }
171
TEST(MemoryTraceReadTest,realloc_valid)172 TEST(MemoryTraceReadTest, realloc_valid) {
173 std::string line = "1237: realloc 0x9000 0x4000 80";
174 memory_trace::Entry entry{.start_ns = 1, .end_ns = 1};
175 std::string error;
176 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
177 EXPECT_EQ(memory_trace::REALLOC, entry.type);
178 EXPECT_EQ(1237, entry.tid);
179 EXPECT_EQ(0x9000U, entry.ptr);
180 EXPECT_EQ(80U, entry.size);
181 EXPECT_EQ(0x4000U, entry.u.old_ptr);
182 EXPECT_EQ(-1, entry.present_bytes);
183 EXPECT_EQ(0U, entry.start_ns);
184 EXPECT_EQ(0U, entry.end_ns);
185
186 line += " 3999 10020";
187 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
188 EXPECT_EQ(memory_trace::REALLOC, entry.type);
189 EXPECT_EQ(1237, entry.tid);
190 EXPECT_EQ(0x9000U, entry.ptr);
191 EXPECT_EQ(80U, entry.size);
192 EXPECT_EQ(0x4000U, entry.u.old_ptr);
193 EXPECT_EQ(-1, entry.present_bytes);
194 EXPECT_EQ(3999U, entry.start_ns);
195 EXPECT_EQ(10020U, entry.end_ns);
196
197 line += " 50";
198 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
199 EXPECT_EQ(memory_trace::REALLOC, entry.type);
200 EXPECT_EQ(1237, entry.tid);
201 EXPECT_EQ(0x9000U, entry.ptr);
202 EXPECT_EQ(80U, entry.size);
203 EXPECT_EQ(0x4000U, entry.u.old_ptr);
204 EXPECT_EQ(50, entry.present_bytes);
205 EXPECT_EQ(3999U, entry.start_ns);
206 EXPECT_EQ(10020U, entry.end_ns);
207 }
208
TEST(MemoryTraceReadTest,realloc_invalid)209 TEST(MemoryTraceReadTest, realloc_invalid) {
210 // Missing size
211 std::string line = "1237: realloc 0x9000 0x4000";
212 memory_trace::Entry entry;
213 std::string error;
214 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
215 EXPECT_EQ("Failed to read realloc data: 1237: realloc 0x9000 0x4000", error);
216
217 // Missing size and old pointer
218 line = "1237: realloc 0x9000";
219 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
220 EXPECT_EQ("Failed to read realloc data: 1237: realloc 0x9000", error);
221
222 // Missing new pointer, size and old pointer
223 line = "1237: realloc";
224 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
225 EXPECT_EQ("Failed to process line: 1237: realloc", error);
226
227 // Missing end time
228 line = "1237: realloc 0x9000 0x4000 10 500";
229 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
230 EXPECT_EQ("Failed to read timestamps: 1237: realloc 0x9000 0x4000 10 500", error);
231 }
232
TEST(MemoryTraceReadTest,memalign_valid)233 TEST(MemoryTraceReadTest, memalign_valid) {
234 std::string line = "1238: memalign 0xa000 16 89";
235 memory_trace::Entry entry{.start_ns = 1, .end_ns = 1};
236 std::string error;
237 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
238 EXPECT_EQ(memory_trace::MEMALIGN, entry.type);
239 EXPECT_EQ(1238, entry.tid);
240 EXPECT_EQ(0xa000U, entry.ptr);
241 EXPECT_EQ(89U, entry.size);
242 EXPECT_EQ(16U, entry.u.align);
243 EXPECT_EQ(-1, entry.present_bytes);
244 EXPECT_EQ(0U, entry.start_ns);
245 EXPECT_EQ(0U, entry.end_ns);
246
247 line += " 900 1000";
248 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
249 EXPECT_EQ(memory_trace::MEMALIGN, entry.type);
250 EXPECT_EQ(1238, entry.tid);
251 EXPECT_EQ(0xa000U, entry.ptr);
252 EXPECT_EQ(89U, entry.size);
253 EXPECT_EQ(16U, entry.u.align);
254 EXPECT_EQ(-1, entry.present_bytes);
255 EXPECT_EQ(900U, entry.start_ns);
256 EXPECT_EQ(1000U, entry.end_ns);
257 }
258
TEST(MemoryTraceReadTest,memalign_invalid)259 TEST(MemoryTraceReadTest, memalign_invalid) {
260 // Missing size
261 std::string line = "1238: memalign 0xa000 16";
262 memory_trace::Entry entry;
263 std::string error;
264 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
265 EXPECT_EQ("Failed to read memalign data: 1238: memalign 0xa000 16", error);
266
267 // Missing alignment and size
268 line = "1238: memalign 0xa000";
269 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
270 EXPECT_EQ("Failed to read memalign data: 1238: memalign 0xa000", error);
271
272 // Missing pointer, alignment and size
273 line = "1238: memalign";
274 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
275 EXPECT_EQ("Failed to process line: 1238: memalign", error);
276
277 // Missing end time
278 line = "1238: memalign 0xa000 16 10 800";
279 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
280 EXPECT_EQ("Failed to read timestamps: 1238: memalign 0xa000 16 10 800", error);
281 }
282
TEST(MemoryTraceReadTest,thread_done_valid)283 TEST(MemoryTraceReadTest, thread_done_valid) {
284 std::string line = "1239: thread_done 0x0";
285 memory_trace::Entry entry{.start_ns = 1, .end_ns = 1};
286 std::string error;
287 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
288 EXPECT_EQ(memory_trace::THREAD_DONE, entry.type);
289 EXPECT_EQ(1239, entry.tid);
290 EXPECT_EQ(0U, entry.ptr);
291 EXPECT_EQ(0U, entry.size);
292 EXPECT_EQ(0U, entry.u.old_ptr);
293 EXPECT_EQ(-1, entry.present_bytes);
294 EXPECT_EQ(0U, entry.start_ns);
295 EXPECT_EQ(0U, entry.end_ns);
296
297 line += " 290";
298 ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
299 EXPECT_EQ(memory_trace::THREAD_DONE, entry.type);
300 EXPECT_EQ(1239, entry.tid);
301 EXPECT_EQ(0U, entry.ptr);
302 EXPECT_EQ(0U, entry.size);
303 EXPECT_EQ(0U, entry.u.old_ptr);
304 EXPECT_EQ(-1, entry.present_bytes);
305 EXPECT_EQ(0U, entry.start_ns);
306 EXPECT_EQ(290U, entry.end_ns);
307 }
308
TEST(MemoryTraceReadTest,thread_done_invalid)309 TEST(MemoryTraceReadTest, thread_done_invalid) {
310 // Missing pointer
311 std::string line = "1240: thread_done";
312 memory_trace::Entry entry;
313 std::string error;
314 EXPECT_FALSE(memory_trace::FillInEntryFromString(line, entry, error));
315 EXPECT_EQ("Failed to process line: 1240: thread_done", error);
316 }
317
318 class MemoryTraceOutputTest : public ::testing::Test {
319 protected:
SetUp()320 void SetUp() override {
321 tmp_file_ = new TemporaryFile();
322 ASSERT_TRUE(tmp_file_->fd != -1);
323 }
324
TearDown()325 void TearDown() override { delete tmp_file_; }
326
WriteAndReadString(const memory_trace::Entry & entry,std::string & str)327 void WriteAndReadString(const memory_trace::Entry& entry, std::string& str) {
328 EXPECT_EQ(lseek(tmp_file_->fd, 0, SEEK_SET), 0);
329 EXPECT_TRUE(memory_trace::WriteEntryToFd(tmp_file_->fd, entry));
330 EXPECT_NE(-1, ftruncate(tmp_file_->fd, lseek(tmp_file_->fd, 0, SEEK_CUR)));
331 EXPECT_EQ(lseek(tmp_file_->fd, 0, SEEK_SET), 0);
332 EXPECT_TRUE(android::base::ReadFdToString(tmp_file_->fd, &str));
333 }
334
WriteAndGetString(const memory_trace::Entry & entry)335 std::string WriteAndGetString(const memory_trace::Entry& entry) {
336 std::string str;
337 WriteAndReadString(entry, str);
338 return str;
339 }
340
VerifyEntry(const memory_trace::Entry & entry,const std::string expected)341 void VerifyEntry(const memory_trace::Entry& entry, const std::string expected) {
342 EXPECT_EQ(expected, memory_trace::CreateStringFromEntry(entry));
343 // The WriteEntryToFd always appends a newline, but string creation doesn't.
344 EXPECT_EQ(expected + "\n", WriteAndGetString(entry));
345 }
346
347 TemporaryFile* tmp_file_ = nullptr;
348 };
349
TEST_F(MemoryTraceOutputTest,malloc_output)350 TEST_F(MemoryTraceOutputTest, malloc_output) {
351 memory_trace::Entry entry{.tid = 123, .type = memory_trace::MALLOC, .ptr = 0x123, .size = 50};
352 VerifyEntry(entry, "123: malloc 0x123 50");
353
354 entry.start_ns = 10;
355 entry.end_ns = 200;
356 VerifyEntry(entry, "123: malloc 0x123 50 10 200");
357 }
358
TEST_F(MemoryTraceOutputTest,calloc_output)359 TEST_F(MemoryTraceOutputTest, calloc_output) {
360 memory_trace::Entry entry{
361 .tid = 123, .type = memory_trace::CALLOC, .ptr = 0x123, .size = 200, .u.n_elements = 400};
362 VerifyEntry(entry, "123: calloc 0x123 400 200");
363
364 entry.start_ns = 15;
365 entry.end_ns = 315;
366 VerifyEntry(entry, "123: calloc 0x123 400 200 15 315");
367 }
368
TEST_F(MemoryTraceOutputTest,memalign_output)369 TEST_F(MemoryTraceOutputTest, memalign_output) {
370 memory_trace::Entry entry{
371 .tid = 123, .type = memory_trace::MEMALIGN, .ptr = 0x123, .size = 1024, .u.align = 0x10};
372 VerifyEntry(entry, "123: memalign 0x123 16 1024");
373
374 entry.start_ns = 23;
375 entry.end_ns = 289;
376 VerifyEntry(entry, "123: memalign 0x123 16 1024 23 289");
377 }
378
TEST_F(MemoryTraceOutputTest,realloc_output)379 TEST_F(MemoryTraceOutputTest, realloc_output) {
380 memory_trace::Entry entry{
381 .tid = 123, .type = memory_trace::REALLOC, .ptr = 0x123, .size = 300, .u.old_ptr = 0x125};
382 VerifyEntry(entry, "123: realloc 0x123 0x125 300");
383
384 entry.start_ns = 45;
385 entry.end_ns = 1000;
386 VerifyEntry(entry, "123: realloc 0x123 0x125 300 45 1000");
387 }
388
TEST_F(MemoryTraceOutputTest,free_output)389 TEST_F(MemoryTraceOutputTest, free_output) {
390 memory_trace::Entry entry{.tid = 123, .type = memory_trace::FREE, .ptr = 0x123};
391 VerifyEntry(entry, "123: free 0x123");
392
393 entry.start_ns = 60;
394 entry.end_ns = 2000;
395 VerifyEntry(entry, "123: free 0x123 60 2000");
396
397 entry.present_bytes = 456;
398 VerifyEntry(entry, "123: free 0x123 60 2000 456");
399
400 // Verify if present bytes is set, the timestamps are in the output.
401 entry.start_ns = 0;
402 entry.end_ns = 0;
403 entry.present_bytes = 456;
404 VerifyEntry(entry, "123: free 0x123 0 0 456");
405 }
406
TEST_F(MemoryTraceOutputTest,thread_done_output)407 TEST_F(MemoryTraceOutputTest, thread_done_output) {
408 memory_trace::Entry entry{.tid = 123, .type = memory_trace::THREAD_DONE};
409 VerifyEntry(entry, "123: thread_done 0x0");
410
411 entry.start_ns = 0;
412 entry.end_ns = 2500;
413 VerifyEntry(entry, "123: thread_done 0x0 2500");
414 }
415