blob: 4da6d3f4d0a18e18a11980f3c6245b936751e799 [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>
Ryan Savitski175c8862020-01-02 19:54:57 +000021#include <malloc.h>
Christopher Ferris1fc5ccf2019-02-15 18:06:15 -080022#include <pthread.h>
Ryan Savitski175c8862020-01-02 19:54:57 +000023#include <signal.h>
Christopher Ferrisa4037802014-06-09 19:14:11 -070024#include <stdint.h>
Christopher Ferris6c619a02019-03-01 17:59:51 -080025#include <stdio.h>
Christopher Ferris885f3b92013-05-21 17:48:01 -070026#include <stdlib.h>
Christopher Ferris1fc5ccf2019-02-15 18:06:15 -080027#include <string.h>
28#include <sys/types.h>
29#include <sys/wait.h>
Christopher Ferrisa4037802014-06-09 19:14:11 -070030#include <unistd.h>
Christopher Ferris885f3b92013-05-21 17:48:01 -070031
Christopher Ferris1fc5ccf2019-02-15 18:06:15 -080032#include <atomic>
Christopher Ferrisf32494c2020-01-08 14:19:10 -080033#include <thread>
34
Dan Albert4caa1f02014-08-20 09:16:57 -070035#include <tinyxml2.h>
36
Christopher Ferrise4cdbc42019-02-08 17:30:58 -080037#include <android-base/file.h>
38
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080039#include "utils.h"
Dan Alberte5fdaa42014-06-14 01:04:31 +000040
Elliott Hughesb1770852018-09-18 12:52:42 -070041#if defined(__BIONIC__)
Christopher Ferrisb874c332020-01-21 16:39:05 -080042
43#include "platform/bionic/malloc.h"
44#include "platform/bionic/reserved_signals.h"
45#include "private/bionic_config.h"
46
Elliott Hughesb1770852018-09-18 12:52:42 -070047#define HAVE_REALLOCARRAY 1
Christopher Ferrisb874c332020-01-21 16:39:05 -080048
Elliott Hughesb1770852018-09-18 12:52:42 -070049#else
Christopher Ferrisb874c332020-01-21 16:39:05 -080050
Elliott Hughesb1770852018-09-18 12:52:42 -070051#define HAVE_REALLOCARRAY __GLIBC_PREREQ(2, 26)
Christopher Ferrisb874c332020-01-21 16:39:05 -080052
Elliott Hughesb1770852018-09-18 12:52:42 -070053#endif
54
Christopher Ferris885f3b92013-05-21 17:48:01 -070055TEST(malloc, malloc_std) {
56 // Simple malloc test.
57 void *ptr = malloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -070058 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -070059 ASSERT_LE(100U, malloc_usable_size(ptr));
Christopher Ferris885f3b92013-05-21 17:48:01 -070060 free(ptr);
61}
62
Christopher Ferrisa4037802014-06-09 19:14:11 -070063TEST(malloc, malloc_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080064 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -070065 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070066 ASSERT_EQ(nullptr, malloc(SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -070067 ASSERT_EQ(ENOMEM, errno);
68}
69
Christopher Ferris885f3b92013-05-21 17:48:01 -070070TEST(malloc, calloc_std) {
71 // Simple calloc test.
72 size_t alloc_len = 100;
73 char *ptr = (char *)calloc(1, alloc_len);
Yi Kong32bc0fc2018-08-02 17:31:13 -070074 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -070075 ASSERT_LE(alloc_len, malloc_usable_size(ptr));
76 for (size_t i = 0; i < alloc_len; i++) {
77 ASSERT_EQ(0, ptr[i]);
78 }
Christopher Ferris885f3b92013-05-21 17:48:01 -070079 free(ptr);
80}
81
Christopher Ferrisa4037802014-06-09 19:14:11 -070082TEST(malloc, calloc_illegal) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080083 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -070084 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070085 ASSERT_EQ(nullptr, calloc(-1, 100));
Christopher Ferrisa4037802014-06-09 19:14:11 -070086 ASSERT_EQ(ENOMEM, errno);
87}
88
89TEST(malloc, calloc_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080090 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -070091 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070092 ASSERT_EQ(nullptr, calloc(1, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -070093 ASSERT_EQ(ENOMEM, errno);
94 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070095 ASSERT_EQ(nullptr, calloc(SIZE_MAX, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -070096 ASSERT_EQ(ENOMEM, errno);
97 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070098 ASSERT_EQ(nullptr, calloc(2, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -070099 ASSERT_EQ(ENOMEM, errno);
100 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700101 ASSERT_EQ(nullptr, calloc(SIZE_MAX, 2));
Christopher Ferrisa4037802014-06-09 19:14:11 -0700102 ASSERT_EQ(ENOMEM, errno);
103}
104
Christopher Ferris885f3b92013-05-21 17:48:01 -0700105TEST(malloc, memalign_multiple) {
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800106 SKIP_WITH_HWASAN << "hwasan requires power of 2 alignment";
Christopher Ferris885f3b92013-05-21 17:48:01 -0700107 // Memalign test where the alignment is any value.
108 for (size_t i = 0; i <= 12; i++) {
109 for (size_t alignment = 1 << i; alignment < (1U << (i+1)); alignment++) {
Christopher Ferrisa4037802014-06-09 19:14:11 -0700110 char *ptr = reinterpret_cast<char*>(memalign(alignment, 100));
Yi Kong32bc0fc2018-08-02 17:31:13 -0700111 ASSERT_TRUE(ptr != nullptr) << "Failed at alignment " << alignment;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700112 ASSERT_LE(100U, malloc_usable_size(ptr)) << "Failed at alignment " << alignment;
113 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) % ((1U << i)))
114 << "Failed at alignment " << alignment;
Christopher Ferris885f3b92013-05-21 17:48:01 -0700115 free(ptr);
116 }
117 }
118}
119
Christopher Ferrisa4037802014-06-09 19:14:11 -0700120TEST(malloc, memalign_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800121 SKIP_WITH_HWASAN;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700122 ASSERT_EQ(nullptr, memalign(4096, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -0700123}
124
125TEST(malloc, memalign_non_power2) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800126 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700127 void* ptr;
128 for (size_t align = 0; align <= 256; align++) {
129 ptr = memalign(align, 1024);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700130 ASSERT_TRUE(ptr != nullptr) << "Failed at align " << align;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700131 free(ptr);
132 }
133}
134
Christopher Ferris885f3b92013-05-21 17:48:01 -0700135TEST(malloc, memalign_realloc) {
136 // Memalign and then realloc the pointer a couple of times.
137 for (size_t alignment = 1; alignment <= 4096; alignment <<= 1) {
138 char *ptr = (char*)memalign(alignment, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700139 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700140 ASSERT_LE(100U, malloc_usable_size(ptr));
141 ASSERT_EQ(0U, (intptr_t)ptr % alignment);
142 memset(ptr, 0x23, 100);
143
144 ptr = (char*)realloc(ptr, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700145 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700146 ASSERT_LE(200U, malloc_usable_size(ptr));
Yi Kong32bc0fc2018-08-02 17:31:13 -0700147 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700148 for (size_t i = 0; i < 100; i++) {
149 ASSERT_EQ(0x23, ptr[i]);
150 }
151 memset(ptr, 0x45, 200);
152
153 ptr = (char*)realloc(ptr, 300);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700154 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700155 ASSERT_LE(300U, malloc_usable_size(ptr));
156 for (size_t i = 0; i < 200; i++) {
157 ASSERT_EQ(0x45, ptr[i]);
158 }
159 memset(ptr, 0x67, 300);
160
161 ptr = (char*)realloc(ptr, 250);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700162 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700163 ASSERT_LE(250U, malloc_usable_size(ptr));
164 for (size_t i = 0; i < 250; i++) {
165 ASSERT_EQ(0x67, ptr[i]);
166 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700167 free(ptr);
168 }
169}
170
171TEST(malloc, malloc_realloc_larger) {
172 // Realloc to a larger size, malloc is used for the original allocation.
173 char *ptr = (char *)malloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700174 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700175 ASSERT_LE(100U, malloc_usable_size(ptr));
176 memset(ptr, 67, 100);
177
178 ptr = (char *)realloc(ptr, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700179 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700180 ASSERT_LE(200U, malloc_usable_size(ptr));
181 for (size_t i = 0; i < 100; i++) {
182 ASSERT_EQ(67, ptr[i]);
183 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700184 free(ptr);
185}
186
187TEST(malloc, malloc_realloc_smaller) {
188 // Realloc to a smaller size, malloc is used for the original allocation.
189 char *ptr = (char *)malloc(200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700190 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700191 ASSERT_LE(200U, malloc_usable_size(ptr));
192 memset(ptr, 67, 200);
193
194 ptr = (char *)realloc(ptr, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700195 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700196 ASSERT_LE(100U, malloc_usable_size(ptr));
197 for (size_t i = 0; i < 100; i++) {
198 ASSERT_EQ(67, ptr[i]);
199 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700200 free(ptr);
201}
202
203TEST(malloc, malloc_multiple_realloc) {
204 // Multiple reallocs, malloc is used for the original allocation.
205 char *ptr = (char *)malloc(200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700206 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700207 ASSERT_LE(200U, malloc_usable_size(ptr));
208 memset(ptr, 0x23, 200);
209
210 ptr = (char *)realloc(ptr, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700211 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700212 ASSERT_LE(100U, malloc_usable_size(ptr));
213 for (size_t i = 0; i < 100; i++) {
214 ASSERT_EQ(0x23, ptr[i]);
215 }
216
217 ptr = (char*)realloc(ptr, 50);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700218 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700219 ASSERT_LE(50U, malloc_usable_size(ptr));
220 for (size_t i = 0; i < 50; i++) {
221 ASSERT_EQ(0x23, ptr[i]);
222 }
223
224 ptr = (char*)realloc(ptr, 150);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700225 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700226 ASSERT_LE(150U, malloc_usable_size(ptr));
227 for (size_t i = 0; i < 50; i++) {
228 ASSERT_EQ(0x23, ptr[i]);
229 }
230 memset(ptr, 0x23, 150);
231
232 ptr = (char*)realloc(ptr, 425);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700233 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700234 ASSERT_LE(425U, malloc_usable_size(ptr));
235 for (size_t i = 0; i < 150; i++) {
236 ASSERT_EQ(0x23, ptr[i]);
237 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700238 free(ptr);
239}
Christopher Ferrisa4037802014-06-09 19:14:11 -0700240
Christopher Ferris885f3b92013-05-21 17:48:01 -0700241TEST(malloc, calloc_realloc_larger) {
242 // Realloc to a larger size, calloc is used for the original allocation.
243 char *ptr = (char *)calloc(1, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700244 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700245 ASSERT_LE(100U, malloc_usable_size(ptr));
246
247 ptr = (char *)realloc(ptr, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700248 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700249 ASSERT_LE(200U, 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_realloc_smaller) {
257 // Realloc to a smaller size, 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 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700268 free(ptr);
269}
270
271TEST(malloc, calloc_multiple_realloc) {
272 // Multiple reallocs, calloc is used for the original allocation.
273 char *ptr = (char *)calloc(1, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700274 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700275 ASSERT_LE(200U, malloc_usable_size(ptr));
276
277 ptr = (char *)realloc(ptr, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700278 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700279 ASSERT_LE(100U, malloc_usable_size(ptr));
280 for (size_t i = 0; i < 100; i++) {
281 ASSERT_EQ(0, ptr[i]);
282 }
283
284 ptr = (char*)realloc(ptr, 50);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700285 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700286 ASSERT_LE(50U, malloc_usable_size(ptr));
287 for (size_t i = 0; i < 50; i++) {
288 ASSERT_EQ(0, ptr[i]);
289 }
290
291 ptr = (char*)realloc(ptr, 150);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700292 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700293 ASSERT_LE(150U, malloc_usable_size(ptr));
294 for (size_t i = 0; i < 50; i++) {
295 ASSERT_EQ(0, ptr[i]);
296 }
297 memset(ptr, 0, 150);
298
299 ptr = (char*)realloc(ptr, 425);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700300 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700301 ASSERT_LE(425U, malloc_usable_size(ptr));
302 for (size_t i = 0; i < 150; i++) {
303 ASSERT_EQ(0, ptr[i]);
304 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700305 free(ptr);
306}
Christopher Ferris72bbd422014-05-08 11:14:03 -0700307
Christopher Ferrisa4037802014-06-09 19:14:11 -0700308TEST(malloc, realloc_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800309 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700310 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700311 ASSERT_EQ(nullptr, realloc(nullptr, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -0700312 ASSERT_EQ(ENOMEM, errno);
313 void* ptr = malloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700314 ASSERT_TRUE(ptr != nullptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700315 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700316 ASSERT_EQ(nullptr, realloc(ptr, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -0700317 ASSERT_EQ(ENOMEM, errno);
318 free(ptr);
Christopher Ferris72bbd422014-05-08 11:14:03 -0700319}
320
Dan Alberte5fdaa42014-06-14 01:04:31 +0000321#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
322extern "C" void* pvalloc(size_t);
323extern "C" void* valloc(size_t);
Christopher Ferris804cebe2019-06-20 08:50:23 -0700324#endif
Dan Alberte5fdaa42014-06-14 01:04:31 +0000325
Christopher Ferrisa4037802014-06-09 19:14:11 -0700326TEST(malloc, pvalloc_std) {
Christopher Ferris804cebe2019-06-20 08:50:23 -0700327#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
Christopher Ferrisa4037802014-06-09 19:14:11 -0700328 size_t pagesize = sysconf(_SC_PAGESIZE);
329 void* ptr = pvalloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700330 ASSERT_TRUE(ptr != nullptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700331 ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0);
332 ASSERT_LE(pagesize, malloc_usable_size(ptr));
333 free(ptr);
Christopher Ferris804cebe2019-06-20 08:50:23 -0700334#else
335 GTEST_SKIP() << "pvalloc not supported.";
336#endif
Christopher Ferrisa4037802014-06-09 19:14:11 -0700337}
338
339TEST(malloc, pvalloc_overflow) {
Christopher Ferris804cebe2019-06-20 08:50:23 -0700340#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
Yi Kong32bc0fc2018-08-02 17:31:13 -0700341 ASSERT_EQ(nullptr, pvalloc(SIZE_MAX));
Christopher Ferris804cebe2019-06-20 08:50:23 -0700342#else
343 GTEST_SKIP() << "pvalloc not supported.";
344#endif
Christopher Ferrisa4037802014-06-09 19:14:11 -0700345}
346
347TEST(malloc, valloc_std) {
Christopher Ferris804cebe2019-06-20 08:50:23 -0700348#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
Christopher Ferrisa4037802014-06-09 19:14:11 -0700349 size_t pagesize = sysconf(_SC_PAGESIZE);
Christopher Ferrisd5ab0a52019-06-19 12:03:57 -0700350 void* ptr = valloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700351 ASSERT_TRUE(ptr != nullptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700352 ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0);
353 free(ptr);
Christopher Ferris804cebe2019-06-20 08:50:23 -0700354#else
355 GTEST_SKIP() << "valloc not supported.";
356#endif
Christopher Ferrisa4037802014-06-09 19:14:11 -0700357}
358
359TEST(malloc, valloc_overflow) {
Christopher Ferris804cebe2019-06-20 08:50:23 -0700360#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
Yi Kong32bc0fc2018-08-02 17:31:13 -0700361 ASSERT_EQ(nullptr, valloc(SIZE_MAX));
Christopher Ferris804cebe2019-06-20 08:50:23 -0700362#else
363 GTEST_SKIP() << "valloc not supported.";
Dan Alberte5fdaa42014-06-14 01:04:31 +0000364#endif
Christopher Ferris804cebe2019-06-20 08:50:23 -0700365}
Dan Albert4caa1f02014-08-20 09:16:57 -0700366
367TEST(malloc, malloc_info) {
368#ifdef __BIONIC__
Evgenii Stepanov8de6b462019-03-22 13:22:28 -0700369 SKIP_WITH_HWASAN; // hwasan does not implement malloc_info
Christopher Ferrisff88fb02019-11-04 18:40:00 -0800370
371 TemporaryFile tf;
372 ASSERT_TRUE(tf.fd != -1);
373 FILE* fp = fdopen(tf.fd, "w+");
374 tf.release();
375 ASSERT_TRUE(fp != nullptr);
376 ASSERT_EQ(0, malloc_info(0, fp));
377 ASSERT_EQ(0, fclose(fp));
378
379 std::string contents;
380 ASSERT_TRUE(android::base::ReadFileToString(tf.path, &contents));
Dan Albert4caa1f02014-08-20 09:16:57 -0700381
382 tinyxml2::XMLDocument doc;
Christopher Ferrisff88fb02019-11-04 18:40:00 -0800383 ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(contents.c_str()));
Dan Albert4caa1f02014-08-20 09:16:57 -0700384
385 auto root = doc.FirstChildElement();
386 ASSERT_NE(nullptr, root);
387 ASSERT_STREQ("malloc", root->Name());
Christopher Ferris85169652019-10-09 18:41:55 -0700388 std::string version(root->Attribute("version"));
389 if (version == "jemalloc-1") {
Christopher Ferris6c619a02019-03-01 17:59:51 -0800390 auto arena = root->FirstChildElement();
391 for (; arena != nullptr; arena = arena->NextSiblingElement()) {
392 int val;
Dan Albert4caa1f02014-08-20 09:16:57 -0700393
Christopher Ferris6c619a02019-03-01 17:59:51 -0800394 ASSERT_STREQ("heap", arena->Name());
395 ASSERT_EQ(tinyxml2::XML_SUCCESS, arena->QueryIntAttribute("nr", &val));
396 ASSERT_EQ(tinyxml2::XML_SUCCESS,
397 arena->FirstChildElement("allocated-large")->QueryIntText(&val));
398 ASSERT_EQ(tinyxml2::XML_SUCCESS,
399 arena->FirstChildElement("allocated-huge")->QueryIntText(&val));
400 ASSERT_EQ(tinyxml2::XML_SUCCESS,
401 arena->FirstChildElement("allocated-bins")->QueryIntText(&val));
402 ASSERT_EQ(tinyxml2::XML_SUCCESS,
403 arena->FirstChildElement("bins-total")->QueryIntText(&val));
Dan Albert4caa1f02014-08-20 09:16:57 -0700404
Christopher Ferris6c619a02019-03-01 17:59:51 -0800405 auto bin = arena->FirstChildElement("bin");
406 for (; bin != nullptr; bin = bin ->NextSiblingElement()) {
407 if (strcmp(bin->Name(), "bin") == 0) {
408 ASSERT_EQ(tinyxml2::XML_SUCCESS, bin->QueryIntAttribute("nr", &val));
409 ASSERT_EQ(tinyxml2::XML_SUCCESS,
410 bin->FirstChildElement("allocated")->QueryIntText(&val));
411 ASSERT_EQ(tinyxml2::XML_SUCCESS,
412 bin->FirstChildElement("nmalloc")->QueryIntText(&val));
413 ASSERT_EQ(tinyxml2::XML_SUCCESS,
414 bin->FirstChildElement("ndalloc")->QueryIntText(&val));
415 }
Dan Albert4caa1f02014-08-20 09:16:57 -0700416 }
417 }
Christopher Ferriscce88c02020-02-12 17:41:01 -0800418 } else if (version == "scudo-1") {
419 auto element = root->FirstChildElement();
420 for (; element != nullptr; element = element->NextSiblingElement()) {
421 int val;
422
423 ASSERT_STREQ("alloc", element->Name());
424 ASSERT_EQ(tinyxml2::XML_SUCCESS, element->QueryIntAttribute("size", &val));
425 ASSERT_EQ(tinyxml2::XML_SUCCESS, element->QueryIntAttribute("count", &val));
426 }
Christopher Ferris6c619a02019-03-01 17:59:51 -0800427 } else {
Christopher Ferriscce88c02020-02-12 17:41:01 -0800428 // Do not verify output for debug malloc.
429 ASSERT_TRUE(version == "debug-malloc-1") << "Unknown version: " << version;
Dan Albert4caa1f02014-08-20 09:16:57 -0700430 }
431#endif
432}
Christopher Ferrisad33ebe2015-12-16 12:07:25 -0800433
Christopher Ferrisdb9706a2019-05-02 18:33:11 -0700434TEST(malloc, malloc_info_matches_mallinfo) {
435#ifdef __BIONIC__
436 SKIP_WITH_HWASAN; // hwasan does not implement malloc_info
437
Christopher Ferrisff88fb02019-11-04 18:40:00 -0800438 TemporaryFile tf;
439 ASSERT_TRUE(tf.fd != -1);
440 FILE* fp = fdopen(tf.fd, "w+");
441 tf.release();
442 ASSERT_TRUE(fp != nullptr);
Christopher Ferrisdb9706a2019-05-02 18:33:11 -0700443 size_t mallinfo_before_allocated_bytes = mallinfo().uordblks;
Christopher Ferrisff88fb02019-11-04 18:40:00 -0800444 ASSERT_EQ(0, malloc_info(0, fp));
Christopher Ferrisdb9706a2019-05-02 18:33:11 -0700445 size_t mallinfo_after_allocated_bytes = mallinfo().uordblks;
Christopher Ferrisff88fb02019-11-04 18:40:00 -0800446 ASSERT_EQ(0, fclose(fp));
447
448 std::string contents;
449 ASSERT_TRUE(android::base::ReadFileToString(tf.path, &contents));
Christopher Ferrisdb9706a2019-05-02 18:33:11 -0700450
451 tinyxml2::XMLDocument doc;
Christopher Ferrisff88fb02019-11-04 18:40:00 -0800452 ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(contents.c_str()));
Christopher Ferrisdb9706a2019-05-02 18:33:11 -0700453
454 size_t total_allocated_bytes = 0;
455 auto root = doc.FirstChildElement();
456 ASSERT_NE(nullptr, root);
457 ASSERT_STREQ("malloc", root->Name());
Christopher Ferris85169652019-10-09 18:41:55 -0700458 std::string version(root->Attribute("version"));
459 if (version == "jemalloc-1") {
Christopher Ferrisdb9706a2019-05-02 18:33:11 -0700460 auto arena = root->FirstChildElement();
461 for (; arena != nullptr; arena = arena->NextSiblingElement()) {
462 int val;
463
464 ASSERT_STREQ("heap", arena->Name());
465 ASSERT_EQ(tinyxml2::XML_SUCCESS, arena->QueryIntAttribute("nr", &val));
466 ASSERT_EQ(tinyxml2::XML_SUCCESS,
467 arena->FirstChildElement("allocated-large")->QueryIntText(&val));
468 total_allocated_bytes += val;
469 ASSERT_EQ(tinyxml2::XML_SUCCESS,
470 arena->FirstChildElement("allocated-huge")->QueryIntText(&val));
471 total_allocated_bytes += val;
472 ASSERT_EQ(tinyxml2::XML_SUCCESS,
473 arena->FirstChildElement("allocated-bins")->QueryIntText(&val));
474 total_allocated_bytes += val;
475 ASSERT_EQ(tinyxml2::XML_SUCCESS,
476 arena->FirstChildElement("bins-total")->QueryIntText(&val));
477 }
478 // The total needs to be between the mallinfo call before and after
479 // since malloc_info allocates some memory.
480 EXPECT_LE(mallinfo_before_allocated_bytes, total_allocated_bytes);
481 EXPECT_GE(mallinfo_after_allocated_bytes, total_allocated_bytes);
Christopher Ferriscce88c02020-02-12 17:41:01 -0800482 } else if (version == "scudo-1") {
483 auto element = root->FirstChildElement();
484 for (; element != nullptr; element = element->NextSiblingElement()) {
485 ASSERT_STREQ("alloc", element->Name());
486 int size;
487 ASSERT_EQ(tinyxml2::XML_SUCCESS, element->QueryIntAttribute("size", &size));
488 int count;
489 ASSERT_EQ(tinyxml2::XML_SUCCESS, element->QueryIntAttribute("count", &count));
490 total_allocated_bytes += size * count;
491 }
492 // Scudo only gives the information on the primary, so simply make
493 // sure that the value is non-zero.
494 EXPECT_NE(0U, total_allocated_bytes);
Christopher Ferrisdb9706a2019-05-02 18:33:11 -0700495 } else {
Christopher Ferriscce88c02020-02-12 17:41:01 -0800496 // Do not verify output for debug malloc.
497 ASSERT_TRUE(version == "debug-malloc-1") << "Unknown version: " << version;
Christopher Ferrisdb9706a2019-05-02 18:33:11 -0700498 }
499#endif
500}
501
Christopher Ferrisad33ebe2015-12-16 12:07:25 -0800502TEST(malloc, calloc_usable_size) {
503 for (size_t size = 1; size <= 2048; size++) {
504 void* pointer = malloc(size);
505 ASSERT_TRUE(pointer != nullptr);
506 memset(pointer, 0xeb, malloc_usable_size(pointer));
507 free(pointer);
508
509 // We should get a previous pointer that has been set to non-zero.
510 // If calloc does not zero out all of the data, this will fail.
511 uint8_t* zero_mem = reinterpret_cast<uint8_t*>(calloc(1, size));
512 ASSERT_TRUE(pointer != nullptr);
513 size_t usable_size = malloc_usable_size(zero_mem);
514 for (size_t i = 0; i < usable_size; i++) {
515 ASSERT_EQ(0, zero_mem[i]) << "Failed at allocation size " << size << " at byte " << i;
516 }
517 free(zero_mem);
518 }
519}
Elliott Hughes884f76e2016-02-10 20:43:22 -0800520
521TEST(malloc, malloc_0) {
522 void* p = malloc(0);
523 ASSERT_TRUE(p != nullptr);
524 free(p);
525}
526
527TEST(malloc, calloc_0_0) {
528 void* p = calloc(0, 0);
529 ASSERT_TRUE(p != nullptr);
530 free(p);
531}
532
533TEST(malloc, calloc_0_1) {
534 void* p = calloc(0, 1);
535 ASSERT_TRUE(p != nullptr);
536 free(p);
537}
538
539TEST(malloc, calloc_1_0) {
540 void* p = calloc(1, 0);
541 ASSERT_TRUE(p != nullptr);
542 free(p);
543}
544
545TEST(malloc, realloc_nullptr_0) {
546 // realloc(nullptr, size) is actually malloc(size).
547 void* p = realloc(nullptr, 0);
548 ASSERT_TRUE(p != nullptr);
549 free(p);
550}
551
552TEST(malloc, realloc_0) {
553 void* p = malloc(1024);
554 ASSERT_TRUE(p != nullptr);
555 // realloc(p, 0) is actually free(p).
556 void* p2 = realloc(p, 0);
557 ASSERT_TRUE(p2 == nullptr);
558}
Christopher Ferris72df6702016-02-11 15:51:31 -0800559
560constexpr size_t MAX_LOOPS = 200;
561
562// Make sure that memory returned by malloc is aligned to allow these data types.
563TEST(malloc, verify_alignment) {
564 uint32_t** values_32 = new uint32_t*[MAX_LOOPS];
565 uint64_t** values_64 = new uint64_t*[MAX_LOOPS];
566 long double** values_ldouble = new long double*[MAX_LOOPS];
567 // Use filler to attempt to force the allocator to get potentially bad alignments.
568 void** filler = new void*[MAX_LOOPS];
569
570 for (size_t i = 0; i < MAX_LOOPS; i++) {
571 // Check uint32_t pointers.
572 filler[i] = malloc(1);
573 ASSERT_TRUE(filler[i] != nullptr);
574
575 values_32[i] = reinterpret_cast<uint32_t*>(malloc(sizeof(uint32_t)));
576 ASSERT_TRUE(values_32[i] != nullptr);
577 *values_32[i] = i;
578 ASSERT_EQ(*values_32[i], i);
579 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_32[i]) & (sizeof(uint32_t) - 1));
580
581 free(filler[i]);
582 }
583
584 for (size_t i = 0; i < MAX_LOOPS; i++) {
585 // Check uint64_t pointers.
586 filler[i] = malloc(1);
587 ASSERT_TRUE(filler[i] != nullptr);
588
589 values_64[i] = reinterpret_cast<uint64_t*>(malloc(sizeof(uint64_t)));
590 ASSERT_TRUE(values_64[i] != nullptr);
591 *values_64[i] = 0x1000 + i;
592 ASSERT_EQ(*values_64[i], 0x1000 + i);
593 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_64[i]) & (sizeof(uint64_t) - 1));
594
595 free(filler[i]);
596 }
597
598 for (size_t i = 0; i < MAX_LOOPS; i++) {
599 // Check long double pointers.
600 filler[i] = malloc(1);
601 ASSERT_TRUE(filler[i] != nullptr);
602
603 values_ldouble[i] = reinterpret_cast<long double*>(malloc(sizeof(long double)));
604 ASSERT_TRUE(values_ldouble[i] != nullptr);
605 *values_ldouble[i] = 5.5 + i;
606 ASSERT_DOUBLE_EQ(*values_ldouble[i], 5.5 + i);
607 // 32 bit glibc has a long double size of 12 bytes, so hardcode the
608 // required alignment to 0x7.
609#if !defined(__BIONIC__) && !defined(__LP64__)
610 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_ldouble[i]) & 0x7);
611#else
612 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_ldouble[i]) & (sizeof(long double) - 1));
613#endif
614
615 free(filler[i]);
616 }
617
618 for (size_t i = 0; i < MAX_LOOPS; i++) {
619 free(values_32[i]);
620 free(values_64[i]);
621 free(values_ldouble[i]);
622 }
623
624 delete[] filler;
625 delete[] values_32;
626 delete[] values_64;
627 delete[] values_ldouble;
628}
Christopher Ferrisa1c0d2f2017-05-15 15:50:19 -0700629
630TEST(malloc, mallopt_smoke) {
631 errno = 0;
632 ASSERT_EQ(0, mallopt(-1000, 1));
633 // mallopt doesn't set errno.
634 ASSERT_EQ(0, errno);
635}
Elliott Hughesb1770852018-09-18 12:52:42 -0700636
Christopher Ferrisaf1b8dd2018-11-07 15:28:16 -0800637TEST(malloc, mallopt_decay) {
638#if defined(__BIONIC__)
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800639 SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
Christopher Ferrisaf1b8dd2018-11-07 15:28:16 -0800640 errno = 0;
641 ASSERT_EQ(1, mallopt(M_DECAY_TIME, 1));
642 ASSERT_EQ(1, mallopt(M_DECAY_TIME, 0));
643 ASSERT_EQ(1, mallopt(M_DECAY_TIME, 1));
644 ASSERT_EQ(1, mallopt(M_DECAY_TIME, 0));
645#else
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800646 GTEST_SKIP() << "bionic-only test";
Christopher Ferrisaf1b8dd2018-11-07 15:28:16 -0800647#endif
648}
649
650TEST(malloc, mallopt_purge) {
651#if defined(__BIONIC__)
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800652 SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
Christopher Ferrisaf1b8dd2018-11-07 15:28:16 -0800653 errno = 0;
654 ASSERT_EQ(1, mallopt(M_PURGE, 0));
655#else
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800656 GTEST_SKIP() << "bionic-only test";
Christopher Ferrisaf1b8dd2018-11-07 15:28:16 -0800657#endif
658}
659
Elliott Hughesb1770852018-09-18 12:52:42 -0700660TEST(malloc, reallocarray_overflow) {
661#if HAVE_REALLOCARRAY
662 // Values that cause overflow to a result small enough (8 on LP64) that malloc would "succeed".
663 size_t a = static_cast<size_t>(INTPTR_MIN + 4);
664 size_t b = 2;
665
666 errno = 0;
667 ASSERT_TRUE(reallocarray(nullptr, a, b) == nullptr);
668 ASSERT_EQ(ENOMEM, errno);
669
670 errno = 0;
671 ASSERT_TRUE(reallocarray(nullptr, b, a) == nullptr);
672 ASSERT_EQ(ENOMEM, errno);
673#else
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800674 GTEST_SKIP() << "reallocarray not available";
Elliott Hughesb1770852018-09-18 12:52:42 -0700675#endif
676}
677
678TEST(malloc, reallocarray) {
679#if HAVE_REALLOCARRAY
680 void* p = reallocarray(nullptr, 2, 32);
681 ASSERT_TRUE(p != nullptr);
682 ASSERT_GE(malloc_usable_size(p), 64U);
683#else
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800684 GTEST_SKIP() << "reallocarray not available";
Elliott Hughesb1770852018-09-18 12:52:42 -0700685#endif
686}
Christopher Ferris09a19aa2018-11-16 13:28:56 -0800687
688TEST(malloc, mallinfo) {
689#if defined(__BIONIC__)
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800690 SKIP_WITH_HWASAN << "hwasan does not implement mallinfo";
Christopher Ferris09a19aa2018-11-16 13:28:56 -0800691 static size_t sizes[] = {
692 8, 32, 128, 4096, 32768, 131072, 1024000, 10240000, 20480000, 300000000
693 };
694
695 constexpr static size_t kMaxAllocs = 50;
696
697 for (size_t size : sizes) {
698 // If some of these allocations are stuck in a thread cache, then keep
699 // looping until we make an allocation that changes the total size of the
700 // memory allocated.
701 // jemalloc implementations counts the thread cache allocations against
702 // total memory allocated.
703 void* ptrs[kMaxAllocs] = {};
704 bool pass = false;
705 for (size_t i = 0; i < kMaxAllocs; i++) {
706 size_t allocated = mallinfo().uordblks;
707 ptrs[i] = malloc(size);
708 ASSERT_TRUE(ptrs[i] != nullptr);
709 size_t new_allocated = mallinfo().uordblks;
710 if (allocated != new_allocated) {
711 size_t usable_size = malloc_usable_size(ptrs[i]);
Christopher Ferris4e562282019-02-07 14:20:03 -0800712 // Only check if the total got bigger by at least allocation size.
713 // Sometimes the mallinfo numbers can go backwards due to compaction
714 // and/or freeing of cached data.
715 if (new_allocated >= allocated + usable_size) {
716 pass = true;
717 break;
718 }
Christopher Ferris09a19aa2018-11-16 13:28:56 -0800719 }
720 }
721 for (void* ptr : ptrs) {
722 free(ptr);
723 }
724 ASSERT_TRUE(pass)
725 << "For size " << size << " allocated bytes did not increase after "
726 << kMaxAllocs << " allocations.";
727 }
728#else
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800729 GTEST_SKIP() << "glibc is broken";
Christopher Ferris09a19aa2018-11-16 13:28:56 -0800730#endif
731}
Ryan Savitskiecc37e32018-12-14 15:57:21 +0000732
Christopher Ferrisf32494c2020-01-08 14:19:10 -0800733template <typename Type>
734void __attribute__((optnone)) VerifyAlignment(Type* floating) {
735 size_t expected_alignment = alignof(Type);
736 if (expected_alignment != 0) {
737 ASSERT_EQ(0U, (expected_alignment - 1) & reinterpret_cast<uintptr_t>(floating))
738 << "Expected alignment " << expected_alignment << " ptr value " << floating;
739 }
740}
741
742template <typename Type>
743void __attribute__((optnone)) TestAllocateType() {
744 // The number of allocations to do in a row. This is to attempt to
745 // expose the worst case alignment for native allocators that use
746 // bins.
747 static constexpr size_t kMaxConsecutiveAllocs = 100;
748
749 // Verify using new directly.
750 Type* types[kMaxConsecutiveAllocs];
751 for (size_t i = 0; i < kMaxConsecutiveAllocs; i++) {
752 types[i] = new Type;
753 VerifyAlignment(types[i]);
754 if (::testing::Test::HasFatalFailure()) {
755 return;
756 }
757 }
758 for (size_t i = 0; i < kMaxConsecutiveAllocs; i++) {
759 delete types[i];
760 }
761
762 // Verify using malloc.
763 for (size_t i = 0; i < kMaxConsecutiveAllocs; i++) {
764 types[i] = reinterpret_cast<Type*>(malloc(sizeof(Type)));
765 ASSERT_TRUE(types[i] != nullptr);
766 VerifyAlignment(types[i]);
767 if (::testing::Test::HasFatalFailure()) {
768 return;
769 }
770 }
771 for (size_t i = 0; i < kMaxConsecutiveAllocs; i++) {
772 free(types[i]);
773 }
774
775 // Verify using a vector.
776 std::vector<Type> type_vector(kMaxConsecutiveAllocs);
777 for (size_t i = 0; i < type_vector.size(); i++) {
778 VerifyAlignment(&type_vector[i]);
779 if (::testing::Test::HasFatalFailure()) {
780 return;
781 }
782 }
783}
784
785#if defined(__ANDROID__)
786static void __attribute__((optnone)) AndroidVerifyAlignment(size_t alloc_size, size_t aligned_bytes) {
787 void* ptrs[100];
788 uintptr_t mask = aligned_bytes - 1;
789 for (size_t i = 0; i < sizeof(ptrs) / sizeof(void*); i++) {
790 ptrs[i] = malloc(alloc_size);
791 ASSERT_TRUE(ptrs[i] != nullptr);
792 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptrs[i]) & mask)
793 << "Expected at least " << aligned_bytes << " byte alignment: size "
794 << alloc_size << " actual ptr " << ptrs[i];
795 }
796}
797#endif
798
799TEST(malloc, align_check) {
800 // See http://www.open-std.org/jtc1/sc22/wg14/www/docs/summary.htm#dr_445
801 // for a discussion of type alignment.
802 ASSERT_NO_FATAL_FAILURE(TestAllocateType<float>());
803 ASSERT_NO_FATAL_FAILURE(TestAllocateType<double>());
804 ASSERT_NO_FATAL_FAILURE(TestAllocateType<long double>());
805
806 ASSERT_NO_FATAL_FAILURE(TestAllocateType<char>());
807 ASSERT_NO_FATAL_FAILURE(TestAllocateType<char16_t>());
808 ASSERT_NO_FATAL_FAILURE(TestAllocateType<char32_t>());
809 ASSERT_NO_FATAL_FAILURE(TestAllocateType<wchar_t>());
810 ASSERT_NO_FATAL_FAILURE(TestAllocateType<signed char>());
811 ASSERT_NO_FATAL_FAILURE(TestAllocateType<short int>());
812 ASSERT_NO_FATAL_FAILURE(TestAllocateType<int>());
813 ASSERT_NO_FATAL_FAILURE(TestAllocateType<long int>());
814 ASSERT_NO_FATAL_FAILURE(TestAllocateType<long long int>());
815 ASSERT_NO_FATAL_FAILURE(TestAllocateType<unsigned char>());
816 ASSERT_NO_FATAL_FAILURE(TestAllocateType<unsigned short int>());
817 ASSERT_NO_FATAL_FAILURE(TestAllocateType<unsigned int>());
818 ASSERT_NO_FATAL_FAILURE(TestAllocateType<unsigned long int>());
819 ASSERT_NO_FATAL_FAILURE(TestAllocateType<unsigned long long int>());
820
821#if defined(__ANDROID__)
822 // On Android, there is a lot of code that expects certain alignments:
823 // - Allocations of a size that rounds up to a multiple of 16 bytes
824 // must have at least 16 byte alignment.
825 // - Allocations of a size that rounds up to a multiple of 8 bytes and
826 // not 16 bytes, are only required to have at least 8 byte alignment.
827 // This is regardless of whether it is in a 32 bit or 64 bit environment.
828
829 // See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2293.htm for
830 // a discussion of this alignment mess. The code below is enforcing
831 // strong-alignment, since who knows what code depends on this behavior now.
832 for (size_t i = 1; i <= 128; i++) {
833 size_t rounded = (i + 7) & ~7;
834 if ((rounded % 16) == 0) {
835 AndroidVerifyAlignment(i, 16);
836 } else {
837 AndroidVerifyAlignment(i, 8);
838 }
839 if (::testing::Test::HasFatalFailure()) {
840 return;
841 }
842 }
843#endif
844}
845
Christopher Ferris201dcf42020-01-29 13:09:31 -0800846// Jemalloc doesn't pass this test right now, so leave it as disabled.
847TEST(malloc, DISABLED_alloc_after_fork) {
848 // Both of these need to be a power of 2.
849 static constexpr size_t kMinAllocationSize = 8;
850 static constexpr size_t kMaxAllocationSize = 2097152;
851
852 static constexpr size_t kNumAllocatingThreads = 5;
853 static constexpr size_t kNumForkLoops = 100;
854
855 std::atomic_bool stop;
856
857 // Create threads that simply allocate and free different sizes.
858 std::vector<std::thread*> threads;
859 for (size_t i = 0; i < kNumAllocatingThreads; i++) {
860 std::thread* t = new std::thread([&stop] {
861 while (!stop) {
862 for (size_t size = kMinAllocationSize; size <= kMaxAllocationSize; size <<= 1) {
863 void* ptr = malloc(size);
864 if (ptr == nullptr) {
865 return;
866 }
867 // Make sure this value is not optimized away.
868 asm volatile("" : : "r,m"(ptr) : "memory");
869 free(ptr);
870 }
871 }
872 });
873 threads.push_back(t);
874 }
875
876 // Create a thread to fork and allocate.
877 for (size_t i = 0; i < kNumForkLoops; i++) {
878 pid_t pid;
879 if ((pid = fork()) == 0) {
880 for (size_t size = kMinAllocationSize; size <= kMaxAllocationSize; size <<= 1) {
881 void* ptr = malloc(size);
882 ASSERT_TRUE(ptr != nullptr);
883 // Make sure this value is not optimized away.
884 asm volatile("" : : "r,m"(ptr) : "memory");
885 // Make sure we can touch all of the allocation.
886 memset(ptr, 0x1, size);
887 ASSERT_LE(size, malloc_usable_size(ptr));
888 free(ptr);
889 }
890 _exit(10);
891 }
892 ASSERT_NE(-1, pid);
893 AssertChildExited(pid, 10);
894 }
895
896 stop = true;
897 for (auto thread : threads) {
898 thread->join();
899 delete thread;
900 }
901}
902
Ryan Savitskiecc37e32018-12-14 15:57:21 +0000903TEST(android_mallopt, error_on_unexpected_option) {
904#if defined(__BIONIC__)
905 const int unrecognized_option = -1;
906 errno = 0;
907 EXPECT_EQ(false, android_mallopt(unrecognized_option, nullptr, 0));
908 EXPECT_EQ(ENOTSUP, errno);
909#else
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800910 GTEST_SKIP() << "bionic-only test";
Ryan Savitskiecc37e32018-12-14 15:57:21 +0000911#endif
912}
913
Christopher Ferrise4cdbc42019-02-08 17:30:58 -0800914bool IsDynamic() {
915#if defined(__LP64__)
916 Elf64_Ehdr ehdr;
917#else
918 Elf32_Ehdr ehdr;
919#endif
920 std::string path(android::base::GetExecutablePath());
921
922 int fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
923 if (fd == -1) {
924 // Assume dynamic on error.
925 return true;
926 }
927 bool read_completed = android::base::ReadFully(fd, &ehdr, sizeof(ehdr));
928 close(fd);
929 // Assume dynamic in error cases.
930 return !read_completed || ehdr.e_type == ET_DYN;
931}
932
Ryan Savitskiecc37e32018-12-14 15:57:21 +0000933TEST(android_mallopt, init_zygote_child_profiling) {
934#if defined(__BIONIC__)
935 // Successful call.
936 errno = 0;
Christopher Ferrise4cdbc42019-02-08 17:30:58 -0800937 if (IsDynamic()) {
938 EXPECT_EQ(true, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0));
939 EXPECT_EQ(0, errno);
940 } else {
941 // Not supported in static executables.
942 EXPECT_EQ(false, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0));
943 EXPECT_EQ(ENOTSUP, errno);
944 }
Ryan Savitskiecc37e32018-12-14 15:57:21 +0000945
946 // Unexpected arguments rejected.
947 errno = 0;
948 char unexpected = 0;
949 EXPECT_EQ(false, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, &unexpected, 1));
Christopher Ferrise4cdbc42019-02-08 17:30:58 -0800950 if (IsDynamic()) {
951 EXPECT_EQ(EINVAL, errno);
952 } else {
953 EXPECT_EQ(ENOTSUP, errno);
954 }
Ryan Savitskiecc37e32018-12-14 15:57:21 +0000955#else
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800956 GTEST_SKIP() << "bionic-only test";
Ryan Savitskiecc37e32018-12-14 15:57:21 +0000957#endif
958}
Christopher Ferris1fc5ccf2019-02-15 18:06:15 -0800959
960#if defined(__BIONIC__)
961template <typename FuncType>
962void CheckAllocationFunction(FuncType func) {
963 // Assumes that no more than 108MB of memory is allocated before this.
964 size_t limit = 128 * 1024 * 1024;
965 ASSERT_TRUE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
966 if (!func(20 * 1024 * 1024))
967 exit(1);
968 if (func(128 * 1024 * 1024))
969 exit(1);
970 exit(0);
971}
972#endif
973
974TEST(android_mallopt, set_allocation_limit) {
975#if defined(__BIONIC__)
976 EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) { return calloc(bytes, 1) != nullptr; }),
977 testing::ExitedWithCode(0), "");
978 EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) { return calloc(1, bytes) != nullptr; }),
979 testing::ExitedWithCode(0), "");
980 EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) { return malloc(bytes) != nullptr; }),
981 testing::ExitedWithCode(0), "");
982 EXPECT_EXIT(CheckAllocationFunction(
983 [](size_t bytes) { return memalign(sizeof(void*), bytes) != nullptr; }),
984 testing::ExitedWithCode(0), "");
985 EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) {
986 void* ptr;
987 return posix_memalign(&ptr, sizeof(void *), bytes) == 0;
988 }),
989 testing::ExitedWithCode(0), "");
990 EXPECT_EXIT(CheckAllocationFunction(
991 [](size_t bytes) { return aligned_alloc(sizeof(void*), bytes) != nullptr; }),
992 testing::ExitedWithCode(0), "");
993 EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) {
994 void* p = malloc(1024 * 1024);
995 return realloc(p, bytes) != nullptr;
996 }),
997 testing::ExitedWithCode(0), "");
998#if !defined(__LP64__)
999 EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) { return pvalloc(bytes) != nullptr; }),
1000 testing::ExitedWithCode(0), "");
1001 EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) { return valloc(bytes) != nullptr; }),
1002 testing::ExitedWithCode(0), "");
1003#endif
1004#else
Elliott Hughes10907202019-03-27 08:51:02 -07001005 GTEST_SKIP() << "bionic extension";
Christopher Ferris1fc5ccf2019-02-15 18:06:15 -08001006#endif
1007}
1008
1009TEST(android_mallopt, set_allocation_limit_multiple) {
1010#if defined(__BIONIC__)
1011 // Only the first set should work.
1012 size_t limit = 256 * 1024 * 1024;
1013 ASSERT_TRUE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
1014 limit = 32 * 1024 * 1024;
1015 ASSERT_FALSE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
1016#else
Elliott Hughes10907202019-03-27 08:51:02 -07001017 GTEST_SKIP() << "bionic extension";
Christopher Ferris1fc5ccf2019-02-15 18:06:15 -08001018#endif
1019}
1020
1021#if defined(__BIONIC__)
1022static constexpr size_t kAllocationSize = 8 * 1024 * 1024;
1023
1024static size_t GetMaxAllocations() {
1025 size_t max_pointers = 0;
1026 void* ptrs[20];
1027 for (size_t i = 0; i < sizeof(ptrs) / sizeof(void*); i++) {
1028 ptrs[i] = malloc(kAllocationSize);
1029 if (ptrs[i] == nullptr) {
1030 max_pointers = i;
1031 break;
1032 }
1033 }
1034 for (size_t i = 0; i < max_pointers; i++) {
1035 free(ptrs[i]);
1036 }
1037 return max_pointers;
1038}
1039
1040static void VerifyMaxPointers(size_t max_pointers) {
1041 // Now verify that we can allocate the same number as before.
1042 void* ptrs[20];
1043 for (size_t i = 0; i < max_pointers; i++) {
1044 ptrs[i] = malloc(kAllocationSize);
1045 ASSERT_TRUE(ptrs[i] != nullptr) << "Failed to allocate on iteration " << i;
1046 }
1047
1048 // Make sure the next allocation still fails.
1049 ASSERT_TRUE(malloc(kAllocationSize) == nullptr);
1050 for (size_t i = 0; i < max_pointers; i++) {
1051 free(ptrs[i]);
1052 }
1053}
1054#endif
1055
1056TEST(android_mallopt, set_allocation_limit_realloc_increase) {
1057#if defined(__BIONIC__)
1058 size_t limit = 128 * 1024 * 1024;
1059 ASSERT_TRUE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
1060
1061 size_t max_pointers = GetMaxAllocations();
1062 ASSERT_TRUE(max_pointers != 0) << "Limit never reached.";
1063
1064 void* memory = malloc(10 * 1024 * 1024);
1065 ASSERT_TRUE(memory != nullptr);
1066
1067 // Increase size.
1068 memory = realloc(memory, 20 * 1024 * 1024);
1069 ASSERT_TRUE(memory != nullptr);
1070 memory = realloc(memory, 40 * 1024 * 1024);
1071 ASSERT_TRUE(memory != nullptr);
1072 memory = realloc(memory, 60 * 1024 * 1024);
1073 ASSERT_TRUE(memory != nullptr);
1074 memory = realloc(memory, 80 * 1024 * 1024);
1075 ASSERT_TRUE(memory != nullptr);
1076 // Now push past limit.
1077 memory = realloc(memory, 130 * 1024 * 1024);
1078 ASSERT_TRUE(memory == nullptr);
1079
1080 VerifyMaxPointers(max_pointers);
1081#else
Elliott Hughes10907202019-03-27 08:51:02 -07001082 GTEST_SKIP() << "bionic extension";
Christopher Ferris1fc5ccf2019-02-15 18:06:15 -08001083#endif
1084}
1085
1086TEST(android_mallopt, set_allocation_limit_realloc_decrease) {
1087#if defined(__BIONIC__)
1088 size_t limit = 100 * 1024 * 1024;
1089 ASSERT_TRUE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
1090
1091 size_t max_pointers = GetMaxAllocations();
1092 ASSERT_TRUE(max_pointers != 0) << "Limit never reached.";
1093
1094 void* memory = malloc(80 * 1024 * 1024);
1095 ASSERT_TRUE(memory != nullptr);
1096
1097 // Decrease size.
1098 memory = realloc(memory, 60 * 1024 * 1024);
1099 ASSERT_TRUE(memory != nullptr);
1100 memory = realloc(memory, 40 * 1024 * 1024);
1101 ASSERT_TRUE(memory != nullptr);
1102 memory = realloc(memory, 20 * 1024 * 1024);
1103 ASSERT_TRUE(memory != nullptr);
1104 memory = realloc(memory, 10 * 1024 * 1024);
1105 ASSERT_TRUE(memory != nullptr);
1106 free(memory);
1107
1108 VerifyMaxPointers(max_pointers);
1109#else
Elliott Hughes10907202019-03-27 08:51:02 -07001110 GTEST_SKIP() << "bionic extension";
Christopher Ferris1fc5ccf2019-02-15 18:06:15 -08001111#endif
1112}
1113
1114TEST(android_mallopt, set_allocation_limit_realloc_free) {
1115#if defined(__BIONIC__)
1116 size_t limit = 100 * 1024 * 1024;
1117 ASSERT_TRUE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
1118
1119 size_t max_pointers = GetMaxAllocations();
1120 ASSERT_TRUE(max_pointers != 0) << "Limit never reached.";
1121
1122 void* memory = malloc(60 * 1024 * 1024);
1123 ASSERT_TRUE(memory != nullptr);
1124
1125 memory = realloc(memory, 0);
1126 ASSERT_TRUE(memory == nullptr);
1127
1128 VerifyMaxPointers(max_pointers);
1129#else
Elliott Hughes10907202019-03-27 08:51:02 -07001130 GTEST_SKIP() << "bionic extension";
Christopher Ferris1fc5ccf2019-02-15 18:06:15 -08001131#endif
1132}
1133
1134#if defined(__BIONIC__)
1135static void* SetAllocationLimit(void* data) {
1136 std::atomic_bool* go = reinterpret_cast<std::atomic_bool*>(data);
1137 while (!go->load()) {
1138 }
1139 size_t limit = 500 * 1024 * 1024;
1140 if (android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit))) {
1141 return reinterpret_cast<void*>(-1);
1142 }
1143 return nullptr;
1144}
1145
1146static void SetAllocationLimitMultipleThreads() {
1147 std::atomic_bool go;
1148 go = false;
1149
1150 static constexpr size_t kNumThreads = 4;
1151 pthread_t threads[kNumThreads];
1152 for (size_t i = 0; i < kNumThreads; i++) {
1153 ASSERT_EQ(0, pthread_create(&threads[i], nullptr, SetAllocationLimit, &go));
1154 }
1155
1156 // Let them go all at once.
1157 go = true;
Ryan Savitski175c8862020-01-02 19:54:57 +00001158 // Send hardcoded signal (BIONIC_SIGNAL_PROFILER with value 0) to trigger
1159 // heapprofd handler.
1160 union sigval signal_value;
1161 signal_value.sival_int = 0;
Christopher Ferrisb874c332020-01-21 16:39:05 -08001162 ASSERT_EQ(0, sigqueue(getpid(), BIONIC_SIGNAL_PROFILER, signal_value));
Christopher Ferris1fc5ccf2019-02-15 18:06:15 -08001163
1164 size_t num_successful = 0;
1165 for (size_t i = 0; i < kNumThreads; i++) {
1166 void* result;
1167 ASSERT_EQ(0, pthread_join(threads[i], &result));
1168 if (result != nullptr) {
1169 num_successful++;
1170 }
1171 }
1172 ASSERT_EQ(1U, num_successful);
1173 exit(0);
1174}
1175#endif
1176
1177TEST(android_mallopt, set_allocation_limit_multiple_threads) {
1178#if defined(__BIONIC__)
1179 if (IsDynamic()) {
1180 ASSERT_TRUE(android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0));
1181 }
1182
1183 // Run this a number of times as a stress test.
1184 for (size_t i = 0; i < 100; i++) {
1185 // Not using ASSERT_EXIT because errors messages are not displayed.
1186 pid_t pid;
1187 if ((pid = fork()) == 0) {
1188 ASSERT_NO_FATAL_FAILURE(SetAllocationLimitMultipleThreads());
1189 }
1190 ASSERT_NE(-1, pid);
1191 int status;
1192 ASSERT_EQ(pid, wait(&status));
1193 ASSERT_EQ(0, WEXITSTATUS(status));
1194 }
1195#else
Elliott Hughes10907202019-03-27 08:51:02 -07001196 GTEST_SKIP() << "bionic extension";
Christopher Ferris1fc5ccf2019-02-15 18:06:15 -08001197#endif
1198}