Home | History | Annotate | Download | only in tests
      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 
     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 
     37 TEST(malloc, malloc_overflow) {
     38   errno = 0;
     39   ASSERT_EQ(NULL, malloc(SIZE_MAX));
     40   ASSERT_EQ(ENOMEM, errno);
     41 }
     42 
     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 
     55 TEST(malloc, calloc_illegal) {
     56   errno = 0;
     57   ASSERT_EQ(NULL, calloc(-1, 100));
     58   ASSERT_EQ(ENOMEM, errno);
     59 }
     60 
     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 
     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 
     90 TEST(malloc, memalign_overflow) {
     91   ASSERT_EQ(NULL, memalign(4096, SIZE_MAX));
     92 }
     93 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    301 TEST(malloc, pvalloc_overflow) {
    302   ASSERT_EQ(NULL, pvalloc(SIZE_MAX));
    303 }
    304 
    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 
    313 TEST(malloc, valloc_overflow) {
    314   ASSERT_EQ(NULL, valloc(SIZE_MAX));
    315 }
    316 #endif
    317 
    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 
    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 
    385 TEST(malloc, malloc_0) {
    386   void* p = malloc(0);
    387   ASSERT_TRUE(p != nullptr);
    388   free(p);
    389 }
    390 
    391 TEST(malloc, calloc_0_0) {
    392   void* p = calloc(0, 0);
    393   ASSERT_TRUE(p != nullptr);
    394   free(p);
    395 }
    396 
    397 TEST(malloc, calloc_0_1) {
    398   void* p = calloc(0, 1);
    399   ASSERT_TRUE(p != nullptr);
    400   free(p);
    401 }
    402 
    403 TEST(malloc, calloc_1_0) {
    404   void* p = calloc(1, 0);
    405   ASSERT_TRUE(p != nullptr);
    406   free(p);
    407 }
    408 
    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 
    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.
    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 
    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