blob: 658f8bdc90be4ce3313a176c0d9acb0a379d20c6 [file] [log] [blame]
Christopher Ferris885f3b92013-05-21 17:48:01 -07001/*
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
Christopher Ferrise4cdbc42019-02-08 17:30:58 -080019#include <elf.h>
Christopher Ferrisa4037802014-06-09 19:14:11 -070020#include <limits.h>
21#include <stdint.h>
Christopher Ferris885f3b92013-05-21 17:48:01 -070022#include <stdlib.h>
23#include <malloc.h>
Christopher Ferrisa4037802014-06-09 19:14:11 -070024#include <unistd.h>
Christopher Ferris885f3b92013-05-21 17:48:01 -070025
Dan Albert4caa1f02014-08-20 09:16:57 -070026#include <tinyxml2.h>
27
Christopher Ferrise4cdbc42019-02-08 17:30:58 -080028#include <android-base/file.h>
29
Christopher Ferris63619642014-06-16 23:35:53 -070030#include "private/bionic_config.h"
Ryan Savitskiecc37e32018-12-14 15:57:21 +000031#include "private/bionic_malloc.h"
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080032#include "utils.h"
Dan Alberte5fdaa42014-06-14 01:04:31 +000033
Elliott Hughesb1770852018-09-18 12:52:42 -070034#if defined(__BIONIC__)
35#define HAVE_REALLOCARRAY 1
36#else
37#define HAVE_REALLOCARRAY __GLIBC_PREREQ(2, 26)
38#endif
39
Christopher Ferris885f3b92013-05-21 17:48:01 -070040TEST(malloc, malloc_std) {
41 // Simple malloc test.
42 void *ptr = malloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -070043 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -070044 ASSERT_LE(100U, malloc_usable_size(ptr));
Christopher Ferris885f3b92013-05-21 17:48:01 -070045 free(ptr);
46}
47
Christopher Ferrisa4037802014-06-09 19:14:11 -070048TEST(malloc, malloc_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080049 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -070050 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070051 ASSERT_EQ(nullptr, malloc(SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -070052 ASSERT_EQ(ENOMEM, errno);
53}
54
Christopher Ferris885f3b92013-05-21 17:48:01 -070055TEST(malloc, calloc_std) {
56 // Simple calloc test.
57 size_t alloc_len = 100;
58 char *ptr = (char *)calloc(1, alloc_len);
Yi Kong32bc0fc2018-08-02 17:31:13 -070059 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -070060 ASSERT_LE(alloc_len, malloc_usable_size(ptr));
61 for (size_t i = 0; i < alloc_len; i++) {
62 ASSERT_EQ(0, ptr[i]);
63 }
Christopher Ferris885f3b92013-05-21 17:48:01 -070064 free(ptr);
65}
66
Christopher Ferrisa4037802014-06-09 19:14:11 -070067TEST(malloc, calloc_illegal) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080068 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -070069 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070070 ASSERT_EQ(nullptr, calloc(-1, 100));
Christopher Ferrisa4037802014-06-09 19:14:11 -070071 ASSERT_EQ(ENOMEM, errno);
72}
73
74TEST(malloc, calloc_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080075 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -070076 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070077 ASSERT_EQ(nullptr, calloc(1, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -070078 ASSERT_EQ(ENOMEM, errno);
79 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070080 ASSERT_EQ(nullptr, calloc(SIZE_MAX, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -070081 ASSERT_EQ(ENOMEM, errno);
82 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070083 ASSERT_EQ(nullptr, calloc(2, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -070084 ASSERT_EQ(ENOMEM, errno);
85 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070086 ASSERT_EQ(nullptr, calloc(SIZE_MAX, 2));
Christopher Ferrisa4037802014-06-09 19:14:11 -070087 ASSERT_EQ(ENOMEM, errno);
88}
89
Christopher Ferris885f3b92013-05-21 17:48:01 -070090TEST(malloc, memalign_multiple) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080091 SKIP_WITH_HWASAN; // hwasan requires power of 2 alignment.
Christopher Ferris885f3b92013-05-21 17:48:01 -070092 // Memalign test where the alignment is any value.
93 for (size_t i = 0; i <= 12; i++) {
94 for (size_t alignment = 1 << i; alignment < (1U << (i+1)); alignment++) {
Christopher Ferrisa4037802014-06-09 19:14:11 -070095 char *ptr = reinterpret_cast<char*>(memalign(alignment, 100));
Yi Kong32bc0fc2018-08-02 17:31:13 -070096 ASSERT_TRUE(ptr != nullptr) << "Failed at alignment " << alignment;
Christopher Ferrisa4037802014-06-09 19:14:11 -070097 ASSERT_LE(100U, malloc_usable_size(ptr)) << "Failed at alignment " << alignment;
98 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) % ((1U << i)))
99 << "Failed at alignment " << alignment;
Christopher Ferris885f3b92013-05-21 17:48:01 -0700100 free(ptr);
101 }
102 }
103}
104
Christopher Ferrisa4037802014-06-09 19:14:11 -0700105TEST(malloc, memalign_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800106 SKIP_WITH_HWASAN;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700107 ASSERT_EQ(nullptr, memalign(4096, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -0700108}
109
110TEST(malloc, memalign_non_power2) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800111 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700112 void* ptr;
113 for (size_t align = 0; align <= 256; align++) {
114 ptr = memalign(align, 1024);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700115 ASSERT_TRUE(ptr != nullptr) << "Failed at align " << align;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700116 free(ptr);
117 }
118}
119
Christopher Ferris885f3b92013-05-21 17:48:01 -0700120TEST(malloc, memalign_realloc) {
121 // Memalign and then realloc the pointer a couple of times.
122 for (size_t alignment = 1; alignment <= 4096; alignment <<= 1) {
123 char *ptr = (char*)memalign(alignment, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700124 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700125 ASSERT_LE(100U, malloc_usable_size(ptr));
126 ASSERT_EQ(0U, (intptr_t)ptr % alignment);
127 memset(ptr, 0x23, 100);
128
129 ptr = (char*)realloc(ptr, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700130 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700131 ASSERT_LE(200U, malloc_usable_size(ptr));
Yi Kong32bc0fc2018-08-02 17:31:13 -0700132 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700133 for (size_t i = 0; i < 100; i++) {
134 ASSERT_EQ(0x23, ptr[i]);
135 }
136 memset(ptr, 0x45, 200);
137
138 ptr = (char*)realloc(ptr, 300);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700139 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700140 ASSERT_LE(300U, malloc_usable_size(ptr));
141 for (size_t i = 0; i < 200; i++) {
142 ASSERT_EQ(0x45, ptr[i]);
143 }
144 memset(ptr, 0x67, 300);
145
146 ptr = (char*)realloc(ptr, 250);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700147 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700148 ASSERT_LE(250U, malloc_usable_size(ptr));
149 for (size_t i = 0; i < 250; i++) {
150 ASSERT_EQ(0x67, ptr[i]);
151 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700152 free(ptr);
153 }
154}
155
156TEST(malloc, malloc_realloc_larger) {
157 // Realloc to a larger size, malloc is used for the original allocation.
158 char *ptr = (char *)malloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700159 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700160 ASSERT_LE(100U, malloc_usable_size(ptr));
161 memset(ptr, 67, 100);
162
163 ptr = (char *)realloc(ptr, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700164 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700165 ASSERT_LE(200U, malloc_usable_size(ptr));
166 for (size_t i = 0; i < 100; i++) {
167 ASSERT_EQ(67, ptr[i]);
168 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700169 free(ptr);
170}
171
172TEST(malloc, malloc_realloc_smaller) {
173 // Realloc to a smaller size, malloc is used for the original allocation.
174 char *ptr = (char *)malloc(200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700175 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700176 ASSERT_LE(200U, malloc_usable_size(ptr));
177 memset(ptr, 67, 200);
178
179 ptr = (char *)realloc(ptr, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700180 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700181 ASSERT_LE(100U, malloc_usable_size(ptr));
182 for (size_t i = 0; i < 100; i++) {
183 ASSERT_EQ(67, ptr[i]);
184 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700185 free(ptr);
186}
187
188TEST(malloc, malloc_multiple_realloc) {
189 // Multiple reallocs, malloc is used for the original allocation.
190 char *ptr = (char *)malloc(200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700191 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700192 ASSERT_LE(200U, malloc_usable_size(ptr));
193 memset(ptr, 0x23, 200);
194
195 ptr = (char *)realloc(ptr, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700196 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700197 ASSERT_LE(100U, malloc_usable_size(ptr));
198 for (size_t i = 0; i < 100; i++) {
199 ASSERT_EQ(0x23, ptr[i]);
200 }
201
202 ptr = (char*)realloc(ptr, 50);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700203 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700204 ASSERT_LE(50U, malloc_usable_size(ptr));
205 for (size_t i = 0; i < 50; i++) {
206 ASSERT_EQ(0x23, ptr[i]);
207 }
208
209 ptr = (char*)realloc(ptr, 150);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700210 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700211 ASSERT_LE(150U, malloc_usable_size(ptr));
212 for (size_t i = 0; i < 50; i++) {
213 ASSERT_EQ(0x23, ptr[i]);
214 }
215 memset(ptr, 0x23, 150);
216
217 ptr = (char*)realloc(ptr, 425);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700218 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700219 ASSERT_LE(425U, malloc_usable_size(ptr));
220 for (size_t i = 0; i < 150; i++) {
221 ASSERT_EQ(0x23, ptr[i]);
222 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700223 free(ptr);
224}
Christopher Ferrisa4037802014-06-09 19:14:11 -0700225
Christopher Ferris885f3b92013-05-21 17:48:01 -0700226TEST(malloc, calloc_realloc_larger) {
227 // Realloc to a larger size, calloc is used for the original allocation.
228 char *ptr = (char *)calloc(1, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700229 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700230 ASSERT_LE(100U, malloc_usable_size(ptr));
231
232 ptr = (char *)realloc(ptr, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700233 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700234 ASSERT_LE(200U, malloc_usable_size(ptr));
235 for (size_t i = 0; i < 100; i++) {
236 ASSERT_EQ(0, ptr[i]);
237 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700238 free(ptr);
239}
240
241TEST(malloc, calloc_realloc_smaller) {
242 // Realloc to a smaller size, calloc is used for the original allocation.
243 char *ptr = (char *)calloc(1, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700244 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700245 ASSERT_LE(200U, malloc_usable_size(ptr));
246
247 ptr = (char *)realloc(ptr, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700248 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700249 ASSERT_LE(100U, malloc_usable_size(ptr));
250 for (size_t i = 0; i < 100; i++) {
251 ASSERT_EQ(0, ptr[i]);
252 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700253 free(ptr);
254}
255
256TEST(malloc, calloc_multiple_realloc) {
257 // Multiple reallocs, calloc is used for the original allocation.
258 char *ptr = (char *)calloc(1, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700259 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700260 ASSERT_LE(200U, malloc_usable_size(ptr));
261
262 ptr = (char *)realloc(ptr, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700263 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700264 ASSERT_LE(100U, malloc_usable_size(ptr));
265 for (size_t i = 0; i < 100; i++) {
266 ASSERT_EQ(0, ptr[i]);
267 }
268
269 ptr = (char*)realloc(ptr, 50);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700270 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700271 ASSERT_LE(50U, malloc_usable_size(ptr));
272 for (size_t i = 0; i < 50; i++) {
273 ASSERT_EQ(0, ptr[i]);
274 }
275
276 ptr = (char*)realloc(ptr, 150);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700277 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700278 ASSERT_LE(150U, malloc_usable_size(ptr));
279 for (size_t i = 0; i < 50; i++) {
280 ASSERT_EQ(0, ptr[i]);
281 }
282 memset(ptr, 0, 150);
283
284 ptr = (char*)realloc(ptr, 425);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700285 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700286 ASSERT_LE(425U, malloc_usable_size(ptr));
287 for (size_t i = 0; i < 150; i++) {
288 ASSERT_EQ(0, ptr[i]);
289 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700290 free(ptr);
291}
Christopher Ferris72bbd422014-05-08 11:14:03 -0700292
Christopher Ferrisa4037802014-06-09 19:14:11 -0700293TEST(malloc, realloc_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800294 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700295 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700296 ASSERT_EQ(nullptr, realloc(nullptr, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -0700297 ASSERT_EQ(ENOMEM, errno);
298 void* ptr = malloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700299 ASSERT_TRUE(ptr != nullptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700300 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700301 ASSERT_EQ(nullptr, realloc(ptr, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -0700302 ASSERT_EQ(ENOMEM, errno);
303 free(ptr);
Christopher Ferris72bbd422014-05-08 11:14:03 -0700304}
305
Dan Alberte5fdaa42014-06-14 01:04:31 +0000306#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
307extern "C" void* pvalloc(size_t);
308extern "C" void* valloc(size_t);
309
Christopher Ferrisa4037802014-06-09 19:14:11 -0700310TEST(malloc, pvalloc_std) {
311 size_t pagesize = sysconf(_SC_PAGESIZE);
312 void* ptr = pvalloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700313 ASSERT_TRUE(ptr != nullptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700314 ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0);
315 ASSERT_LE(pagesize, malloc_usable_size(ptr));
316 free(ptr);
317}
318
319TEST(malloc, pvalloc_overflow) {
Yi Kong32bc0fc2018-08-02 17:31:13 -0700320 ASSERT_EQ(nullptr, pvalloc(SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -0700321}
322
323TEST(malloc, valloc_std) {
324 size_t pagesize = sysconf(_SC_PAGESIZE);
325 void* ptr = pvalloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700326 ASSERT_TRUE(ptr != nullptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700327 ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0);
328 free(ptr);
329}
330
331TEST(malloc, valloc_overflow) {
Yi Kong32bc0fc2018-08-02 17:31:13 -0700332 ASSERT_EQ(nullptr, valloc(SIZE_MAX));
Christopher Ferris72bbd422014-05-08 11:14:03 -0700333}
Dan Alberte5fdaa42014-06-14 01:04:31 +0000334#endif
Dan Albert4caa1f02014-08-20 09:16:57 -0700335
336TEST(malloc, malloc_info) {
337#ifdef __BIONIC__
338 char* buf;
339 size_t bufsize;
340 FILE* memstream = open_memstream(&buf, &bufsize);
341 ASSERT_NE(nullptr, memstream);
342 ASSERT_EQ(0, malloc_info(0, memstream));
343 ASSERT_EQ(0, fclose(memstream));
344
345 tinyxml2::XMLDocument doc;
346 ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(buf));
347
348 auto root = doc.FirstChildElement();
349 ASSERT_NE(nullptr, root);
350 ASSERT_STREQ("malloc", root->Name());
351 ASSERT_STREQ("jemalloc-1", root->Attribute("version"));
352
353 auto arena = root->FirstChildElement();
354 for (; arena != nullptr; arena = arena->NextSiblingElement()) {
355 int val;
356
357 ASSERT_STREQ("heap", arena->Name());
358 ASSERT_EQ(tinyxml2::XML_SUCCESS, arena->QueryIntAttribute("nr", &val));
359 ASSERT_EQ(tinyxml2::XML_SUCCESS,
360 arena->FirstChildElement("allocated-large")->QueryIntText(&val));
361 ASSERT_EQ(tinyxml2::XML_SUCCESS,
362 arena->FirstChildElement("allocated-huge")->QueryIntText(&val));
363 ASSERT_EQ(tinyxml2::XML_SUCCESS,
364 arena->FirstChildElement("allocated-bins")->QueryIntText(&val));
365 ASSERT_EQ(tinyxml2::XML_SUCCESS,
366 arena->FirstChildElement("bins-total")->QueryIntText(&val));
367
368 auto bin = arena->FirstChildElement("bin");
369 for (; bin != nullptr; bin = bin ->NextSiblingElement()) {
370 if (strcmp(bin->Name(), "bin") == 0) {
371 ASSERT_EQ(tinyxml2::XML_SUCCESS, bin->QueryIntAttribute("nr", &val));
372 ASSERT_EQ(tinyxml2::XML_SUCCESS,
373 bin->FirstChildElement("allocated")->QueryIntText(&val));
374 ASSERT_EQ(tinyxml2::XML_SUCCESS,
375 bin->FirstChildElement("nmalloc")->QueryIntText(&val));
376 ASSERT_EQ(tinyxml2::XML_SUCCESS,
377 bin->FirstChildElement("ndalloc")->QueryIntText(&val));
378 }
379 }
380 }
381#endif
382}
Christopher Ferrisad33ebe2015-12-16 12:07:25 -0800383
384TEST(malloc, calloc_usable_size) {
385 for (size_t size = 1; size <= 2048; size++) {
386 void* pointer = malloc(size);
387 ASSERT_TRUE(pointer != nullptr);
388 memset(pointer, 0xeb, malloc_usable_size(pointer));
389 free(pointer);
390
391 // We should get a previous pointer that has been set to non-zero.
392 // If calloc does not zero out all of the data, this will fail.
393 uint8_t* zero_mem = reinterpret_cast<uint8_t*>(calloc(1, size));
394 ASSERT_TRUE(pointer != nullptr);
395 size_t usable_size = malloc_usable_size(zero_mem);
396 for (size_t i = 0; i < usable_size; i++) {
397 ASSERT_EQ(0, zero_mem[i]) << "Failed at allocation size " << size << " at byte " << i;
398 }
399 free(zero_mem);
400 }
401}
Elliott Hughes884f76e2016-02-10 20:43:22 -0800402
403TEST(malloc, malloc_0) {
404 void* p = malloc(0);
405 ASSERT_TRUE(p != nullptr);
406 free(p);
407}
408
409TEST(malloc, calloc_0_0) {
410 void* p = calloc(0, 0);
411 ASSERT_TRUE(p != nullptr);
412 free(p);
413}
414
415TEST(malloc, calloc_0_1) {
416 void* p = calloc(0, 1);
417 ASSERT_TRUE(p != nullptr);
418 free(p);
419}
420
421TEST(malloc, calloc_1_0) {
422 void* p = calloc(1, 0);
423 ASSERT_TRUE(p != nullptr);
424 free(p);
425}
426
427TEST(malloc, realloc_nullptr_0) {
428 // realloc(nullptr, size) is actually malloc(size).
429 void* p = realloc(nullptr, 0);
430 ASSERT_TRUE(p != nullptr);
431 free(p);
432}
433
434TEST(malloc, realloc_0) {
435 void* p = malloc(1024);
436 ASSERT_TRUE(p != nullptr);
437 // realloc(p, 0) is actually free(p).
438 void* p2 = realloc(p, 0);
439 ASSERT_TRUE(p2 == nullptr);
440}
Christopher Ferris72df6702016-02-11 15:51:31 -0800441
442constexpr size_t MAX_LOOPS = 200;
443
444// Make sure that memory returned by malloc is aligned to allow these data types.
445TEST(malloc, verify_alignment) {
446 uint32_t** values_32 = new uint32_t*[MAX_LOOPS];
447 uint64_t** values_64 = new uint64_t*[MAX_LOOPS];
448 long double** values_ldouble = new long double*[MAX_LOOPS];
449 // Use filler to attempt to force the allocator to get potentially bad alignments.
450 void** filler = new void*[MAX_LOOPS];
451
452 for (size_t i = 0; i < MAX_LOOPS; i++) {
453 // Check uint32_t pointers.
454 filler[i] = malloc(1);
455 ASSERT_TRUE(filler[i] != nullptr);
456
457 values_32[i] = reinterpret_cast<uint32_t*>(malloc(sizeof(uint32_t)));
458 ASSERT_TRUE(values_32[i] != nullptr);
459 *values_32[i] = i;
460 ASSERT_EQ(*values_32[i], i);
461 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_32[i]) & (sizeof(uint32_t) - 1));
462
463 free(filler[i]);
464 }
465
466 for (size_t i = 0; i < MAX_LOOPS; i++) {
467 // Check uint64_t pointers.
468 filler[i] = malloc(1);
469 ASSERT_TRUE(filler[i] != nullptr);
470
471 values_64[i] = reinterpret_cast<uint64_t*>(malloc(sizeof(uint64_t)));
472 ASSERT_TRUE(values_64[i] != nullptr);
473 *values_64[i] = 0x1000 + i;
474 ASSERT_EQ(*values_64[i], 0x1000 + i);
475 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_64[i]) & (sizeof(uint64_t) - 1));
476
477 free(filler[i]);
478 }
479
480 for (size_t i = 0; i < MAX_LOOPS; i++) {
481 // Check long double pointers.
482 filler[i] = malloc(1);
483 ASSERT_TRUE(filler[i] != nullptr);
484
485 values_ldouble[i] = reinterpret_cast<long double*>(malloc(sizeof(long double)));
486 ASSERT_TRUE(values_ldouble[i] != nullptr);
487 *values_ldouble[i] = 5.5 + i;
488 ASSERT_DOUBLE_EQ(*values_ldouble[i], 5.5 + i);
489 // 32 bit glibc has a long double size of 12 bytes, so hardcode the
490 // required alignment to 0x7.
491#if !defined(__BIONIC__) && !defined(__LP64__)
492 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_ldouble[i]) & 0x7);
493#else
494 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_ldouble[i]) & (sizeof(long double) - 1));
495#endif
496
497 free(filler[i]);
498 }
499
500 for (size_t i = 0; i < MAX_LOOPS; i++) {
501 free(values_32[i]);
502 free(values_64[i]);
503 free(values_ldouble[i]);
504 }
505
506 delete[] filler;
507 delete[] values_32;
508 delete[] values_64;
509 delete[] values_ldouble;
510}
Christopher Ferrisa1c0d2f2017-05-15 15:50:19 -0700511
512TEST(malloc, mallopt_smoke) {
513 errno = 0;
514 ASSERT_EQ(0, mallopt(-1000, 1));
515 // mallopt doesn't set errno.
516 ASSERT_EQ(0, errno);
517}
Elliott Hughesb1770852018-09-18 12:52:42 -0700518
Christopher Ferrisaf1b8dd2018-11-07 15:28:16 -0800519TEST(malloc, mallopt_decay) {
520#if defined(__BIONIC__)
Evgenii Stepanov7cc67062019-02-05 18:43:34 -0800521 SKIP_WITH_HWASAN; // hwasan does not implement mallopt
Christopher Ferrisaf1b8dd2018-11-07 15:28:16 -0800522 errno = 0;
523 ASSERT_EQ(1, mallopt(M_DECAY_TIME, 1));
524 ASSERT_EQ(1, mallopt(M_DECAY_TIME, 0));
525 ASSERT_EQ(1, mallopt(M_DECAY_TIME, 1));
526 ASSERT_EQ(1, mallopt(M_DECAY_TIME, 0));
527#else
528 GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
529#endif
530}
531
532TEST(malloc, mallopt_purge) {
533#if defined(__BIONIC__)
Evgenii Stepanov7cc67062019-02-05 18:43:34 -0800534 SKIP_WITH_HWASAN; // hwasan does not implement mallopt
Christopher Ferrisaf1b8dd2018-11-07 15:28:16 -0800535 errno = 0;
536 ASSERT_EQ(1, mallopt(M_PURGE, 0));
537#else
538 GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
539#endif
540}
541
Elliott Hughesb1770852018-09-18 12:52:42 -0700542TEST(malloc, reallocarray_overflow) {
543#if HAVE_REALLOCARRAY
544 // Values that cause overflow to a result small enough (8 on LP64) that malloc would "succeed".
545 size_t a = static_cast<size_t>(INTPTR_MIN + 4);
546 size_t b = 2;
547
548 errno = 0;
549 ASSERT_TRUE(reallocarray(nullptr, a, b) == nullptr);
550 ASSERT_EQ(ENOMEM, errno);
551
552 errno = 0;
553 ASSERT_TRUE(reallocarray(nullptr, b, a) == nullptr);
554 ASSERT_EQ(ENOMEM, errno);
555#else
556 GTEST_LOG_(INFO) << "This test requires a C library with reallocarray.\n";
557#endif
558}
559
560TEST(malloc, reallocarray) {
561#if HAVE_REALLOCARRAY
562 void* p = reallocarray(nullptr, 2, 32);
563 ASSERT_TRUE(p != nullptr);
564 ASSERT_GE(malloc_usable_size(p), 64U);
565#else
566 GTEST_LOG_(INFO) << "This test requires a C library with reallocarray.\n";
567#endif
568}
Christopher Ferris09a19aa2018-11-16 13:28:56 -0800569
570TEST(malloc, mallinfo) {
571#if defined(__BIONIC__)
Evgenii Stepanov7cc67062019-02-05 18:43:34 -0800572 SKIP_WITH_HWASAN; // hwasan does not implement mallinfo
Christopher Ferris09a19aa2018-11-16 13:28:56 -0800573 static size_t sizes[] = {
574 8, 32, 128, 4096, 32768, 131072, 1024000, 10240000, 20480000, 300000000
575 };
576
577 constexpr static size_t kMaxAllocs = 50;
578
579 for (size_t size : sizes) {
580 // If some of these allocations are stuck in a thread cache, then keep
581 // looping until we make an allocation that changes the total size of the
582 // memory allocated.
583 // jemalloc implementations counts the thread cache allocations against
584 // total memory allocated.
585 void* ptrs[kMaxAllocs] = {};
586 bool pass = false;
587 for (size_t i = 0; i < kMaxAllocs; i++) {
588 size_t allocated = mallinfo().uordblks;
589 ptrs[i] = malloc(size);
590 ASSERT_TRUE(ptrs[i] != nullptr);
591 size_t new_allocated = mallinfo().uordblks;
592 if (allocated != new_allocated) {
593 size_t usable_size = malloc_usable_size(ptrs[i]);
Christopher Ferris4e562282019-02-07 14:20:03 -0800594 // Only check if the total got bigger by at least allocation size.
595 // Sometimes the mallinfo numbers can go backwards due to compaction
596 // and/or freeing of cached data.
597 if (new_allocated >= allocated + usable_size) {
598 pass = true;
599 break;
600 }
Christopher Ferris09a19aa2018-11-16 13:28:56 -0800601 }
602 }
603 for (void* ptr : ptrs) {
604 free(ptr);
605 }
606 ASSERT_TRUE(pass)
607 << "For size " << size << " allocated bytes did not increase after "
608 << kMaxAllocs << " allocations.";
609 }
610#else
611 GTEST_LOG_(INFO) << "Host glibc does not pass this test, skipping.\n";
612#endif
613}
Ryan Savitskiecc37e32018-12-14 15:57:21 +0000614
615TEST(android_mallopt, error_on_unexpected_option) {
616#if defined(__BIONIC__)
617 const int unrecognized_option = -1;
618 errno = 0;
619 EXPECT_EQ(false, android_mallopt(unrecognized_option, nullptr, 0));
620 EXPECT_EQ(ENOTSUP, errno);
621#else
622 GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
623#endif
624}
625
Christopher Ferrise4cdbc42019-02-08 17:30:58 -0800626bool IsDynamic() {
627#if defined(__LP64__)
628 Elf64_Ehdr ehdr;
629#else
630 Elf32_Ehdr ehdr;
631#endif
632 std::string path(android::base::GetExecutablePath());
633
634 int fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
635 if (fd == -1) {
636 // Assume dynamic on error.
637 return true;
638 }
639 bool read_completed = android::base::ReadFully(fd, &ehdr, sizeof(ehdr));
640 close(fd);
641 // Assume dynamic in error cases.
642 return !read_completed || ehdr.e_type == ET_DYN;
643}
644
Ryan Savitskiecc37e32018-12-14 15:57:21 +0000645TEST(android_mallopt, init_zygote_child_profiling) {
646#if defined(__BIONIC__)
647 // Successful call.
648 errno = 0;
Christopher Ferrise4cdbc42019-02-08 17:30:58 -0800649 if (IsDynamic()) {
650 EXPECT_EQ(true, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0));
651 EXPECT_EQ(0, errno);
652 } else {
653 // Not supported in static executables.
654 EXPECT_EQ(false, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0));
655 EXPECT_EQ(ENOTSUP, errno);
656 }
Ryan Savitskiecc37e32018-12-14 15:57:21 +0000657
658 // Unexpected arguments rejected.
659 errno = 0;
660 char unexpected = 0;
661 EXPECT_EQ(false, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, &unexpected, 1));
Christopher Ferrise4cdbc42019-02-08 17:30:58 -0800662 if (IsDynamic()) {
663 EXPECT_EQ(EINVAL, errno);
664 } else {
665 EXPECT_EQ(ENOTSUP, errno);
666 }
Ryan Savitskiecc37e32018-12-14 15:57:21 +0000667#else
668 GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
669#endif
670}