2 * Copyright (C) 2013 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <gtest/gtest.h>
27 #include "private/bionic_config.h"
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));
37 TEST(malloc, malloc_overflow) {
39 ASSERT_EQ(NULL, malloc(SIZE_MAX));
40 ASSERT_EQ(ENOMEM, errno);
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++) {
55 TEST(malloc, calloc_illegal) {
57 ASSERT_EQ(NULL, calloc(-1, 100));
58 ASSERT_EQ(ENOMEM, errno);
61 TEST(malloc, calloc_overflow) {
63 ASSERT_EQ(NULL, calloc(1, SIZE_MAX));
64 ASSERT_EQ(ENOMEM, errno);
66 ASSERT_EQ(NULL, calloc(SIZE_MAX, SIZE_MAX));
67 ASSERT_EQ(ENOMEM, errno);
69 ASSERT_EQ(NULL, calloc(2, SIZE_MAX));
70 ASSERT_EQ(ENOMEM, errno);
72 ASSERT_EQ(NULL, calloc(SIZE_MAX, 2));
73 ASSERT_EQ(ENOMEM, errno);
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;
90 TEST(malloc, memalign_overflow) {
91 ASSERT_EQ(NULL, memalign(4096, SIZE_MAX));
94 TEST(malloc, memalign_non_power2) {
96 for (size_t align = 0; align <= 256; align++) {
97 ptr = memalign(align, 1024);
98 ASSERT_TRUE(ptr != NULL) << "Failed at align " << align;
103 TEST(malloc, posix_memalign_non_power2) {
105 ASSERT_EQ(EINVAL, posix_memalign(&ptr, 17, 1024));
108 TEST(malloc, posix_memalign_overflow) {
110 ASSERT_NE(0, posix_memalign(&ptr, 16, SIZE_MAX));
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);
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]);
129 memset(ptr, 0x45, 200);
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]);
137 memset(ptr, 0x67, 300);
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]);
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);
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]);
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);
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]);
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);
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]);
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]);
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]);
208 memset(ptr, 0x23, 150);
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]);
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));
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]);
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));
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]);
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));
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]);
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]);
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]);
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]);
286 TEST(malloc, realloc_overflow) {
288 ASSERT_EQ(NULL, realloc(NULL, SIZE_MAX));
289 ASSERT_EQ(ENOMEM, errno);
290 void* ptr = malloc(100);
291 ASSERT_TRUE(ptr != NULL);
293 ASSERT_EQ(NULL, realloc(ptr, SIZE_MAX));
294 ASSERT_EQ(ENOMEM, errno);
298 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
299 extern "C" void* pvalloc(size_t);
300 extern "C" void* valloc(size_t);
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));
311 TEST(malloc, pvalloc_overflow) {
312 ASSERT_EQ(NULL, pvalloc(SIZE_MAX));
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);
323 TEST(malloc, valloc_overflow) {
324 ASSERT_EQ(NULL, valloc(SIZE_MAX));
328 TEST(malloc, malloc_info) {
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));
337 tinyxml2::XMLDocument doc;
338 ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(buf));
340 auto root = doc.FirstChildElement();
341 ASSERT_NE(nullptr, root);
342 ASSERT_STREQ("malloc", root->Name());
343 ASSERT_STREQ("jemalloc-1", root->Attribute("version"));
345 auto arena = root->FirstChildElement();
346 for (; arena != nullptr; arena = arena->NextSiblingElement()) {
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));
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));
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));
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;
395 TEST(malloc, malloc_0) {
397 ASSERT_TRUE(p != nullptr);
401 TEST(malloc, calloc_0_0) {
402 void* p = calloc(0, 0);
403 ASSERT_TRUE(p != nullptr);
407 TEST(malloc, calloc_0_1) {
408 void* p = calloc(0, 1);
409 ASSERT_TRUE(p != nullptr);
413 TEST(malloc, calloc_1_0) {
414 void* p = calloc(1, 0);
415 ASSERT_TRUE(p != nullptr);
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);
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);
434 constexpr size_t MAX_LOOPS = 200;
436 // Make sure that memory returned by malloc is aligned to allow these data types.
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];
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);
449 values_32[i] = reinterpret_cast<uint32_t*>(malloc(sizeof(uint32_t)));
450 ASSERT_TRUE(values_32[i] != nullptr);
452 ASSERT_EQ(*values_32[i], i);
453 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_32[i]) & (sizeof(uint32_t) - 1));
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);
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));
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);
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);
486 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_ldouble[i]) & (sizeof(long double) - 1));
492 for (size_t i = 0; i < MAX_LOOPS; i++) {
495 free(values_ldouble[i]);
501 delete[] values_ldouble;