blob: 25066915f07212aefd441bb2f50a5c76998aadcd [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 Ferrisa4037802014-06-09 19:14:11 -070019#include <limits.h>
20#include <stdint.h>
Christopher Ferris885f3b92013-05-21 17:48:01 -070021#include <stdlib.h>
22#include <malloc.h>
Christopher Ferrisa4037802014-06-09 19:14:11 -070023#include <unistd.h>
Christopher Ferris885f3b92013-05-21 17:48:01 -070024
Dan Albert4caa1f02014-08-20 09:16:57 -070025#include <tinyxml2.h>
26
Christopher Ferris63619642014-06-16 23:35:53 -070027#include "private/bionic_config.h"
Ryan Savitskiecc37e32018-12-14 15:57:21 +000028#include "private/bionic_malloc.h"
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080029#include "utils.h"
Dan Alberte5fdaa42014-06-14 01:04:31 +000030
Elliott Hughesb1770852018-09-18 12:52:42 -070031#if defined(__BIONIC__)
32#define HAVE_REALLOCARRAY 1
33#else
34#define HAVE_REALLOCARRAY __GLIBC_PREREQ(2, 26)
35#endif
36
Christopher Ferris885f3b92013-05-21 17:48:01 -070037TEST(malloc, malloc_std) {
38 // Simple malloc test.
39 void *ptr = malloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -070040 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -070041 ASSERT_LE(100U, malloc_usable_size(ptr));
Christopher Ferris885f3b92013-05-21 17:48:01 -070042 free(ptr);
43}
44
Christopher Ferrisa4037802014-06-09 19:14:11 -070045TEST(malloc, malloc_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080046 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -070047 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070048 ASSERT_EQ(nullptr, malloc(SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -070049 ASSERT_EQ(ENOMEM, errno);
50}
51
Christopher Ferris885f3b92013-05-21 17:48:01 -070052TEST(malloc, calloc_std) {
53 // Simple calloc test.
54 size_t alloc_len = 100;
55 char *ptr = (char *)calloc(1, alloc_len);
Yi Kong32bc0fc2018-08-02 17:31:13 -070056 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -070057 ASSERT_LE(alloc_len, malloc_usable_size(ptr));
58 for (size_t i = 0; i < alloc_len; i++) {
59 ASSERT_EQ(0, ptr[i]);
60 }
Christopher Ferris885f3b92013-05-21 17:48:01 -070061 free(ptr);
62}
63
Christopher Ferrisa4037802014-06-09 19:14:11 -070064TEST(malloc, calloc_illegal) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080065 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -070066 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070067 ASSERT_EQ(nullptr, calloc(-1, 100));
Christopher Ferrisa4037802014-06-09 19:14:11 -070068 ASSERT_EQ(ENOMEM, errno);
69}
70
71TEST(malloc, calloc_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080072 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -070073 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070074 ASSERT_EQ(nullptr, calloc(1, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -070075 ASSERT_EQ(ENOMEM, errno);
76 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070077 ASSERT_EQ(nullptr, calloc(SIZE_MAX, 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(2, 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(SIZE_MAX, 2));
Christopher Ferrisa4037802014-06-09 19:14:11 -070084 ASSERT_EQ(ENOMEM, errno);
85}
86
Christopher Ferris885f3b92013-05-21 17:48:01 -070087TEST(malloc, memalign_multiple) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080088 SKIP_WITH_HWASAN; // hwasan requires power of 2 alignment.
Christopher Ferris885f3b92013-05-21 17:48:01 -070089 // Memalign test where the alignment is any value.
90 for (size_t i = 0; i <= 12; i++) {
91 for (size_t alignment = 1 << i; alignment < (1U << (i+1)); alignment++) {
Christopher Ferrisa4037802014-06-09 19:14:11 -070092 char *ptr = reinterpret_cast<char*>(memalign(alignment, 100));
Yi Kong32bc0fc2018-08-02 17:31:13 -070093 ASSERT_TRUE(ptr != nullptr) << "Failed at alignment " << alignment;
Christopher Ferrisa4037802014-06-09 19:14:11 -070094 ASSERT_LE(100U, malloc_usable_size(ptr)) << "Failed at alignment " << alignment;
95 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) % ((1U << i)))
96 << "Failed at alignment " << alignment;
Christopher Ferris885f3b92013-05-21 17:48:01 -070097 free(ptr);
98 }
99 }
100}
101
Christopher Ferrisa4037802014-06-09 19:14:11 -0700102TEST(malloc, memalign_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800103 SKIP_WITH_HWASAN;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700104 ASSERT_EQ(nullptr, memalign(4096, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -0700105}
106
107TEST(malloc, memalign_non_power2) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800108 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700109 void* ptr;
110 for (size_t align = 0; align <= 256; align++) {
111 ptr = memalign(align, 1024);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700112 ASSERT_TRUE(ptr != nullptr) << "Failed at align " << align;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700113 free(ptr);
114 }
115}
116
Christopher Ferris885f3b92013-05-21 17:48:01 -0700117TEST(malloc, memalign_realloc) {
118 // Memalign and then realloc the pointer a couple of times.
119 for (size_t alignment = 1; alignment <= 4096; alignment <<= 1) {
120 char *ptr = (char*)memalign(alignment, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700121 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700122 ASSERT_LE(100U, malloc_usable_size(ptr));
123 ASSERT_EQ(0U, (intptr_t)ptr % alignment);
124 memset(ptr, 0x23, 100);
125
126 ptr = (char*)realloc(ptr, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700127 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700128 ASSERT_LE(200U, malloc_usable_size(ptr));
Yi Kong32bc0fc2018-08-02 17:31:13 -0700129 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700130 for (size_t i = 0; i < 100; i++) {
131 ASSERT_EQ(0x23, ptr[i]);
132 }
133 memset(ptr, 0x45, 200);
134
135 ptr = (char*)realloc(ptr, 300);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700136 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700137 ASSERT_LE(300U, malloc_usable_size(ptr));
138 for (size_t i = 0; i < 200; i++) {
139 ASSERT_EQ(0x45, ptr[i]);
140 }
141 memset(ptr, 0x67, 300);
142
143 ptr = (char*)realloc(ptr, 250);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700144 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700145 ASSERT_LE(250U, malloc_usable_size(ptr));
146 for (size_t i = 0; i < 250; i++) {
147 ASSERT_EQ(0x67, ptr[i]);
148 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700149 free(ptr);
150 }
151}
152
153TEST(malloc, malloc_realloc_larger) {
154 // Realloc to a larger size, malloc is used for the original allocation.
155 char *ptr = (char *)malloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700156 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700157 ASSERT_LE(100U, malloc_usable_size(ptr));
158 memset(ptr, 67, 100);
159
160 ptr = (char *)realloc(ptr, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700161 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700162 ASSERT_LE(200U, malloc_usable_size(ptr));
163 for (size_t i = 0; i < 100; i++) {
164 ASSERT_EQ(67, ptr[i]);
165 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700166 free(ptr);
167}
168
169TEST(malloc, malloc_realloc_smaller) {
170 // Realloc to a smaller size, malloc is used for the original allocation.
171 char *ptr = (char *)malloc(200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700172 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700173 ASSERT_LE(200U, malloc_usable_size(ptr));
174 memset(ptr, 67, 200);
175
176 ptr = (char *)realloc(ptr, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700177 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700178 ASSERT_LE(100U, malloc_usable_size(ptr));
179 for (size_t i = 0; i < 100; i++) {
180 ASSERT_EQ(67, ptr[i]);
181 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700182 free(ptr);
183}
184
185TEST(malloc, malloc_multiple_realloc) {
186 // Multiple reallocs, malloc is used for the original allocation.
187 char *ptr = (char *)malloc(200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700188 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700189 ASSERT_LE(200U, malloc_usable_size(ptr));
190 memset(ptr, 0x23, 200);
191
192 ptr = (char *)realloc(ptr, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700193 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700194 ASSERT_LE(100U, malloc_usable_size(ptr));
195 for (size_t i = 0; i < 100; i++) {
196 ASSERT_EQ(0x23, ptr[i]);
197 }
198
199 ptr = (char*)realloc(ptr, 50);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700200 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700201 ASSERT_LE(50U, malloc_usable_size(ptr));
202 for (size_t i = 0; i < 50; i++) {
203 ASSERT_EQ(0x23, ptr[i]);
204 }
205
206 ptr = (char*)realloc(ptr, 150);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700207 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700208 ASSERT_LE(150U, malloc_usable_size(ptr));
209 for (size_t i = 0; i < 50; i++) {
210 ASSERT_EQ(0x23, ptr[i]);
211 }
212 memset(ptr, 0x23, 150);
213
214 ptr = (char*)realloc(ptr, 425);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700215 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700216 ASSERT_LE(425U, malloc_usable_size(ptr));
217 for (size_t i = 0; i < 150; i++) {
218 ASSERT_EQ(0x23, ptr[i]);
219 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700220 free(ptr);
221}
Christopher Ferrisa4037802014-06-09 19:14:11 -0700222
Christopher Ferris885f3b92013-05-21 17:48:01 -0700223TEST(malloc, calloc_realloc_larger) {
224 // Realloc to a larger size, calloc is used for the original allocation.
225 char *ptr = (char *)calloc(1, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700226 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700227 ASSERT_LE(100U, malloc_usable_size(ptr));
228
229 ptr = (char *)realloc(ptr, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700230 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700231 ASSERT_LE(200U, malloc_usable_size(ptr));
232 for (size_t i = 0; i < 100; i++) {
233 ASSERT_EQ(0, ptr[i]);
234 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700235 free(ptr);
236}
237
238TEST(malloc, calloc_realloc_smaller) {
239 // Realloc to a smaller size, calloc is used for the original allocation.
240 char *ptr = (char *)calloc(1, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700241 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700242 ASSERT_LE(200U, malloc_usable_size(ptr));
243
244 ptr = (char *)realloc(ptr, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700245 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700246 ASSERT_LE(100U, malloc_usable_size(ptr));
247 for (size_t i = 0; i < 100; i++) {
248 ASSERT_EQ(0, ptr[i]);
249 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700250 free(ptr);
251}
252
253TEST(malloc, calloc_multiple_realloc) {
254 // Multiple reallocs, calloc is used for the original allocation.
255 char *ptr = (char *)calloc(1, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700256 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700257 ASSERT_LE(200U, malloc_usable_size(ptr));
258
259 ptr = (char *)realloc(ptr, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700260 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700261 ASSERT_LE(100U, malloc_usable_size(ptr));
262 for (size_t i = 0; i < 100; i++) {
263 ASSERT_EQ(0, ptr[i]);
264 }
265
266 ptr = (char*)realloc(ptr, 50);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700267 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700268 ASSERT_LE(50U, malloc_usable_size(ptr));
269 for (size_t i = 0; i < 50; i++) {
270 ASSERT_EQ(0, ptr[i]);
271 }
272
273 ptr = (char*)realloc(ptr, 150);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700274 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700275 ASSERT_LE(150U, malloc_usable_size(ptr));
276 for (size_t i = 0; i < 50; i++) {
277 ASSERT_EQ(0, ptr[i]);
278 }
279 memset(ptr, 0, 150);
280
281 ptr = (char*)realloc(ptr, 425);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700282 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700283 ASSERT_LE(425U, malloc_usable_size(ptr));
284 for (size_t i = 0; i < 150; i++) {
285 ASSERT_EQ(0, ptr[i]);
286 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700287 free(ptr);
288}
Christopher Ferris72bbd422014-05-08 11:14:03 -0700289
Christopher Ferrisa4037802014-06-09 19:14:11 -0700290TEST(malloc, realloc_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800291 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700292 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700293 ASSERT_EQ(nullptr, realloc(nullptr, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -0700294 ASSERT_EQ(ENOMEM, errno);
295 void* ptr = malloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700296 ASSERT_TRUE(ptr != nullptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700297 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700298 ASSERT_EQ(nullptr, realloc(ptr, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -0700299 ASSERT_EQ(ENOMEM, errno);
300 free(ptr);
Christopher Ferris72bbd422014-05-08 11:14:03 -0700301}
302
Dan Alberte5fdaa42014-06-14 01:04:31 +0000303#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
304extern "C" void* pvalloc(size_t);
305extern "C" void* valloc(size_t);
306
Christopher Ferrisa4037802014-06-09 19:14:11 -0700307TEST(malloc, pvalloc_std) {
308 size_t pagesize = sysconf(_SC_PAGESIZE);
309 void* ptr = pvalloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700310 ASSERT_TRUE(ptr != nullptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700311 ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0);
312 ASSERT_LE(pagesize, malloc_usable_size(ptr));
313 free(ptr);
314}
315
316TEST(malloc, pvalloc_overflow) {
Yi Kong32bc0fc2018-08-02 17:31:13 -0700317 ASSERT_EQ(nullptr, pvalloc(SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -0700318}
319
320TEST(malloc, valloc_std) {
321 size_t pagesize = sysconf(_SC_PAGESIZE);
322 void* ptr = pvalloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700323 ASSERT_TRUE(ptr != nullptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700324 ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0);
325 free(ptr);
326}
327
328TEST(malloc, valloc_overflow) {
Yi Kong32bc0fc2018-08-02 17:31:13 -0700329 ASSERT_EQ(nullptr, valloc(SIZE_MAX));
Christopher Ferris72bbd422014-05-08 11:14:03 -0700330}
Dan Alberte5fdaa42014-06-14 01:04:31 +0000331#endif
Dan Albert4caa1f02014-08-20 09:16:57 -0700332
333TEST(malloc, malloc_info) {
334#ifdef __BIONIC__
335 char* buf;
336 size_t bufsize;
337 FILE* memstream = open_memstream(&buf, &bufsize);
338 ASSERT_NE(nullptr, memstream);
339 ASSERT_EQ(0, malloc_info(0, memstream));
340 ASSERT_EQ(0, fclose(memstream));
341
342 tinyxml2::XMLDocument doc;
343 ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(buf));
344
345 auto root = doc.FirstChildElement();
346 ASSERT_NE(nullptr, root);
347 ASSERT_STREQ("malloc", root->Name());
348 ASSERT_STREQ("jemalloc-1", root->Attribute("version"));
349
350 auto arena = root->FirstChildElement();
351 for (; arena != nullptr; arena = arena->NextSiblingElement()) {
352 int val;
353
354 ASSERT_STREQ("heap", arena->Name());
355 ASSERT_EQ(tinyxml2::XML_SUCCESS, arena->QueryIntAttribute("nr", &val));
356 ASSERT_EQ(tinyxml2::XML_SUCCESS,
357 arena->FirstChildElement("allocated-large")->QueryIntText(&val));
358 ASSERT_EQ(tinyxml2::XML_SUCCESS,
359 arena->FirstChildElement("allocated-huge")->QueryIntText(&val));
360 ASSERT_EQ(tinyxml2::XML_SUCCESS,
361 arena->FirstChildElement("allocated-bins")->QueryIntText(&val));
362 ASSERT_EQ(tinyxml2::XML_SUCCESS,
363 arena->FirstChildElement("bins-total")->QueryIntText(&val));
364
365 auto bin = arena->FirstChildElement("bin");
366 for (; bin != nullptr; bin = bin ->NextSiblingElement()) {
367 if (strcmp(bin->Name(), "bin") == 0) {
368 ASSERT_EQ(tinyxml2::XML_SUCCESS, bin->QueryIntAttribute("nr", &val));
369 ASSERT_EQ(tinyxml2::XML_SUCCESS,
370 bin->FirstChildElement("allocated")->QueryIntText(&val));
371 ASSERT_EQ(tinyxml2::XML_SUCCESS,
372 bin->FirstChildElement("nmalloc")->QueryIntText(&val));
373 ASSERT_EQ(tinyxml2::XML_SUCCESS,
374 bin->FirstChildElement("ndalloc")->QueryIntText(&val));
375 }
376 }
377 }
378#endif
379}
Christopher Ferrisad33ebe2015-12-16 12:07:25 -0800380
381TEST(malloc, calloc_usable_size) {
382 for (size_t size = 1; size <= 2048; size++) {
383 void* pointer = malloc(size);
384 ASSERT_TRUE(pointer != nullptr);
385 memset(pointer, 0xeb, malloc_usable_size(pointer));
386 free(pointer);
387
388 // We should get a previous pointer that has been set to non-zero.
389 // If calloc does not zero out all of the data, this will fail.
390 uint8_t* zero_mem = reinterpret_cast<uint8_t*>(calloc(1, size));
391 ASSERT_TRUE(pointer != nullptr);
392 size_t usable_size = malloc_usable_size(zero_mem);
393 for (size_t i = 0; i < usable_size; i++) {
394 ASSERT_EQ(0, zero_mem[i]) << "Failed at allocation size " << size << " at byte " << i;
395 }
396 free(zero_mem);
397 }
398}
Elliott Hughes884f76e2016-02-10 20:43:22 -0800399
400TEST(malloc, malloc_0) {
401 void* p = malloc(0);
402 ASSERT_TRUE(p != nullptr);
403 free(p);
404}
405
406TEST(malloc, calloc_0_0) {
407 void* p = calloc(0, 0);
408 ASSERT_TRUE(p != nullptr);
409 free(p);
410}
411
412TEST(malloc, calloc_0_1) {
413 void* p = calloc(0, 1);
414 ASSERT_TRUE(p != nullptr);
415 free(p);
416}
417
418TEST(malloc, calloc_1_0) {
419 void* p = calloc(1, 0);
420 ASSERT_TRUE(p != nullptr);
421 free(p);
422}
423
424TEST(malloc, realloc_nullptr_0) {
425 // realloc(nullptr, size) is actually malloc(size).
426 void* p = realloc(nullptr, 0);
427 ASSERT_TRUE(p != nullptr);
428 free(p);
429}
430
431TEST(malloc, realloc_0) {
432 void* p = malloc(1024);
433 ASSERT_TRUE(p != nullptr);
434 // realloc(p, 0) is actually free(p).
435 void* p2 = realloc(p, 0);
436 ASSERT_TRUE(p2 == nullptr);
437}
Christopher Ferris72df6702016-02-11 15:51:31 -0800438
439constexpr size_t MAX_LOOPS = 200;
440
441// Make sure that memory returned by malloc is aligned to allow these data types.
442TEST(malloc, verify_alignment) {
443 uint32_t** values_32 = new uint32_t*[MAX_LOOPS];
444 uint64_t** values_64 = new uint64_t*[MAX_LOOPS];
445 long double** values_ldouble = new long double*[MAX_LOOPS];
446 // Use filler to attempt to force the allocator to get potentially bad alignments.
447 void** filler = new void*[MAX_LOOPS];
448
449 for (size_t i = 0; i < MAX_LOOPS; i++) {
450 // Check uint32_t pointers.
451 filler[i] = malloc(1);
452 ASSERT_TRUE(filler[i] != nullptr);
453
454 values_32[i] = reinterpret_cast<uint32_t*>(malloc(sizeof(uint32_t)));
455 ASSERT_TRUE(values_32[i] != nullptr);
456 *values_32[i] = i;
457 ASSERT_EQ(*values_32[i], i);
458 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_32[i]) & (sizeof(uint32_t) - 1));
459
460 free(filler[i]);
461 }
462
463 for (size_t i = 0; i < MAX_LOOPS; i++) {
464 // Check uint64_t pointers.
465 filler[i] = malloc(1);
466 ASSERT_TRUE(filler[i] != nullptr);
467
468 values_64[i] = reinterpret_cast<uint64_t*>(malloc(sizeof(uint64_t)));
469 ASSERT_TRUE(values_64[i] != nullptr);
470 *values_64[i] = 0x1000 + i;
471 ASSERT_EQ(*values_64[i], 0x1000 + i);
472 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_64[i]) & (sizeof(uint64_t) - 1));
473
474 free(filler[i]);
475 }
476
477 for (size_t i = 0; i < MAX_LOOPS; i++) {
478 // Check long double pointers.
479 filler[i] = malloc(1);
480 ASSERT_TRUE(filler[i] != nullptr);
481
482 values_ldouble[i] = reinterpret_cast<long double*>(malloc(sizeof(long double)));
483 ASSERT_TRUE(values_ldouble[i] != nullptr);
484 *values_ldouble[i] = 5.5 + i;
485 ASSERT_DOUBLE_EQ(*values_ldouble[i], 5.5 + i);
486 // 32 bit glibc has a long double size of 12 bytes, so hardcode the
487 // required alignment to 0x7.
488#if !defined(__BIONIC__) && !defined(__LP64__)
489 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_ldouble[i]) & 0x7);
490#else
491 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_ldouble[i]) & (sizeof(long double) - 1));
492#endif
493
494 free(filler[i]);
495 }
496
497 for (size_t i = 0; i < MAX_LOOPS; i++) {
498 free(values_32[i]);
499 free(values_64[i]);
500 free(values_ldouble[i]);
501 }
502
503 delete[] filler;
504 delete[] values_32;
505 delete[] values_64;
506 delete[] values_ldouble;
507}
Christopher Ferrisa1c0d2f2017-05-15 15:50:19 -0700508
509TEST(malloc, mallopt_smoke) {
510 errno = 0;
511 ASSERT_EQ(0, mallopt(-1000, 1));
512 // mallopt doesn't set errno.
513 ASSERT_EQ(0, errno);
514}
Elliott Hughesb1770852018-09-18 12:52:42 -0700515
Christopher Ferrisaf1b8dd2018-11-07 15:28:16 -0800516TEST(malloc, mallopt_decay) {
517#if defined(__BIONIC__)
518 errno = 0;
519 ASSERT_EQ(1, mallopt(M_DECAY_TIME, 1));
520 ASSERT_EQ(1, mallopt(M_DECAY_TIME, 0));
521 ASSERT_EQ(1, mallopt(M_DECAY_TIME, 1));
522 ASSERT_EQ(1, mallopt(M_DECAY_TIME, 0));
523#else
524 GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
525#endif
526}
527
528TEST(malloc, mallopt_purge) {
529#if defined(__BIONIC__)
530 errno = 0;
531 ASSERT_EQ(1, mallopt(M_PURGE, 0));
532#else
533 GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
534#endif
535}
536
Elliott Hughesb1770852018-09-18 12:52:42 -0700537TEST(malloc, reallocarray_overflow) {
538#if HAVE_REALLOCARRAY
539 // Values that cause overflow to a result small enough (8 on LP64) that malloc would "succeed".
540 size_t a = static_cast<size_t>(INTPTR_MIN + 4);
541 size_t b = 2;
542
543 errno = 0;
544 ASSERT_TRUE(reallocarray(nullptr, a, b) == nullptr);
545 ASSERT_EQ(ENOMEM, errno);
546
547 errno = 0;
548 ASSERT_TRUE(reallocarray(nullptr, b, a) == nullptr);
549 ASSERT_EQ(ENOMEM, errno);
550#else
551 GTEST_LOG_(INFO) << "This test requires a C library with reallocarray.\n";
552#endif
553}
554
555TEST(malloc, reallocarray) {
556#if HAVE_REALLOCARRAY
557 void* p = reallocarray(nullptr, 2, 32);
558 ASSERT_TRUE(p != nullptr);
559 ASSERT_GE(malloc_usable_size(p), 64U);
560#else
561 GTEST_LOG_(INFO) << "This test requires a C library with reallocarray.\n";
562#endif
563}
Christopher Ferris09a19aa2018-11-16 13:28:56 -0800564
565TEST(malloc, mallinfo) {
566#if defined(__BIONIC__)
567 static size_t sizes[] = {
568 8, 32, 128, 4096, 32768, 131072, 1024000, 10240000, 20480000, 300000000
569 };
570
571 constexpr static size_t kMaxAllocs = 50;
572
573 for (size_t size : sizes) {
574 // If some of these allocations are stuck in a thread cache, then keep
575 // looping until we make an allocation that changes the total size of the
576 // memory allocated.
577 // jemalloc implementations counts the thread cache allocations against
578 // total memory allocated.
579 void* ptrs[kMaxAllocs] = {};
580 bool pass = false;
581 for (size_t i = 0; i < kMaxAllocs; i++) {
582 size_t allocated = mallinfo().uordblks;
583 ptrs[i] = malloc(size);
584 ASSERT_TRUE(ptrs[i] != nullptr);
585 size_t new_allocated = mallinfo().uordblks;
586 if (allocated != new_allocated) {
587 size_t usable_size = malloc_usable_size(ptrs[i]);
588 ASSERT_GE(new_allocated, allocated + usable_size)
589 << "Failed at size " << size << " usable size " << usable_size;
590 pass = true;
591 break;
592 }
593 }
594 for (void* ptr : ptrs) {
595 free(ptr);
596 }
597 ASSERT_TRUE(pass)
598 << "For size " << size << " allocated bytes did not increase after "
599 << kMaxAllocs << " allocations.";
600 }
601#else
602 GTEST_LOG_(INFO) << "Host glibc does not pass this test, skipping.\n";
603#endif
604}
Ryan Savitskiecc37e32018-12-14 15:57:21 +0000605
606TEST(android_mallopt, error_on_unexpected_option) {
607#if defined(__BIONIC__)
608 const int unrecognized_option = -1;
609 errno = 0;
610 EXPECT_EQ(false, android_mallopt(unrecognized_option, nullptr, 0));
611 EXPECT_EQ(ENOTSUP, errno);
612#else
613 GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
614#endif
615}
616
617TEST(android_mallopt, init_zygote_child_profiling) {
618#if defined(__BIONIC__)
619 // Successful call.
620 errno = 0;
621 EXPECT_EQ(true, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0));
622 EXPECT_EQ(0, errno);
623
624 // Unexpected arguments rejected.
625 errno = 0;
626 char unexpected = 0;
627 EXPECT_EQ(false, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, &unexpected, 1));
628 EXPECT_EQ(EINVAL, errno);
629#else
630 GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
631#endif
632}
633