blob: bc6a37b75c1136c7abf724c21a2dfe8fb225d9f8 [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 Ferris6c619a02019-03-01 17:59:51 -080022#include <stdio.h>
Christopher Ferris885f3b92013-05-21 17:48:01 -070023#include <stdlib.h>
24#include <malloc.h>
Christopher Ferrisa4037802014-06-09 19:14:11 -070025#include <unistd.h>
Christopher Ferris885f3b92013-05-21 17:48:01 -070026
Dan Albert4caa1f02014-08-20 09:16:57 -070027#include <tinyxml2.h>
28
Christopher Ferrise4cdbc42019-02-08 17:30:58 -080029#include <android-base/file.h>
30
Christopher Ferris63619642014-06-16 23:35:53 -070031#include "private/bionic_config.h"
Ryan Savitskiecc37e32018-12-14 15:57:21 +000032#include "private/bionic_malloc.h"
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080033#include "utils.h"
Dan Alberte5fdaa42014-06-14 01:04:31 +000034
Elliott Hughesb1770852018-09-18 12:52:42 -070035#if defined(__BIONIC__)
36#define HAVE_REALLOCARRAY 1
37#else
38#define HAVE_REALLOCARRAY __GLIBC_PREREQ(2, 26)
39#endif
40
Christopher Ferris885f3b92013-05-21 17:48:01 -070041TEST(malloc, malloc_std) {
42 // Simple malloc test.
43 void *ptr = malloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -070044 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -070045 ASSERT_LE(100U, malloc_usable_size(ptr));
Christopher Ferris885f3b92013-05-21 17:48:01 -070046 free(ptr);
47}
48
Christopher Ferrisa4037802014-06-09 19:14:11 -070049TEST(malloc, malloc_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080050 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -070051 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070052 ASSERT_EQ(nullptr, malloc(SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -070053 ASSERT_EQ(ENOMEM, errno);
54}
55
Christopher Ferris885f3b92013-05-21 17:48:01 -070056TEST(malloc, calloc_std) {
57 // Simple calloc test.
58 size_t alloc_len = 100;
59 char *ptr = (char *)calloc(1, alloc_len);
Yi Kong32bc0fc2018-08-02 17:31:13 -070060 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -070061 ASSERT_LE(alloc_len, malloc_usable_size(ptr));
62 for (size_t i = 0; i < alloc_len; i++) {
63 ASSERT_EQ(0, ptr[i]);
64 }
Christopher Ferris885f3b92013-05-21 17:48:01 -070065 free(ptr);
66}
67
Christopher Ferrisa4037802014-06-09 19:14:11 -070068TEST(malloc, calloc_illegal) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080069 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -070070 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070071 ASSERT_EQ(nullptr, calloc(-1, 100));
Christopher Ferrisa4037802014-06-09 19:14:11 -070072 ASSERT_EQ(ENOMEM, errno);
73}
74
75TEST(malloc, calloc_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080076 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -070077 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070078 ASSERT_EQ(nullptr, calloc(1, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -070079 ASSERT_EQ(ENOMEM, errno);
80 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070081 ASSERT_EQ(nullptr, calloc(SIZE_MAX, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -070082 ASSERT_EQ(ENOMEM, errno);
83 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070084 ASSERT_EQ(nullptr, calloc(2, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -070085 ASSERT_EQ(ENOMEM, errno);
86 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -070087 ASSERT_EQ(nullptr, calloc(SIZE_MAX, 2));
Christopher Ferrisa4037802014-06-09 19:14:11 -070088 ASSERT_EQ(ENOMEM, errno);
89}
90
Christopher Ferris885f3b92013-05-21 17:48:01 -070091TEST(malloc, memalign_multiple) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080092 SKIP_WITH_HWASAN; // hwasan requires power of 2 alignment.
Christopher Ferris885f3b92013-05-21 17:48:01 -070093 // Memalign test where the alignment is any value.
94 for (size_t i = 0; i <= 12; i++) {
95 for (size_t alignment = 1 << i; alignment < (1U << (i+1)); alignment++) {
Christopher Ferrisa4037802014-06-09 19:14:11 -070096 char *ptr = reinterpret_cast<char*>(memalign(alignment, 100));
Yi Kong32bc0fc2018-08-02 17:31:13 -070097 ASSERT_TRUE(ptr != nullptr) << "Failed at alignment " << alignment;
Christopher Ferrisa4037802014-06-09 19:14:11 -070098 ASSERT_LE(100U, malloc_usable_size(ptr)) << "Failed at alignment " << alignment;
99 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) % ((1U << i)))
100 << "Failed at alignment " << alignment;
Christopher Ferris885f3b92013-05-21 17:48:01 -0700101 free(ptr);
102 }
103 }
104}
105
Christopher Ferrisa4037802014-06-09 19:14:11 -0700106TEST(malloc, memalign_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800107 SKIP_WITH_HWASAN;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700108 ASSERT_EQ(nullptr, memalign(4096, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -0700109}
110
111TEST(malloc, memalign_non_power2) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800112 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700113 void* ptr;
114 for (size_t align = 0; align <= 256; align++) {
115 ptr = memalign(align, 1024);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700116 ASSERT_TRUE(ptr != nullptr) << "Failed at align " << align;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700117 free(ptr);
118 }
119}
120
Christopher Ferris885f3b92013-05-21 17:48:01 -0700121TEST(malloc, memalign_realloc) {
122 // Memalign and then realloc the pointer a couple of times.
123 for (size_t alignment = 1; alignment <= 4096; alignment <<= 1) {
124 char *ptr = (char*)memalign(alignment, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700125 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700126 ASSERT_LE(100U, malloc_usable_size(ptr));
127 ASSERT_EQ(0U, (intptr_t)ptr % alignment);
128 memset(ptr, 0x23, 100);
129
130 ptr = (char*)realloc(ptr, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700131 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700132 ASSERT_LE(200U, malloc_usable_size(ptr));
Yi Kong32bc0fc2018-08-02 17:31:13 -0700133 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700134 for (size_t i = 0; i < 100; i++) {
135 ASSERT_EQ(0x23, ptr[i]);
136 }
137 memset(ptr, 0x45, 200);
138
139 ptr = (char*)realloc(ptr, 300);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700140 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700141 ASSERT_LE(300U, malloc_usable_size(ptr));
142 for (size_t i = 0; i < 200; i++) {
143 ASSERT_EQ(0x45, ptr[i]);
144 }
145 memset(ptr, 0x67, 300);
146
147 ptr = (char*)realloc(ptr, 250);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700148 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700149 ASSERT_LE(250U, malloc_usable_size(ptr));
150 for (size_t i = 0; i < 250; i++) {
151 ASSERT_EQ(0x67, ptr[i]);
152 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700153 free(ptr);
154 }
155}
156
157TEST(malloc, malloc_realloc_larger) {
158 // Realloc to a larger size, malloc is used for the original allocation.
159 char *ptr = (char *)malloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700160 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700161 ASSERT_LE(100U, malloc_usable_size(ptr));
162 memset(ptr, 67, 100);
163
164 ptr = (char *)realloc(ptr, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700165 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700166 ASSERT_LE(200U, malloc_usable_size(ptr));
167 for (size_t i = 0; i < 100; i++) {
168 ASSERT_EQ(67, ptr[i]);
169 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700170 free(ptr);
171}
172
173TEST(malloc, malloc_realloc_smaller) {
174 // Realloc to a smaller size, malloc is used for the original allocation.
175 char *ptr = (char *)malloc(200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700176 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700177 ASSERT_LE(200U, malloc_usable_size(ptr));
178 memset(ptr, 67, 200);
179
180 ptr = (char *)realloc(ptr, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700181 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700182 ASSERT_LE(100U, malloc_usable_size(ptr));
183 for (size_t i = 0; i < 100; i++) {
184 ASSERT_EQ(67, ptr[i]);
185 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700186 free(ptr);
187}
188
189TEST(malloc, malloc_multiple_realloc) {
190 // Multiple reallocs, malloc is used for the original allocation.
191 char *ptr = (char *)malloc(200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700192 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700193 ASSERT_LE(200U, malloc_usable_size(ptr));
194 memset(ptr, 0x23, 200);
195
196 ptr = (char *)realloc(ptr, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700197 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700198 ASSERT_LE(100U, malloc_usable_size(ptr));
199 for (size_t i = 0; i < 100; i++) {
200 ASSERT_EQ(0x23, ptr[i]);
201 }
202
203 ptr = (char*)realloc(ptr, 50);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700204 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700205 ASSERT_LE(50U, malloc_usable_size(ptr));
206 for (size_t i = 0; i < 50; i++) {
207 ASSERT_EQ(0x23, ptr[i]);
208 }
209
210 ptr = (char*)realloc(ptr, 150);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700211 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700212 ASSERT_LE(150U, malloc_usable_size(ptr));
213 for (size_t i = 0; i < 50; i++) {
214 ASSERT_EQ(0x23, ptr[i]);
215 }
216 memset(ptr, 0x23, 150);
217
218 ptr = (char*)realloc(ptr, 425);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700219 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700220 ASSERT_LE(425U, malloc_usable_size(ptr));
221 for (size_t i = 0; i < 150; i++) {
222 ASSERT_EQ(0x23, ptr[i]);
223 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700224 free(ptr);
225}
Christopher Ferrisa4037802014-06-09 19:14:11 -0700226
Christopher Ferris885f3b92013-05-21 17:48:01 -0700227TEST(malloc, calloc_realloc_larger) {
228 // Realloc to a larger size, calloc is used for the original allocation.
229 char *ptr = (char *)calloc(1, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700230 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700231 ASSERT_LE(100U, malloc_usable_size(ptr));
232
233 ptr = (char *)realloc(ptr, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700234 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700235 ASSERT_LE(200U, malloc_usable_size(ptr));
236 for (size_t i = 0; i < 100; i++) {
237 ASSERT_EQ(0, ptr[i]);
238 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700239 free(ptr);
240}
241
242TEST(malloc, calloc_realloc_smaller) {
243 // Realloc to a smaller size, calloc is used for the original allocation.
244 char *ptr = (char *)calloc(1, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700245 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700246 ASSERT_LE(200U, malloc_usable_size(ptr));
247
248 ptr = (char *)realloc(ptr, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700249 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700250 ASSERT_LE(100U, malloc_usable_size(ptr));
251 for (size_t i = 0; i < 100; i++) {
252 ASSERT_EQ(0, ptr[i]);
253 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700254 free(ptr);
255}
256
257TEST(malloc, calloc_multiple_realloc) {
258 // Multiple reallocs, calloc is used for the original allocation.
259 char *ptr = (char *)calloc(1, 200);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700260 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700261 ASSERT_LE(200U, malloc_usable_size(ptr));
262
263 ptr = (char *)realloc(ptr, 100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700264 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700265 ASSERT_LE(100U, malloc_usable_size(ptr));
266 for (size_t i = 0; i < 100; i++) {
267 ASSERT_EQ(0, ptr[i]);
268 }
269
270 ptr = (char*)realloc(ptr, 50);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700271 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700272 ASSERT_LE(50U, malloc_usable_size(ptr));
273 for (size_t i = 0; i < 50; i++) {
274 ASSERT_EQ(0, ptr[i]);
275 }
276
277 ptr = (char*)realloc(ptr, 150);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700278 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700279 ASSERT_LE(150U, malloc_usable_size(ptr));
280 for (size_t i = 0; i < 50; i++) {
281 ASSERT_EQ(0, ptr[i]);
282 }
283 memset(ptr, 0, 150);
284
285 ptr = (char*)realloc(ptr, 425);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700286 ASSERT_TRUE(ptr != nullptr);
Christopher Ferris885f3b92013-05-21 17:48:01 -0700287 ASSERT_LE(425U, malloc_usable_size(ptr));
288 for (size_t i = 0; i < 150; i++) {
289 ASSERT_EQ(0, ptr[i]);
290 }
Christopher Ferris885f3b92013-05-21 17:48:01 -0700291 free(ptr);
292}
Christopher Ferris72bbd422014-05-08 11:14:03 -0700293
Christopher Ferrisa4037802014-06-09 19:14:11 -0700294TEST(malloc, realloc_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800295 SKIP_WITH_HWASAN;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700296 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700297 ASSERT_EQ(nullptr, realloc(nullptr, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -0700298 ASSERT_EQ(ENOMEM, errno);
299 void* ptr = malloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700300 ASSERT_TRUE(ptr != nullptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700301 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700302 ASSERT_EQ(nullptr, realloc(ptr, SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -0700303 ASSERT_EQ(ENOMEM, errno);
304 free(ptr);
Christopher Ferris72bbd422014-05-08 11:14:03 -0700305}
306
Dan Alberte5fdaa42014-06-14 01:04:31 +0000307#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
308extern "C" void* pvalloc(size_t);
309extern "C" void* valloc(size_t);
310
Christopher Ferrisa4037802014-06-09 19:14:11 -0700311TEST(malloc, pvalloc_std) {
312 size_t pagesize = sysconf(_SC_PAGESIZE);
313 void* ptr = pvalloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700314 ASSERT_TRUE(ptr != nullptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700315 ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0);
316 ASSERT_LE(pagesize, malloc_usable_size(ptr));
317 free(ptr);
318}
319
320TEST(malloc, pvalloc_overflow) {
Yi Kong32bc0fc2018-08-02 17:31:13 -0700321 ASSERT_EQ(nullptr, pvalloc(SIZE_MAX));
Christopher Ferrisa4037802014-06-09 19:14:11 -0700322}
323
324TEST(malloc, valloc_std) {
325 size_t pagesize = sysconf(_SC_PAGESIZE);
326 void* ptr = pvalloc(100);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700327 ASSERT_TRUE(ptr != nullptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700328 ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0);
329 free(ptr);
330}
331
332TEST(malloc, valloc_overflow) {
Yi Kong32bc0fc2018-08-02 17:31:13 -0700333 ASSERT_EQ(nullptr, valloc(SIZE_MAX));
Christopher Ferris72bbd422014-05-08 11:14:03 -0700334}
Dan Alberte5fdaa42014-06-14 01:04:31 +0000335#endif
Dan Albert4caa1f02014-08-20 09:16:57 -0700336
337TEST(malloc, malloc_info) {
338#ifdef __BIONIC__
339 char* buf;
340 size_t bufsize;
341 FILE* memstream = open_memstream(&buf, &bufsize);
342 ASSERT_NE(nullptr, memstream);
343 ASSERT_EQ(0, malloc_info(0, memstream));
344 ASSERT_EQ(0, fclose(memstream));
345
346 tinyxml2::XMLDocument doc;
347 ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(buf));
348
349 auto root = doc.FirstChildElement();
350 ASSERT_NE(nullptr, root);
351 ASSERT_STREQ("malloc", root->Name());
Christopher Ferris6c619a02019-03-01 17:59:51 -0800352 if (std::string(root->Attribute("version")) == "jemalloc-1") {
353 // Verify jemalloc version of this data.
354 ASSERT_STREQ("jemalloc-1", root->Attribute("version"));
Dan Albert4caa1f02014-08-20 09:16:57 -0700355
Christopher Ferris6c619a02019-03-01 17:59:51 -0800356 auto arena = root->FirstChildElement();
357 for (; arena != nullptr; arena = arena->NextSiblingElement()) {
358 int val;
Dan Albert4caa1f02014-08-20 09:16:57 -0700359
Christopher Ferris6c619a02019-03-01 17:59:51 -0800360 ASSERT_STREQ("heap", arena->Name());
361 ASSERT_EQ(tinyxml2::XML_SUCCESS, arena->QueryIntAttribute("nr", &val));
362 ASSERT_EQ(tinyxml2::XML_SUCCESS,
363 arena->FirstChildElement("allocated-large")->QueryIntText(&val));
364 ASSERT_EQ(tinyxml2::XML_SUCCESS,
365 arena->FirstChildElement("allocated-huge")->QueryIntText(&val));
366 ASSERT_EQ(tinyxml2::XML_SUCCESS,
367 arena->FirstChildElement("allocated-bins")->QueryIntText(&val));
368 ASSERT_EQ(tinyxml2::XML_SUCCESS,
369 arena->FirstChildElement("bins-total")->QueryIntText(&val));
Dan Albert4caa1f02014-08-20 09:16:57 -0700370
Christopher Ferris6c619a02019-03-01 17:59:51 -0800371 auto bin = arena->FirstChildElement("bin");
372 for (; bin != nullptr; bin = bin ->NextSiblingElement()) {
373 if (strcmp(bin->Name(), "bin") == 0) {
374 ASSERT_EQ(tinyxml2::XML_SUCCESS, bin->QueryIntAttribute("nr", &val));
375 ASSERT_EQ(tinyxml2::XML_SUCCESS,
376 bin->FirstChildElement("allocated")->QueryIntText(&val));
377 ASSERT_EQ(tinyxml2::XML_SUCCESS,
378 bin->FirstChildElement("nmalloc")->QueryIntText(&val));
379 ASSERT_EQ(tinyxml2::XML_SUCCESS,
380 bin->FirstChildElement("ndalloc")->QueryIntText(&val));
381 }
Dan Albert4caa1f02014-08-20 09:16:57 -0700382 }
383 }
Christopher Ferris6c619a02019-03-01 17:59:51 -0800384 } else {
385 // Only verify that this is debug-malloc-1, the malloc debug unit tests
386 // verify the output.
387 ASSERT_STREQ("debug-malloc-1", root->Attribute("version"));
Dan Albert4caa1f02014-08-20 09:16:57 -0700388 }
389#endif
390}
Christopher Ferrisad33ebe2015-12-16 12:07:25 -0800391
392TEST(malloc, calloc_usable_size) {
393 for (size_t size = 1; size <= 2048; size++) {
394 void* pointer = malloc(size);
395 ASSERT_TRUE(pointer != nullptr);
396 memset(pointer, 0xeb, malloc_usable_size(pointer));
397 free(pointer);
398
399 // We should get a previous pointer that has been set to non-zero.
400 // If calloc does not zero out all of the data, this will fail.
401 uint8_t* zero_mem = reinterpret_cast<uint8_t*>(calloc(1, size));
402 ASSERT_TRUE(pointer != nullptr);
403 size_t usable_size = malloc_usable_size(zero_mem);
404 for (size_t i = 0; i < usable_size; i++) {
405 ASSERT_EQ(0, zero_mem[i]) << "Failed at allocation size " << size << " at byte " << i;
406 }
407 free(zero_mem);
408 }
409}
Elliott Hughes884f76e2016-02-10 20:43:22 -0800410
411TEST(malloc, malloc_0) {
412 void* p = malloc(0);
413 ASSERT_TRUE(p != nullptr);
414 free(p);
415}
416
417TEST(malloc, calloc_0_0) {
418 void* p = calloc(0, 0);
419 ASSERT_TRUE(p != nullptr);
420 free(p);
421}
422
423TEST(malloc, calloc_0_1) {
424 void* p = calloc(0, 1);
425 ASSERT_TRUE(p != nullptr);
426 free(p);
427}
428
429TEST(malloc, calloc_1_0) {
430 void* p = calloc(1, 0);
431 ASSERT_TRUE(p != nullptr);
432 free(p);
433}
434
435TEST(malloc, realloc_nullptr_0) {
436 // realloc(nullptr, size) is actually malloc(size).
437 void* p = realloc(nullptr, 0);
438 ASSERT_TRUE(p != nullptr);
439 free(p);
440}
441
442TEST(malloc, realloc_0) {
443 void* p = malloc(1024);
444 ASSERT_TRUE(p != nullptr);
445 // realloc(p, 0) is actually free(p).
446 void* p2 = realloc(p, 0);
447 ASSERT_TRUE(p2 == nullptr);
448}
Christopher Ferris72df6702016-02-11 15:51:31 -0800449
450constexpr size_t MAX_LOOPS = 200;
451
452// Make sure that memory returned by malloc is aligned to allow these data types.
453TEST(malloc, verify_alignment) {
454 uint32_t** values_32 = new uint32_t*[MAX_LOOPS];
455 uint64_t** values_64 = new uint64_t*[MAX_LOOPS];
456 long double** values_ldouble = new long double*[MAX_LOOPS];
457 // Use filler to attempt to force the allocator to get potentially bad alignments.
458 void** filler = new void*[MAX_LOOPS];
459
460 for (size_t i = 0; i < MAX_LOOPS; i++) {
461 // Check uint32_t pointers.
462 filler[i] = malloc(1);
463 ASSERT_TRUE(filler[i] != nullptr);
464
465 values_32[i] = reinterpret_cast<uint32_t*>(malloc(sizeof(uint32_t)));
466 ASSERT_TRUE(values_32[i] != nullptr);
467 *values_32[i] = i;
468 ASSERT_EQ(*values_32[i], i);
469 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_32[i]) & (sizeof(uint32_t) - 1));
470
471 free(filler[i]);
472 }
473
474 for (size_t i = 0; i < MAX_LOOPS; i++) {
475 // Check uint64_t pointers.
476 filler[i] = malloc(1);
477 ASSERT_TRUE(filler[i] != nullptr);
478
479 values_64[i] = reinterpret_cast<uint64_t*>(malloc(sizeof(uint64_t)));
480 ASSERT_TRUE(values_64[i] != nullptr);
481 *values_64[i] = 0x1000 + i;
482 ASSERT_EQ(*values_64[i], 0x1000 + i);
483 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_64[i]) & (sizeof(uint64_t) - 1));
484
485 free(filler[i]);
486 }
487
488 for (size_t i = 0; i < MAX_LOOPS; i++) {
489 // Check long double pointers.
490 filler[i] = malloc(1);
491 ASSERT_TRUE(filler[i] != nullptr);
492
493 values_ldouble[i] = reinterpret_cast<long double*>(malloc(sizeof(long double)));
494 ASSERT_TRUE(values_ldouble[i] != nullptr);
495 *values_ldouble[i] = 5.5 + i;
496 ASSERT_DOUBLE_EQ(*values_ldouble[i], 5.5 + i);
497 // 32 bit glibc has a long double size of 12 bytes, so hardcode the
498 // required alignment to 0x7.
499#if !defined(__BIONIC__) && !defined(__LP64__)
500 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_ldouble[i]) & 0x7);
501#else
502 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_ldouble[i]) & (sizeof(long double) - 1));
503#endif
504
505 free(filler[i]);
506 }
507
508 for (size_t i = 0; i < MAX_LOOPS; i++) {
509 free(values_32[i]);
510 free(values_64[i]);
511 free(values_ldouble[i]);
512 }
513
514 delete[] filler;
515 delete[] values_32;
516 delete[] values_64;
517 delete[] values_ldouble;
518}
Christopher Ferrisa1c0d2f2017-05-15 15:50:19 -0700519
520TEST(malloc, mallopt_smoke) {
521 errno = 0;
522 ASSERT_EQ(0, mallopt(-1000, 1));
523 // mallopt doesn't set errno.
524 ASSERT_EQ(0, errno);
525}
Elliott Hughesb1770852018-09-18 12:52:42 -0700526
Christopher Ferrisaf1b8dd2018-11-07 15:28:16 -0800527TEST(malloc, mallopt_decay) {
528#if defined(__BIONIC__)
Evgenii Stepanov7cc67062019-02-05 18:43:34 -0800529 SKIP_WITH_HWASAN; // hwasan does not implement mallopt
Christopher Ferrisaf1b8dd2018-11-07 15:28:16 -0800530 errno = 0;
531 ASSERT_EQ(1, mallopt(M_DECAY_TIME, 1));
532 ASSERT_EQ(1, mallopt(M_DECAY_TIME, 0));
533 ASSERT_EQ(1, mallopt(M_DECAY_TIME, 1));
534 ASSERT_EQ(1, mallopt(M_DECAY_TIME, 0));
535#else
536 GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
537#endif
538}
539
540TEST(malloc, mallopt_purge) {
541#if defined(__BIONIC__)
Evgenii Stepanov7cc67062019-02-05 18:43:34 -0800542 SKIP_WITH_HWASAN; // hwasan does not implement mallopt
Christopher Ferrisaf1b8dd2018-11-07 15:28:16 -0800543 errno = 0;
544 ASSERT_EQ(1, mallopt(M_PURGE, 0));
545#else
546 GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
547#endif
548}
549
Elliott Hughesb1770852018-09-18 12:52:42 -0700550TEST(malloc, reallocarray_overflow) {
551#if HAVE_REALLOCARRAY
552 // Values that cause overflow to a result small enough (8 on LP64) that malloc would "succeed".
553 size_t a = static_cast<size_t>(INTPTR_MIN + 4);
554 size_t b = 2;
555
556 errno = 0;
557 ASSERT_TRUE(reallocarray(nullptr, a, b) == nullptr);
558 ASSERT_EQ(ENOMEM, errno);
559
560 errno = 0;
561 ASSERT_TRUE(reallocarray(nullptr, b, a) == nullptr);
562 ASSERT_EQ(ENOMEM, errno);
563#else
564 GTEST_LOG_(INFO) << "This test requires a C library with reallocarray.\n";
565#endif
566}
567
568TEST(malloc, reallocarray) {
569#if HAVE_REALLOCARRAY
570 void* p = reallocarray(nullptr, 2, 32);
571 ASSERT_TRUE(p != nullptr);
572 ASSERT_GE(malloc_usable_size(p), 64U);
573#else
574 GTEST_LOG_(INFO) << "This test requires a C library with reallocarray.\n";
575#endif
576}
Christopher Ferris09a19aa2018-11-16 13:28:56 -0800577
578TEST(malloc, mallinfo) {
579#if defined(__BIONIC__)
Evgenii Stepanov7cc67062019-02-05 18:43:34 -0800580 SKIP_WITH_HWASAN; // hwasan does not implement mallinfo
Christopher Ferris09a19aa2018-11-16 13:28:56 -0800581 static size_t sizes[] = {
582 8, 32, 128, 4096, 32768, 131072, 1024000, 10240000, 20480000, 300000000
583 };
584
585 constexpr static size_t kMaxAllocs = 50;
586
587 for (size_t size : sizes) {
588 // If some of these allocations are stuck in a thread cache, then keep
589 // looping until we make an allocation that changes the total size of the
590 // memory allocated.
591 // jemalloc implementations counts the thread cache allocations against
592 // total memory allocated.
593 void* ptrs[kMaxAllocs] = {};
594 bool pass = false;
595 for (size_t i = 0; i < kMaxAllocs; i++) {
596 size_t allocated = mallinfo().uordblks;
597 ptrs[i] = malloc(size);
598 ASSERT_TRUE(ptrs[i] != nullptr);
599 size_t new_allocated = mallinfo().uordblks;
600 if (allocated != new_allocated) {
601 size_t usable_size = malloc_usable_size(ptrs[i]);
Christopher Ferris4e562282019-02-07 14:20:03 -0800602 // Only check if the total got bigger by at least allocation size.
603 // Sometimes the mallinfo numbers can go backwards due to compaction
604 // and/or freeing of cached data.
605 if (new_allocated >= allocated + usable_size) {
606 pass = true;
607 break;
608 }
Christopher Ferris09a19aa2018-11-16 13:28:56 -0800609 }
610 }
611 for (void* ptr : ptrs) {
612 free(ptr);
613 }
614 ASSERT_TRUE(pass)
615 << "For size " << size << " allocated bytes did not increase after "
616 << kMaxAllocs << " allocations.";
617 }
618#else
619 GTEST_LOG_(INFO) << "Host glibc does not pass this test, skipping.\n";
620#endif
621}
Ryan Savitskiecc37e32018-12-14 15:57:21 +0000622
623TEST(android_mallopt, error_on_unexpected_option) {
624#if defined(__BIONIC__)
625 const int unrecognized_option = -1;
626 errno = 0;
627 EXPECT_EQ(false, android_mallopt(unrecognized_option, nullptr, 0));
628 EXPECT_EQ(ENOTSUP, errno);
629#else
630 GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
631#endif
632}
633
Christopher Ferrise4cdbc42019-02-08 17:30:58 -0800634bool IsDynamic() {
635#if defined(__LP64__)
636 Elf64_Ehdr ehdr;
637#else
638 Elf32_Ehdr ehdr;
639#endif
640 std::string path(android::base::GetExecutablePath());
641
642 int fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
643 if (fd == -1) {
644 // Assume dynamic on error.
645 return true;
646 }
647 bool read_completed = android::base::ReadFully(fd, &ehdr, sizeof(ehdr));
648 close(fd);
649 // Assume dynamic in error cases.
650 return !read_completed || ehdr.e_type == ET_DYN;
651}
652
Ryan Savitskiecc37e32018-12-14 15:57:21 +0000653TEST(android_mallopt, init_zygote_child_profiling) {
654#if defined(__BIONIC__)
655 // Successful call.
656 errno = 0;
Christopher Ferrise4cdbc42019-02-08 17:30:58 -0800657 if (IsDynamic()) {
658 EXPECT_EQ(true, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0));
659 EXPECT_EQ(0, errno);
660 } else {
661 // Not supported in static executables.
662 EXPECT_EQ(false, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0));
663 EXPECT_EQ(ENOTSUP, errno);
664 }
Ryan Savitskiecc37e32018-12-14 15:57:21 +0000665
666 // Unexpected arguments rejected.
667 errno = 0;
668 char unexpected = 0;
669 EXPECT_EQ(false, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, &unexpected, 1));
Christopher Ferrise4cdbc42019-02-08 17:30:58 -0800670 if (IsDynamic()) {
671 EXPECT_EQ(EINVAL, errno);
672 } else {
673 EXPECT_EQ(ENOTSUP, errno);
674 }
Ryan Savitskiecc37e32018-12-14 15:57:21 +0000675#else
676 GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
677#endif
678}