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