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, posix_memalign_non_power2) {
    104   void* ptr;
    105   ASSERT_EQ(EINVAL, posix_memalign(&ptr, 17, 1024));
    106 }
    107 
    108 TEST(malloc, posix_memalign_overflow) {
    109   void* ptr;
    110   ASSERT_NE(0, posix_memalign(&ptr, 16, SIZE_MAX));
    111 }
    112 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    311 TEST(malloc, pvalloc_overflow) {
    312   ASSERT_EQ(NULL, pvalloc(SIZE_MAX));
    313 }
    314 
    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 
    323 TEST(malloc, valloc_overflow) {
    324   ASSERT_EQ(NULL, valloc(SIZE_MAX));
    325 }
    326 #endif
    327 
    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 
    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 
    395 TEST(malloc, malloc_0) {
    396   void* p = malloc(0);
    397   ASSERT_TRUE(p != nullptr);
    398   free(p);
    399 }
    400 
    401 TEST(malloc, calloc_0_0) {
    402   void* p = calloc(0, 0);
    403   ASSERT_TRUE(p != nullptr);
    404   free(p);
    405 }
    406 
    407 TEST(malloc, calloc_0_1) {
    408   void* p = calloc(0, 1);
    409   ASSERT_TRUE(p != nullptr);
    410   free(p);
    411 }
    412 
    413 TEST(malloc, calloc_1_0) {
    414   void* p = calloc(1, 0);
    415   ASSERT_TRUE(p != nullptr);
    416   free(p);
    417 }
    418 
    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 
    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.
    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 
    504 TEST(malloc, mallopt_smoke) {
    505   errno = 0;
    506   ASSERT_EQ(0, mallopt(-1000, 1));
    507   // mallopt doesn't set errno.
    508   ASSERT_EQ(0, errno);
    509 }
    510