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