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