1 /*
2 * Copyright (C) 2013 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 <gtest/gtest.h>
18
19 #include <limits.h>
20 #include <stdint.h>
21 #include <stdlib.h>
22 #include <malloc.h>
23 #include <unistd.h>
24
25 #include <tinyxml2.h>
26
27 #include "private/bionic_config.h"
28
TEST(malloc,malloc_std)29 TEST(malloc, malloc_std) {
30 // Simple malloc test.
31 void *ptr = malloc(100);
32 ASSERT_TRUE(ptr != NULL);
33 ASSERT_LE(100U, malloc_usable_size(ptr));
34 free(ptr);
35 }
36
TEST(malloc,malloc_overflow)37 TEST(malloc, malloc_overflow) {
38 errno = 0;
39 ASSERT_EQ(NULL, malloc(SIZE_MAX));
40 ASSERT_EQ(ENOMEM, errno);
41 }
42
TEST(malloc,calloc_std)43 TEST(malloc, calloc_std) {
44 // Simple calloc test.
45 size_t alloc_len = 100;
46 char *ptr = (char *)calloc(1, alloc_len);
47 ASSERT_TRUE(ptr != NULL);
48 ASSERT_LE(alloc_len, malloc_usable_size(ptr));
49 for (size_t i = 0; i < alloc_len; i++) {
50 ASSERT_EQ(0, ptr[i]);
51 }
52 free(ptr);
53 }
54
TEST(malloc,calloc_illegal)55 TEST(malloc, calloc_illegal) {
56 errno = 0;
57 ASSERT_EQ(NULL, calloc(-1, 100));
58 ASSERT_EQ(ENOMEM, errno);
59 }
60
TEST(malloc,calloc_overflow)61 TEST(malloc, calloc_overflow) {
62 errno = 0;
63 ASSERT_EQ(NULL, calloc(1, SIZE_MAX));
64 ASSERT_EQ(ENOMEM, errno);
65 errno = 0;
66 ASSERT_EQ(NULL, calloc(SIZE_MAX, SIZE_MAX));
67 ASSERT_EQ(ENOMEM, errno);
68 errno = 0;
69 ASSERT_EQ(NULL, calloc(2, SIZE_MAX));
70 ASSERT_EQ(ENOMEM, errno);
71 errno = 0;
72 ASSERT_EQ(NULL, calloc(SIZE_MAX, 2));
73 ASSERT_EQ(ENOMEM, errno);
74 }
75
TEST(malloc,memalign_multiple)76 TEST(malloc, memalign_multiple) {
77 // Memalign test where the alignment is any value.
78 for (size_t i = 0; i <= 12; i++) {
79 for (size_t alignment = 1 << i; alignment < (1U << (i+1)); alignment++) {
80 char *ptr = reinterpret_cast<char*>(memalign(alignment, 100));
81 ASSERT_TRUE(ptr != NULL) << "Failed at alignment " << alignment;
82 ASSERT_LE(100U, malloc_usable_size(ptr)) << "Failed at alignment " << alignment;
83 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) % ((1U << i)))
84 << "Failed at alignment " << alignment;
85 free(ptr);
86 }
87 }
88 }
89
TEST(malloc,memalign_overflow)90 TEST(malloc, memalign_overflow) {
91 ASSERT_EQ(NULL, memalign(4096, SIZE_MAX));
92 }
93
TEST(malloc,memalign_non_power2)94 TEST(malloc, memalign_non_power2) {
95 void* ptr;
96 for (size_t align = 0; align <= 256; align++) {
97 ptr = memalign(align, 1024);
98 ASSERT_TRUE(ptr != NULL) << "Failed at align " << align;
99 free(ptr);
100 }
101 }
102
TEST(malloc,posix_memalign_non_power2)103 TEST(malloc, posix_memalign_non_power2) {
104 void* ptr;
105 ASSERT_EQ(EINVAL, posix_memalign(&ptr, 17, 1024));
106 }
107
TEST(malloc,posix_memalign_overflow)108 TEST(malloc, posix_memalign_overflow) {
109 void* ptr;
110 ASSERT_NE(0, posix_memalign(&ptr, 16, SIZE_MAX));
111 }
112
TEST(malloc,memalign_realloc)113 TEST(malloc, memalign_realloc) {
114 // Memalign and then realloc the pointer a couple of times.
115 for (size_t alignment = 1; alignment <= 4096; alignment <<= 1) {
116 char *ptr = (char*)memalign(alignment, 100);
117 ASSERT_TRUE(ptr != NULL);
118 ASSERT_LE(100U, malloc_usable_size(ptr));
119 ASSERT_EQ(0U, (intptr_t)ptr % alignment);
120 memset(ptr, 0x23, 100);
121
122 ptr = (char*)realloc(ptr, 200);
123 ASSERT_TRUE(ptr != NULL);
124 ASSERT_LE(200U, malloc_usable_size(ptr));
125 ASSERT_TRUE(ptr != NULL);
126 for (size_t i = 0; i < 100; i++) {
127 ASSERT_EQ(0x23, ptr[i]);
128 }
129 memset(ptr, 0x45, 200);
130
131 ptr = (char*)realloc(ptr, 300);
132 ASSERT_TRUE(ptr != NULL);
133 ASSERT_LE(300U, malloc_usable_size(ptr));
134 for (size_t i = 0; i < 200; i++) {
135 ASSERT_EQ(0x45, ptr[i]);
136 }
137 memset(ptr, 0x67, 300);
138
139 ptr = (char*)realloc(ptr, 250);
140 ASSERT_TRUE(ptr != NULL);
141 ASSERT_LE(250U, malloc_usable_size(ptr));
142 for (size_t i = 0; i < 250; i++) {
143 ASSERT_EQ(0x67, ptr[i]);
144 }
145 free(ptr);
146 }
147 }
148
TEST(malloc,malloc_realloc_larger)149 TEST(malloc, malloc_realloc_larger) {
150 // Realloc to a larger size, malloc is used for the original allocation.
151 char *ptr = (char *)malloc(100);
152 ASSERT_TRUE(ptr != NULL);
153 ASSERT_LE(100U, malloc_usable_size(ptr));
154 memset(ptr, 67, 100);
155
156 ptr = (char *)realloc(ptr, 200);
157 ASSERT_TRUE(ptr != NULL);
158 ASSERT_LE(200U, malloc_usable_size(ptr));
159 for (size_t i = 0; i < 100; i++) {
160 ASSERT_EQ(67, ptr[i]);
161 }
162 free(ptr);
163 }
164
TEST(malloc,malloc_realloc_smaller)165 TEST(malloc, malloc_realloc_smaller) {
166 // Realloc to a smaller size, malloc is used for the original allocation.
167 char *ptr = (char *)malloc(200);
168 ASSERT_TRUE(ptr != NULL);
169 ASSERT_LE(200U, malloc_usable_size(ptr));
170 memset(ptr, 67, 200);
171
172 ptr = (char *)realloc(ptr, 100);
173 ASSERT_TRUE(ptr != NULL);
174 ASSERT_LE(100U, malloc_usable_size(ptr));
175 for (size_t i = 0; i < 100; i++) {
176 ASSERT_EQ(67, ptr[i]);
177 }
178 free(ptr);
179 }
180
TEST(malloc,malloc_multiple_realloc)181 TEST(malloc, malloc_multiple_realloc) {
182 // Multiple reallocs, malloc is used for the original allocation.
183 char *ptr = (char *)malloc(200);
184 ASSERT_TRUE(ptr != NULL);
185 ASSERT_LE(200U, malloc_usable_size(ptr));
186 memset(ptr, 0x23, 200);
187
188 ptr = (char *)realloc(ptr, 100);
189 ASSERT_TRUE(ptr != NULL);
190 ASSERT_LE(100U, malloc_usable_size(ptr));
191 for (size_t i = 0; i < 100; i++) {
192 ASSERT_EQ(0x23, ptr[i]);
193 }
194
195 ptr = (char*)realloc(ptr, 50);
196 ASSERT_TRUE(ptr != NULL);
197 ASSERT_LE(50U, malloc_usable_size(ptr));
198 for (size_t i = 0; i < 50; i++) {
199 ASSERT_EQ(0x23, ptr[i]);
200 }
201
202 ptr = (char*)realloc(ptr, 150);
203 ASSERT_TRUE(ptr != NULL);
204 ASSERT_LE(150U, malloc_usable_size(ptr));
205 for (size_t i = 0; i < 50; i++) {
206 ASSERT_EQ(0x23, ptr[i]);
207 }
208 memset(ptr, 0x23, 150);
209
210 ptr = (char*)realloc(ptr, 425);
211 ASSERT_TRUE(ptr != NULL);
212 ASSERT_LE(425U, malloc_usable_size(ptr));
213 for (size_t i = 0; i < 150; i++) {
214 ASSERT_EQ(0x23, ptr[i]);
215 }
216 free(ptr);
217 }
218
TEST(malloc,calloc_realloc_larger)219 TEST(malloc, calloc_realloc_larger) {
220 // Realloc to a larger size, calloc is used for the original allocation.
221 char *ptr = (char *)calloc(1, 100);
222 ASSERT_TRUE(ptr != NULL);
223 ASSERT_LE(100U, malloc_usable_size(ptr));
224
225 ptr = (char *)realloc(ptr, 200);
226 ASSERT_TRUE(ptr != NULL);
227 ASSERT_LE(200U, malloc_usable_size(ptr));
228 for (size_t i = 0; i < 100; i++) {
229 ASSERT_EQ(0, ptr[i]);
230 }
231 free(ptr);
232 }
233
TEST(malloc,calloc_realloc_smaller)234 TEST(malloc, calloc_realloc_smaller) {
235 // Realloc to a smaller size, calloc is used for the original allocation.
236 char *ptr = (char *)calloc(1, 200);
237 ASSERT_TRUE(ptr != NULL);
238 ASSERT_LE(200U, malloc_usable_size(ptr));
239
240 ptr = (char *)realloc(ptr, 100);
241 ASSERT_TRUE(ptr != NULL);
242 ASSERT_LE(100U, malloc_usable_size(ptr));
243 for (size_t i = 0; i < 100; i++) {
244 ASSERT_EQ(0, ptr[i]);
245 }
246 free(ptr);
247 }
248
TEST(malloc,calloc_multiple_realloc)249 TEST(malloc, calloc_multiple_realloc) {
250 // Multiple reallocs, calloc is used for the original allocation.
251 char *ptr = (char *)calloc(1, 200);
252 ASSERT_TRUE(ptr != NULL);
253 ASSERT_LE(200U, malloc_usable_size(ptr));
254
255 ptr = (char *)realloc(ptr, 100);
256 ASSERT_TRUE(ptr != NULL);
257 ASSERT_LE(100U, malloc_usable_size(ptr));
258 for (size_t i = 0; i < 100; i++) {
259 ASSERT_EQ(0, ptr[i]);
260 }
261
262 ptr = (char*)realloc(ptr, 50);
263 ASSERT_TRUE(ptr != NULL);
264 ASSERT_LE(50U, malloc_usable_size(ptr));
265 for (size_t i = 0; i < 50; i++) {
266 ASSERT_EQ(0, ptr[i]);
267 }
268
269 ptr = (char*)realloc(ptr, 150);
270 ASSERT_TRUE(ptr != NULL);
271 ASSERT_LE(150U, malloc_usable_size(ptr));
272 for (size_t i = 0; i < 50; i++) {
273 ASSERT_EQ(0, ptr[i]);
274 }
275 memset(ptr, 0, 150);
276
277 ptr = (char*)realloc(ptr, 425);
278 ASSERT_TRUE(ptr != NULL);
279 ASSERT_LE(425U, malloc_usable_size(ptr));
280 for (size_t i = 0; i < 150; i++) {
281 ASSERT_EQ(0, ptr[i]);
282 }
283 free(ptr);
284 }
285
TEST(malloc,realloc_overflow)286 TEST(malloc, realloc_overflow) {
287 errno = 0;
288 ASSERT_EQ(NULL, realloc(NULL, SIZE_MAX));
289 ASSERT_EQ(ENOMEM, errno);
290 void* ptr = malloc(100);
291 ASSERT_TRUE(ptr != NULL);
292 errno = 0;
293 ASSERT_EQ(NULL, realloc(ptr, SIZE_MAX));
294 ASSERT_EQ(ENOMEM, errno);
295 free(ptr);
296 }
297
298 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
299 extern "C" void* pvalloc(size_t);
300 extern "C" void* valloc(size_t);
301
TEST(malloc,pvalloc_std)302 TEST(malloc, pvalloc_std) {
303 size_t pagesize = sysconf(_SC_PAGESIZE);
304 void* ptr = pvalloc(100);
305 ASSERT_TRUE(ptr != NULL);
306 ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0);
307 ASSERT_LE(pagesize, malloc_usable_size(ptr));
308 free(ptr);
309 }
310
TEST(malloc,pvalloc_overflow)311 TEST(malloc, pvalloc_overflow) {
312 ASSERT_EQ(NULL, pvalloc(SIZE_MAX));
313 }
314
TEST(malloc,valloc_std)315 TEST(malloc, valloc_std) {
316 size_t pagesize = sysconf(_SC_PAGESIZE);
317 void* ptr = pvalloc(100);
318 ASSERT_TRUE(ptr != NULL);
319 ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0);
320 free(ptr);
321 }
322
TEST(malloc,valloc_overflow)323 TEST(malloc, valloc_overflow) {
324 ASSERT_EQ(NULL, valloc(SIZE_MAX));
325 }
326 #endif
327
TEST(malloc,malloc_info)328 TEST(malloc, malloc_info) {
329 #ifdef __BIONIC__
330 char* buf;
331 size_t bufsize;
332 FILE* memstream = open_memstream(&buf, &bufsize);
333 ASSERT_NE(nullptr, memstream);
334 ASSERT_EQ(0, malloc_info(0, memstream));
335 ASSERT_EQ(0, fclose(memstream));
336
337 tinyxml2::XMLDocument doc;
338 ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(buf));
339
340 auto root = doc.FirstChildElement();
341 ASSERT_NE(nullptr, root);
342 ASSERT_STREQ("malloc", root->Name());
343 ASSERT_STREQ("jemalloc-1", root->Attribute("version"));
344
345 auto arena = root->FirstChildElement();
346 for (; arena != nullptr; arena = arena->NextSiblingElement()) {
347 int val;
348
349 ASSERT_STREQ("heap", arena->Name());
350 ASSERT_EQ(tinyxml2::XML_SUCCESS, arena->QueryIntAttribute("nr", &val));
351 ASSERT_EQ(tinyxml2::XML_SUCCESS,
352 arena->FirstChildElement("allocated-large")->QueryIntText(&val));
353 ASSERT_EQ(tinyxml2::XML_SUCCESS,
354 arena->FirstChildElement("allocated-huge")->QueryIntText(&val));
355 ASSERT_EQ(tinyxml2::XML_SUCCESS,
356 arena->FirstChildElement("allocated-bins")->QueryIntText(&val));
357 ASSERT_EQ(tinyxml2::XML_SUCCESS,
358 arena->FirstChildElement("bins-total")->QueryIntText(&val));
359
360 auto bin = arena->FirstChildElement("bin");
361 for (; bin != nullptr; bin = bin ->NextSiblingElement()) {
362 if (strcmp(bin->Name(), "bin") == 0) {
363 ASSERT_EQ(tinyxml2::XML_SUCCESS, bin->QueryIntAttribute("nr", &val));
364 ASSERT_EQ(tinyxml2::XML_SUCCESS,
365 bin->FirstChildElement("allocated")->QueryIntText(&val));
366 ASSERT_EQ(tinyxml2::XML_SUCCESS,
367 bin->FirstChildElement("nmalloc")->QueryIntText(&val));
368 ASSERT_EQ(tinyxml2::XML_SUCCESS,
369 bin->FirstChildElement("ndalloc")->QueryIntText(&val));
370 }
371 }
372 }
373 #endif
374 }
375
TEST(malloc,calloc_usable_size)376 TEST(malloc, calloc_usable_size) {
377 for (size_t size = 1; size <= 2048; size++) {
378 void* pointer = malloc(size);
379 ASSERT_TRUE(pointer != nullptr);
380 memset(pointer, 0xeb, malloc_usable_size(pointer));
381 free(pointer);
382
383 // We should get a previous pointer that has been set to non-zero.
384 // If calloc does not zero out all of the data, this will fail.
385 uint8_t* zero_mem = reinterpret_cast<uint8_t*>(calloc(1, size));
386 ASSERT_TRUE(pointer != nullptr);
387 size_t usable_size = malloc_usable_size(zero_mem);
388 for (size_t i = 0; i < usable_size; i++) {
389 ASSERT_EQ(0, zero_mem[i]) << "Failed at allocation size " << size << " at byte " << i;
390 }
391 free(zero_mem);
392 }
393 }
394
TEST(malloc,malloc_0)395 TEST(malloc, malloc_0) {
396 void* p = malloc(0);
397 ASSERT_TRUE(p != nullptr);
398 free(p);
399 }
400
TEST(malloc,calloc_0_0)401 TEST(malloc, calloc_0_0) {
402 void* p = calloc(0, 0);
403 ASSERT_TRUE(p != nullptr);
404 free(p);
405 }
406
TEST(malloc,calloc_0_1)407 TEST(malloc, calloc_0_1) {
408 void* p = calloc(0, 1);
409 ASSERT_TRUE(p != nullptr);
410 free(p);
411 }
412
TEST(malloc,calloc_1_0)413 TEST(malloc, calloc_1_0) {
414 void* p = calloc(1, 0);
415 ASSERT_TRUE(p != nullptr);
416 free(p);
417 }
418
TEST(malloc,realloc_nullptr_0)419 TEST(malloc, realloc_nullptr_0) {
420 // realloc(nullptr, size) is actually malloc(size).
421 void* p = realloc(nullptr, 0);
422 ASSERT_TRUE(p != nullptr);
423 free(p);
424 }
425
TEST(malloc,realloc_0)426 TEST(malloc, realloc_0) {
427 void* p = malloc(1024);
428 ASSERT_TRUE(p != nullptr);
429 // realloc(p, 0) is actually free(p).
430 void* p2 = realloc(p, 0);
431 ASSERT_TRUE(p2 == nullptr);
432 }
433
434 constexpr size_t MAX_LOOPS = 200;
435
436 // Make sure that memory returned by malloc is aligned to allow these data types.
TEST(malloc,verify_alignment)437 TEST(malloc, verify_alignment) {
438 uint32_t** values_32 = new uint32_t*[MAX_LOOPS];
439 uint64_t** values_64 = new uint64_t*[MAX_LOOPS];
440 long double** values_ldouble = new long double*[MAX_LOOPS];
441 // Use filler to attempt to force the allocator to get potentially bad alignments.
442 void** filler = new void*[MAX_LOOPS];
443
444 for (size_t i = 0; i < MAX_LOOPS; i++) {
445 // Check uint32_t pointers.
446 filler[i] = malloc(1);
447 ASSERT_TRUE(filler[i] != nullptr);
448
449 values_32[i] = reinterpret_cast<uint32_t*>(malloc(sizeof(uint32_t)));
450 ASSERT_TRUE(values_32[i] != nullptr);
451 *values_32[i] = i;
452 ASSERT_EQ(*values_32[i], i);
453 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_32[i]) & (sizeof(uint32_t) - 1));
454
455 free(filler[i]);
456 }
457
458 for (size_t i = 0; i < MAX_LOOPS; i++) {
459 // Check uint64_t pointers.
460 filler[i] = malloc(1);
461 ASSERT_TRUE(filler[i] != nullptr);
462
463 values_64[i] = reinterpret_cast<uint64_t*>(malloc(sizeof(uint64_t)));
464 ASSERT_TRUE(values_64[i] != nullptr);
465 *values_64[i] = 0x1000 + i;
466 ASSERT_EQ(*values_64[i], 0x1000 + i);
467 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_64[i]) & (sizeof(uint64_t) - 1));
468
469 free(filler[i]);
470 }
471
472 for (size_t i = 0; i < MAX_LOOPS; i++) {
473 // Check long double pointers.
474 filler[i] = malloc(1);
475 ASSERT_TRUE(filler[i] != nullptr);
476
477 values_ldouble[i] = reinterpret_cast<long double*>(malloc(sizeof(long double)));
478 ASSERT_TRUE(values_ldouble[i] != nullptr);
479 *values_ldouble[i] = 5.5 + i;
480 ASSERT_DOUBLE_EQ(*values_ldouble[i], 5.5 + i);
481 // 32 bit glibc has a long double size of 12 bytes, so hardcode the
482 // required alignment to 0x7.
483 #if !defined(__BIONIC__) && !defined(__LP64__)
484 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_ldouble[i]) & 0x7);
485 #else
486 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_ldouble[i]) & (sizeof(long double) - 1));
487 #endif
488
489 free(filler[i]);
490 }
491
492 for (size_t i = 0; i < MAX_LOOPS; i++) {
493 free(values_32[i]);
494 free(values_64[i]);
495 free(values_ldouble[i]);
496 }
497
498 delete[] filler;
499 delete[] values_32;
500 delete[] values_64;
501 delete[] values_ldouble;
502 }
503