1*8d67ca89SAndroid Build Coastguard Worker /*
2*8d67ca89SAndroid Build Coastguard Worker * Copyright (C) 2013 The Android Open Source Project
3*8d67ca89SAndroid Build Coastguard Worker *
4*8d67ca89SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*8d67ca89SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*8d67ca89SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*8d67ca89SAndroid Build Coastguard Worker *
8*8d67ca89SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*8d67ca89SAndroid Build Coastguard Worker *
10*8d67ca89SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*8d67ca89SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*8d67ca89SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8d67ca89SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*8d67ca89SAndroid Build Coastguard Worker * limitations under the License.
15*8d67ca89SAndroid Build Coastguard Worker */
16*8d67ca89SAndroid Build Coastguard Worker
17*8d67ca89SAndroid Build Coastguard Worker #include <gtest/gtest.h>
18*8d67ca89SAndroid Build Coastguard Worker
19*8d67ca89SAndroid Build Coastguard Worker #include <elf.h>
20*8d67ca89SAndroid Build Coastguard Worker #include <limits.h>
21*8d67ca89SAndroid Build Coastguard Worker #include <malloc.h>
22*8d67ca89SAndroid Build Coastguard Worker #include <pthread.h>
23*8d67ca89SAndroid Build Coastguard Worker #include <semaphore.h>
24*8d67ca89SAndroid Build Coastguard Worker #include <signal.h>
25*8d67ca89SAndroid Build Coastguard Worker #include <stdint.h>
26*8d67ca89SAndroid Build Coastguard Worker #include <stdio.h>
27*8d67ca89SAndroid Build Coastguard Worker #include <stdlib.h>
28*8d67ca89SAndroid Build Coastguard Worker #include <string.h>
29*8d67ca89SAndroid Build Coastguard Worker #include <sys/auxv.h>
30*8d67ca89SAndroid Build Coastguard Worker #include <sys/cdefs.h>
31*8d67ca89SAndroid Build Coastguard Worker #include <sys/prctl.h>
32*8d67ca89SAndroid Build Coastguard Worker #include <sys/types.h>
33*8d67ca89SAndroid Build Coastguard Worker #include <sys/wait.h>
34*8d67ca89SAndroid Build Coastguard Worker #include <unistd.h>
35*8d67ca89SAndroid Build Coastguard Worker
36*8d67ca89SAndroid Build Coastguard Worker #include <algorithm>
37*8d67ca89SAndroid Build Coastguard Worker #include <atomic>
38*8d67ca89SAndroid Build Coastguard Worker #include <functional>
39*8d67ca89SAndroid Build Coastguard Worker #include <string>
40*8d67ca89SAndroid Build Coastguard Worker #include <thread>
41*8d67ca89SAndroid Build Coastguard Worker #include <unordered_map>
42*8d67ca89SAndroid Build Coastguard Worker #include <utility>
43*8d67ca89SAndroid Build Coastguard Worker #include <vector>
44*8d67ca89SAndroid Build Coastguard Worker
45*8d67ca89SAndroid Build Coastguard Worker #include <tinyxml2.h>
46*8d67ca89SAndroid Build Coastguard Worker
47*8d67ca89SAndroid Build Coastguard Worker #include <android-base/file.h>
48*8d67ca89SAndroid Build Coastguard Worker #include <android-base/test_utils.h>
49*8d67ca89SAndroid Build Coastguard Worker
50*8d67ca89SAndroid Build Coastguard Worker #include "DoNotOptimize.h"
51*8d67ca89SAndroid Build Coastguard Worker #include "utils.h"
52*8d67ca89SAndroid Build Coastguard Worker
53*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
54*8d67ca89SAndroid Build Coastguard Worker
55*8d67ca89SAndroid Build Coastguard Worker #include "SignalUtils.h"
56*8d67ca89SAndroid Build Coastguard Worker #include "dlext_private.h"
57*8d67ca89SAndroid Build Coastguard Worker
58*8d67ca89SAndroid Build Coastguard Worker #include "platform/bionic/malloc.h"
59*8d67ca89SAndroid Build Coastguard Worker #include "platform/bionic/mte.h"
60*8d67ca89SAndroid Build Coastguard Worker #include "platform/bionic/reserved_signals.h"
61*8d67ca89SAndroid Build Coastguard Worker #include "private/bionic_config.h"
62*8d67ca89SAndroid Build Coastguard Worker
63*8d67ca89SAndroid Build Coastguard Worker #define HAVE_REALLOCARRAY 1
64*8d67ca89SAndroid Build Coastguard Worker
65*8d67ca89SAndroid Build Coastguard Worker #elif defined(__GLIBC__)
66*8d67ca89SAndroid Build Coastguard Worker
67*8d67ca89SAndroid Build Coastguard Worker #define HAVE_REALLOCARRAY __GLIBC_PREREQ(2, 26)
68*8d67ca89SAndroid Build Coastguard Worker
69*8d67ca89SAndroid Build Coastguard Worker #elif defined(ANDROID_HOST_MUSL)
70*8d67ca89SAndroid Build Coastguard Worker
71*8d67ca89SAndroid Build Coastguard Worker #define HAVE_REALLOCARRAY 1
72*8d67ca89SAndroid Build Coastguard Worker
73*8d67ca89SAndroid Build Coastguard Worker #endif
74*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,malloc_std)75*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, malloc_std) {
76*8d67ca89SAndroid Build Coastguard Worker // Simple malloc test.
77*8d67ca89SAndroid Build Coastguard Worker void *ptr = malloc(100);
78*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
79*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(100U, malloc_usable_size(ptr));
80*8d67ca89SAndroid Build Coastguard Worker free(ptr);
81*8d67ca89SAndroid Build Coastguard Worker }
82*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,malloc_overflow)83*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, malloc_overflow) {
84*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN;
85*8d67ca89SAndroid Build Coastguard Worker errno = 0;
86*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, malloc(SIZE_MAX));
87*8d67ca89SAndroid Build Coastguard Worker ASSERT_ERRNO(ENOMEM);
88*8d67ca89SAndroid Build Coastguard Worker }
89*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,calloc_std)90*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, calloc_std) {
91*8d67ca89SAndroid Build Coastguard Worker // Simple calloc test.
92*8d67ca89SAndroid Build Coastguard Worker size_t alloc_len = 100;
93*8d67ca89SAndroid Build Coastguard Worker char *ptr = (char *)calloc(1, alloc_len);
94*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
95*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(alloc_len, malloc_usable_size(ptr));
96*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < alloc_len; i++) {
97*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, ptr[i]);
98*8d67ca89SAndroid Build Coastguard Worker }
99*8d67ca89SAndroid Build Coastguard Worker free(ptr);
100*8d67ca89SAndroid Build Coastguard Worker }
101*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,calloc_mem_init_disabled)102*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, calloc_mem_init_disabled) {
103*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
104*8d67ca89SAndroid Build Coastguard Worker // calloc should still zero memory if mem-init is disabled.
105*8d67ca89SAndroid Build Coastguard Worker // With jemalloc the mallopts will fail but that shouldn't affect the
106*8d67ca89SAndroid Build Coastguard Worker // execution of the test.
107*8d67ca89SAndroid Build Coastguard Worker mallopt(M_THREAD_DISABLE_MEM_INIT, 1);
108*8d67ca89SAndroid Build Coastguard Worker size_t alloc_len = 100;
109*8d67ca89SAndroid Build Coastguard Worker char *ptr = reinterpret_cast<char*>(calloc(1, alloc_len));
110*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < alloc_len; i++) {
111*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, ptr[i]);
112*8d67ca89SAndroid Build Coastguard Worker }
113*8d67ca89SAndroid Build Coastguard Worker free(ptr);
114*8d67ca89SAndroid Build Coastguard Worker mallopt(M_THREAD_DISABLE_MEM_INIT, 0);
115*8d67ca89SAndroid Build Coastguard Worker #else
116*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
117*8d67ca89SAndroid Build Coastguard Worker #endif
118*8d67ca89SAndroid Build Coastguard Worker }
119*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,calloc_illegal)120*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, calloc_illegal) {
121*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN;
122*8d67ca89SAndroid Build Coastguard Worker errno = 0;
123*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, calloc(-1, 100));
124*8d67ca89SAndroid Build Coastguard Worker ASSERT_ERRNO(ENOMEM);
125*8d67ca89SAndroid Build Coastguard Worker }
126*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,calloc_overflow)127*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, calloc_overflow) {
128*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN;
129*8d67ca89SAndroid Build Coastguard Worker errno = 0;
130*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, calloc(1, SIZE_MAX));
131*8d67ca89SAndroid Build Coastguard Worker ASSERT_ERRNO(ENOMEM);
132*8d67ca89SAndroid Build Coastguard Worker errno = 0;
133*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, calloc(SIZE_MAX, SIZE_MAX));
134*8d67ca89SAndroid Build Coastguard Worker ASSERT_ERRNO(ENOMEM);
135*8d67ca89SAndroid Build Coastguard Worker errno = 0;
136*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, calloc(2, SIZE_MAX));
137*8d67ca89SAndroid Build Coastguard Worker ASSERT_ERRNO(ENOMEM);
138*8d67ca89SAndroid Build Coastguard Worker errno = 0;
139*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, calloc(SIZE_MAX, 2));
140*8d67ca89SAndroid Build Coastguard Worker ASSERT_ERRNO(ENOMEM);
141*8d67ca89SAndroid Build Coastguard Worker }
142*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,memalign_multiple)143*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, memalign_multiple) {
144*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN << "hwasan requires power of 2 alignment";
145*8d67ca89SAndroid Build Coastguard Worker // Memalign test where the alignment is any value.
146*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i <= 12; i++) {
147*8d67ca89SAndroid Build Coastguard Worker for (size_t alignment = 1 << i; alignment < (1U << (i+1)); alignment++) {
148*8d67ca89SAndroid Build Coastguard Worker char *ptr = reinterpret_cast<char*>(memalign(alignment, 100));
149*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr) << "Failed at alignment " << alignment;
150*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(100U, malloc_usable_size(ptr)) << "Failed at alignment " << alignment;
151*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) % ((1U << i)))
152*8d67ca89SAndroid Build Coastguard Worker << "Failed at alignment " << alignment;
153*8d67ca89SAndroid Build Coastguard Worker free(ptr);
154*8d67ca89SAndroid Build Coastguard Worker }
155*8d67ca89SAndroid Build Coastguard Worker }
156*8d67ca89SAndroid Build Coastguard Worker }
157*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,memalign_overflow)158*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, memalign_overflow) {
159*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN;
160*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, memalign(4096, SIZE_MAX));
161*8d67ca89SAndroid Build Coastguard Worker }
162*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,memalign_non_power2)163*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, memalign_non_power2) {
164*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN;
165*8d67ca89SAndroid Build Coastguard Worker void* ptr;
166*8d67ca89SAndroid Build Coastguard Worker for (size_t align = 0; align <= 256; align++) {
167*8d67ca89SAndroid Build Coastguard Worker ptr = memalign(align, 1024);
168*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr) << "Failed at align " << align;
169*8d67ca89SAndroid Build Coastguard Worker free(ptr);
170*8d67ca89SAndroid Build Coastguard Worker }
171*8d67ca89SAndroid Build Coastguard Worker }
172*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,memalign_realloc)173*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, memalign_realloc) {
174*8d67ca89SAndroid Build Coastguard Worker // Memalign and then realloc the pointer a couple of times.
175*8d67ca89SAndroid Build Coastguard Worker for (size_t alignment = 1; alignment <= 4096; alignment <<= 1) {
176*8d67ca89SAndroid Build Coastguard Worker char *ptr = (char*)memalign(alignment, 100);
177*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
178*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(100U, malloc_usable_size(ptr));
179*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0U, (intptr_t)ptr % alignment);
180*8d67ca89SAndroid Build Coastguard Worker memset(ptr, 0x23, 100);
181*8d67ca89SAndroid Build Coastguard Worker
182*8d67ca89SAndroid Build Coastguard Worker ptr = (char*)realloc(ptr, 200);
183*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
184*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(200U, malloc_usable_size(ptr));
185*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
186*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < 100; i++) {
187*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0x23, ptr[i]);
188*8d67ca89SAndroid Build Coastguard Worker }
189*8d67ca89SAndroid Build Coastguard Worker memset(ptr, 0x45, 200);
190*8d67ca89SAndroid Build Coastguard Worker
191*8d67ca89SAndroid Build Coastguard Worker ptr = (char*)realloc(ptr, 300);
192*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
193*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(300U, malloc_usable_size(ptr));
194*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < 200; i++) {
195*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0x45, ptr[i]);
196*8d67ca89SAndroid Build Coastguard Worker }
197*8d67ca89SAndroid Build Coastguard Worker memset(ptr, 0x67, 300);
198*8d67ca89SAndroid Build Coastguard Worker
199*8d67ca89SAndroid Build Coastguard Worker ptr = (char*)realloc(ptr, 250);
200*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
201*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(250U, malloc_usable_size(ptr));
202*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < 250; i++) {
203*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0x67, ptr[i]);
204*8d67ca89SAndroid Build Coastguard Worker }
205*8d67ca89SAndroid Build Coastguard Worker free(ptr);
206*8d67ca89SAndroid Build Coastguard Worker }
207*8d67ca89SAndroid Build Coastguard Worker }
208*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,malloc_realloc_larger)209*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, malloc_realloc_larger) {
210*8d67ca89SAndroid Build Coastguard Worker // Realloc to a larger size, malloc is used for the original allocation.
211*8d67ca89SAndroid Build Coastguard Worker char *ptr = (char *)malloc(100);
212*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
213*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(100U, malloc_usable_size(ptr));
214*8d67ca89SAndroid Build Coastguard Worker memset(ptr, 67, 100);
215*8d67ca89SAndroid Build Coastguard Worker
216*8d67ca89SAndroid Build Coastguard Worker ptr = (char *)realloc(ptr, 200);
217*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
218*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(200U, malloc_usable_size(ptr));
219*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < 100; i++) {
220*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(67, ptr[i]);
221*8d67ca89SAndroid Build Coastguard Worker }
222*8d67ca89SAndroid Build Coastguard Worker free(ptr);
223*8d67ca89SAndroid Build Coastguard Worker }
224*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,malloc_realloc_smaller)225*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, malloc_realloc_smaller) {
226*8d67ca89SAndroid Build Coastguard Worker // Realloc to a smaller size, malloc is used for the original allocation.
227*8d67ca89SAndroid Build Coastguard Worker char *ptr = (char *)malloc(200);
228*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
229*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(200U, malloc_usable_size(ptr));
230*8d67ca89SAndroid Build Coastguard Worker memset(ptr, 67, 200);
231*8d67ca89SAndroid Build Coastguard Worker
232*8d67ca89SAndroid Build Coastguard Worker ptr = (char *)realloc(ptr, 100);
233*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
234*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(100U, malloc_usable_size(ptr));
235*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < 100; i++) {
236*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(67, ptr[i]);
237*8d67ca89SAndroid Build Coastguard Worker }
238*8d67ca89SAndroid Build Coastguard Worker free(ptr);
239*8d67ca89SAndroid Build Coastguard Worker }
240*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,malloc_multiple_realloc)241*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, malloc_multiple_realloc) {
242*8d67ca89SAndroid Build Coastguard Worker // Multiple reallocs, malloc is used for the original allocation.
243*8d67ca89SAndroid Build Coastguard Worker char *ptr = (char *)malloc(200);
244*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
245*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(200U, malloc_usable_size(ptr));
246*8d67ca89SAndroid Build Coastguard Worker memset(ptr, 0x23, 200);
247*8d67ca89SAndroid Build Coastguard Worker
248*8d67ca89SAndroid Build Coastguard Worker ptr = (char *)realloc(ptr, 100);
249*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
250*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(100U, malloc_usable_size(ptr));
251*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < 100; i++) {
252*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0x23, ptr[i]);
253*8d67ca89SAndroid Build Coastguard Worker }
254*8d67ca89SAndroid Build Coastguard Worker
255*8d67ca89SAndroid Build Coastguard Worker ptr = (char*)realloc(ptr, 50);
256*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
257*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(50U, malloc_usable_size(ptr));
258*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < 50; i++) {
259*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0x23, ptr[i]);
260*8d67ca89SAndroid Build Coastguard Worker }
261*8d67ca89SAndroid Build Coastguard Worker
262*8d67ca89SAndroid Build Coastguard Worker ptr = (char*)realloc(ptr, 150);
263*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
264*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(150U, malloc_usable_size(ptr));
265*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < 50; i++) {
266*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0x23, ptr[i]);
267*8d67ca89SAndroid Build Coastguard Worker }
268*8d67ca89SAndroid Build Coastguard Worker memset(ptr, 0x23, 150);
269*8d67ca89SAndroid Build Coastguard Worker
270*8d67ca89SAndroid Build Coastguard Worker ptr = (char*)realloc(ptr, 425);
271*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
272*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(425U, malloc_usable_size(ptr));
273*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < 150; i++) {
274*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0x23, ptr[i]);
275*8d67ca89SAndroid Build Coastguard Worker }
276*8d67ca89SAndroid Build Coastguard Worker free(ptr);
277*8d67ca89SAndroid Build Coastguard Worker }
278*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,calloc_realloc_larger)279*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, calloc_realloc_larger) {
280*8d67ca89SAndroid Build Coastguard Worker // Realloc to a larger size, calloc is used for the original allocation.
281*8d67ca89SAndroid Build Coastguard Worker char *ptr = (char *)calloc(1, 100);
282*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
283*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(100U, malloc_usable_size(ptr));
284*8d67ca89SAndroid Build Coastguard Worker
285*8d67ca89SAndroid Build Coastguard Worker ptr = (char *)realloc(ptr, 200);
286*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
287*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(200U, malloc_usable_size(ptr));
288*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < 100; i++) {
289*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, ptr[i]);
290*8d67ca89SAndroid Build Coastguard Worker }
291*8d67ca89SAndroid Build Coastguard Worker free(ptr);
292*8d67ca89SAndroid Build Coastguard Worker }
293*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,calloc_realloc_smaller)294*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, calloc_realloc_smaller) {
295*8d67ca89SAndroid Build Coastguard Worker // Realloc to a smaller size, calloc is used for the original allocation.
296*8d67ca89SAndroid Build Coastguard Worker char *ptr = (char *)calloc(1, 200);
297*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
298*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(200U, malloc_usable_size(ptr));
299*8d67ca89SAndroid Build Coastguard Worker
300*8d67ca89SAndroid Build Coastguard Worker ptr = (char *)realloc(ptr, 100);
301*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
302*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(100U, malloc_usable_size(ptr));
303*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < 100; i++) {
304*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, ptr[i]);
305*8d67ca89SAndroid Build Coastguard Worker }
306*8d67ca89SAndroid Build Coastguard Worker free(ptr);
307*8d67ca89SAndroid Build Coastguard Worker }
308*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,calloc_multiple_realloc)309*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, calloc_multiple_realloc) {
310*8d67ca89SAndroid Build Coastguard Worker // Multiple reallocs, calloc is used for the original allocation.
311*8d67ca89SAndroid Build Coastguard Worker char *ptr = (char *)calloc(1, 200);
312*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
313*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(200U, malloc_usable_size(ptr));
314*8d67ca89SAndroid Build Coastguard Worker
315*8d67ca89SAndroid Build Coastguard Worker ptr = (char *)realloc(ptr, 100);
316*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
317*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(100U, malloc_usable_size(ptr));
318*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < 100; i++) {
319*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, ptr[i]);
320*8d67ca89SAndroid Build Coastguard Worker }
321*8d67ca89SAndroid Build Coastguard Worker
322*8d67ca89SAndroid Build Coastguard Worker ptr = (char*)realloc(ptr, 50);
323*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
324*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(50U, malloc_usable_size(ptr));
325*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < 50; i++) {
326*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, ptr[i]);
327*8d67ca89SAndroid Build Coastguard Worker }
328*8d67ca89SAndroid Build Coastguard Worker
329*8d67ca89SAndroid Build Coastguard Worker ptr = (char*)realloc(ptr, 150);
330*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
331*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(150U, malloc_usable_size(ptr));
332*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < 50; i++) {
333*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, ptr[i]);
334*8d67ca89SAndroid Build Coastguard Worker }
335*8d67ca89SAndroid Build Coastguard Worker memset(ptr, 0, 150);
336*8d67ca89SAndroid Build Coastguard Worker
337*8d67ca89SAndroid Build Coastguard Worker ptr = (char*)realloc(ptr, 425);
338*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
339*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(425U, malloc_usable_size(ptr));
340*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < 150; i++) {
341*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, ptr[i]);
342*8d67ca89SAndroid Build Coastguard Worker }
343*8d67ca89SAndroid Build Coastguard Worker free(ptr);
344*8d67ca89SAndroid Build Coastguard Worker }
345*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,realloc_overflow)346*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, realloc_overflow) {
347*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN;
348*8d67ca89SAndroid Build Coastguard Worker errno = 0;
349*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, realloc(nullptr, SIZE_MAX));
350*8d67ca89SAndroid Build Coastguard Worker ASSERT_ERRNO(ENOMEM);
351*8d67ca89SAndroid Build Coastguard Worker void* ptr = malloc(100);
352*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
353*8d67ca89SAndroid Build Coastguard Worker errno = 0;
354*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, realloc(ptr, SIZE_MAX));
355*8d67ca89SAndroid Build Coastguard Worker ASSERT_ERRNO(ENOMEM);
356*8d67ca89SAndroid Build Coastguard Worker free(ptr);
357*8d67ca89SAndroid Build Coastguard Worker }
358*8d67ca89SAndroid Build Coastguard Worker
359*8d67ca89SAndroid Build Coastguard Worker #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
360*8d67ca89SAndroid Build Coastguard Worker extern "C" void* pvalloc(size_t);
361*8d67ca89SAndroid Build Coastguard Worker extern "C" void* valloc(size_t);
362*8d67ca89SAndroid Build Coastguard Worker #endif
363*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,pvalloc_std)364*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, pvalloc_std) {
365*8d67ca89SAndroid Build Coastguard Worker #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
366*8d67ca89SAndroid Build Coastguard Worker size_t pagesize = sysconf(_SC_PAGESIZE);
367*8d67ca89SAndroid Build Coastguard Worker void* ptr = pvalloc(100);
368*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
369*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0);
370*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(pagesize, malloc_usable_size(ptr));
371*8d67ca89SAndroid Build Coastguard Worker free(ptr);
372*8d67ca89SAndroid Build Coastguard Worker #else
373*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "pvalloc not supported.";
374*8d67ca89SAndroid Build Coastguard Worker #endif
375*8d67ca89SAndroid Build Coastguard Worker }
376*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,pvalloc_overflow)377*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, pvalloc_overflow) {
378*8d67ca89SAndroid Build Coastguard Worker #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
379*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, pvalloc(SIZE_MAX));
380*8d67ca89SAndroid Build Coastguard Worker #else
381*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "pvalloc not supported.";
382*8d67ca89SAndroid Build Coastguard Worker #endif
383*8d67ca89SAndroid Build Coastguard Worker }
384*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,valloc_std)385*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, valloc_std) {
386*8d67ca89SAndroid Build Coastguard Worker #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
387*8d67ca89SAndroid Build Coastguard Worker size_t pagesize = sysconf(_SC_PAGESIZE);
388*8d67ca89SAndroid Build Coastguard Worker void* ptr = valloc(100);
389*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
390*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0);
391*8d67ca89SAndroid Build Coastguard Worker free(ptr);
392*8d67ca89SAndroid Build Coastguard Worker #else
393*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "valloc not supported.";
394*8d67ca89SAndroid Build Coastguard Worker #endif
395*8d67ca89SAndroid Build Coastguard Worker }
396*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,valloc_overflow)397*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, valloc_overflow) {
398*8d67ca89SAndroid Build Coastguard Worker #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
399*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(nullptr, valloc(SIZE_MAX));
400*8d67ca89SAndroid Build Coastguard Worker #else
401*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "valloc not supported.";
402*8d67ca89SAndroid Build Coastguard Worker #endif
403*8d67ca89SAndroid Build Coastguard Worker }
404*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,malloc_info)405*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, malloc_info) {
406*8d67ca89SAndroid Build Coastguard Worker #ifdef __BIONIC__
407*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN; // hwasan does not implement malloc_info
408*8d67ca89SAndroid Build Coastguard Worker
409*8d67ca89SAndroid Build Coastguard Worker TemporaryFile tf;
410*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(tf.fd != -1);
411*8d67ca89SAndroid Build Coastguard Worker FILE* fp = fdopen(tf.fd, "w+");
412*8d67ca89SAndroid Build Coastguard Worker tf.release();
413*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(fp != nullptr);
414*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, malloc_info(0, fp));
415*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, fclose(fp));
416*8d67ca89SAndroid Build Coastguard Worker
417*8d67ca89SAndroid Build Coastguard Worker std::string contents;
418*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFileToString(tf.path, &contents));
419*8d67ca89SAndroid Build Coastguard Worker
420*8d67ca89SAndroid Build Coastguard Worker tinyxml2::XMLDocument doc;
421*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(contents.c_str()));
422*8d67ca89SAndroid Build Coastguard Worker
423*8d67ca89SAndroid Build Coastguard Worker auto root = doc.FirstChildElement();
424*8d67ca89SAndroid Build Coastguard Worker ASSERT_NE(nullptr, root);
425*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("malloc", root->Name());
426*8d67ca89SAndroid Build Coastguard Worker std::string version(root->Attribute("version"));
427*8d67ca89SAndroid Build Coastguard Worker if (version == "jemalloc-1") {
428*8d67ca89SAndroid Build Coastguard Worker auto arena = root->FirstChildElement();
429*8d67ca89SAndroid Build Coastguard Worker for (; arena != nullptr; arena = arena->NextSiblingElement()) {
430*8d67ca89SAndroid Build Coastguard Worker int val;
431*8d67ca89SAndroid Build Coastguard Worker
432*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("heap", arena->Name());
433*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS, arena->QueryIntAttribute("nr", &val));
434*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS,
435*8d67ca89SAndroid Build Coastguard Worker arena->FirstChildElement("allocated-large")->QueryIntText(&val));
436*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS,
437*8d67ca89SAndroid Build Coastguard Worker arena->FirstChildElement("allocated-huge")->QueryIntText(&val));
438*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS,
439*8d67ca89SAndroid Build Coastguard Worker arena->FirstChildElement("allocated-bins")->QueryIntText(&val));
440*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS,
441*8d67ca89SAndroid Build Coastguard Worker arena->FirstChildElement("bins-total")->QueryIntText(&val));
442*8d67ca89SAndroid Build Coastguard Worker
443*8d67ca89SAndroid Build Coastguard Worker auto bin = arena->FirstChildElement("bin");
444*8d67ca89SAndroid Build Coastguard Worker for (; bin != nullptr; bin = bin ->NextSiblingElement()) {
445*8d67ca89SAndroid Build Coastguard Worker if (strcmp(bin->Name(), "bin") == 0) {
446*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS, bin->QueryIntAttribute("nr", &val));
447*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS,
448*8d67ca89SAndroid Build Coastguard Worker bin->FirstChildElement("allocated")->QueryIntText(&val));
449*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS,
450*8d67ca89SAndroid Build Coastguard Worker bin->FirstChildElement("nmalloc")->QueryIntText(&val));
451*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS,
452*8d67ca89SAndroid Build Coastguard Worker bin->FirstChildElement("ndalloc")->QueryIntText(&val));
453*8d67ca89SAndroid Build Coastguard Worker }
454*8d67ca89SAndroid Build Coastguard Worker }
455*8d67ca89SAndroid Build Coastguard Worker }
456*8d67ca89SAndroid Build Coastguard Worker } else if (version == "scudo-1") {
457*8d67ca89SAndroid Build Coastguard Worker auto element = root->FirstChildElement();
458*8d67ca89SAndroid Build Coastguard Worker for (; element != nullptr; element = element->NextSiblingElement()) {
459*8d67ca89SAndroid Build Coastguard Worker int val;
460*8d67ca89SAndroid Build Coastguard Worker
461*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("alloc", element->Name());
462*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS, element->QueryIntAttribute("size", &val));
463*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS, element->QueryIntAttribute("count", &val));
464*8d67ca89SAndroid Build Coastguard Worker }
465*8d67ca89SAndroid Build Coastguard Worker } else {
466*8d67ca89SAndroid Build Coastguard Worker // Do not verify output for debug malloc.
467*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(version == "debug-malloc-1") << "Unknown version: " << version;
468*8d67ca89SAndroid Build Coastguard Worker }
469*8d67ca89SAndroid Build Coastguard Worker #endif
470*8d67ca89SAndroid Build Coastguard Worker }
471*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,malloc_info_matches_mallinfo)472*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, malloc_info_matches_mallinfo) {
473*8d67ca89SAndroid Build Coastguard Worker #ifdef __BIONIC__
474*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN; // hwasan does not implement malloc_info
475*8d67ca89SAndroid Build Coastguard Worker
476*8d67ca89SAndroid Build Coastguard Worker TemporaryFile tf;
477*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(tf.fd != -1);
478*8d67ca89SAndroid Build Coastguard Worker FILE* fp = fdopen(tf.fd, "w+");
479*8d67ca89SAndroid Build Coastguard Worker tf.release();
480*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(fp != nullptr);
481*8d67ca89SAndroid Build Coastguard Worker size_t mallinfo_before_allocated_bytes = mallinfo().uordblks;
482*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, malloc_info(0, fp));
483*8d67ca89SAndroid Build Coastguard Worker size_t mallinfo_after_allocated_bytes = mallinfo().uordblks;
484*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, fclose(fp));
485*8d67ca89SAndroid Build Coastguard Worker
486*8d67ca89SAndroid Build Coastguard Worker std::string contents;
487*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFileToString(tf.path, &contents));
488*8d67ca89SAndroid Build Coastguard Worker
489*8d67ca89SAndroid Build Coastguard Worker tinyxml2::XMLDocument doc;
490*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(contents.c_str()));
491*8d67ca89SAndroid Build Coastguard Worker
492*8d67ca89SAndroid Build Coastguard Worker size_t total_allocated_bytes = 0;
493*8d67ca89SAndroid Build Coastguard Worker auto root = doc.FirstChildElement();
494*8d67ca89SAndroid Build Coastguard Worker ASSERT_NE(nullptr, root);
495*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("malloc", root->Name());
496*8d67ca89SAndroid Build Coastguard Worker std::string version(root->Attribute("version"));
497*8d67ca89SAndroid Build Coastguard Worker if (version == "jemalloc-1") {
498*8d67ca89SAndroid Build Coastguard Worker auto arena = root->FirstChildElement();
499*8d67ca89SAndroid Build Coastguard Worker for (; arena != nullptr; arena = arena->NextSiblingElement()) {
500*8d67ca89SAndroid Build Coastguard Worker int val;
501*8d67ca89SAndroid Build Coastguard Worker
502*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("heap", arena->Name());
503*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS, arena->QueryIntAttribute("nr", &val));
504*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS,
505*8d67ca89SAndroid Build Coastguard Worker arena->FirstChildElement("allocated-large")->QueryIntText(&val));
506*8d67ca89SAndroid Build Coastguard Worker total_allocated_bytes += val;
507*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS,
508*8d67ca89SAndroid Build Coastguard Worker arena->FirstChildElement("allocated-huge")->QueryIntText(&val));
509*8d67ca89SAndroid Build Coastguard Worker total_allocated_bytes += val;
510*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS,
511*8d67ca89SAndroid Build Coastguard Worker arena->FirstChildElement("allocated-bins")->QueryIntText(&val));
512*8d67ca89SAndroid Build Coastguard Worker total_allocated_bytes += val;
513*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS,
514*8d67ca89SAndroid Build Coastguard Worker arena->FirstChildElement("bins-total")->QueryIntText(&val));
515*8d67ca89SAndroid Build Coastguard Worker }
516*8d67ca89SAndroid Build Coastguard Worker // The total needs to be between the mallinfo call before and after
517*8d67ca89SAndroid Build Coastguard Worker // since malloc_info allocates some memory.
518*8d67ca89SAndroid Build Coastguard Worker EXPECT_LE(mallinfo_before_allocated_bytes, total_allocated_bytes);
519*8d67ca89SAndroid Build Coastguard Worker EXPECT_GE(mallinfo_after_allocated_bytes, total_allocated_bytes);
520*8d67ca89SAndroid Build Coastguard Worker } else if (version == "scudo-1") {
521*8d67ca89SAndroid Build Coastguard Worker auto element = root->FirstChildElement();
522*8d67ca89SAndroid Build Coastguard Worker for (; element != nullptr; element = element->NextSiblingElement()) {
523*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("alloc", element->Name());
524*8d67ca89SAndroid Build Coastguard Worker int size;
525*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS, element->QueryIntAttribute("size", &size));
526*8d67ca89SAndroid Build Coastguard Worker int count;
527*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS, element->QueryIntAttribute("count", &count));
528*8d67ca89SAndroid Build Coastguard Worker total_allocated_bytes += size * count;
529*8d67ca89SAndroid Build Coastguard Worker }
530*8d67ca89SAndroid Build Coastguard Worker // Scudo only gives the information on the primary, so simply make
531*8d67ca89SAndroid Build Coastguard Worker // sure that the value is non-zero.
532*8d67ca89SAndroid Build Coastguard Worker EXPECT_NE(0U, total_allocated_bytes);
533*8d67ca89SAndroid Build Coastguard Worker } else {
534*8d67ca89SAndroid Build Coastguard Worker // Do not verify output for debug malloc.
535*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(version == "debug-malloc-1") << "Unknown version: " << version;
536*8d67ca89SAndroid Build Coastguard Worker }
537*8d67ca89SAndroid Build Coastguard Worker #endif
538*8d67ca89SAndroid Build Coastguard Worker }
539*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,calloc_usable_size)540*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, calloc_usable_size) {
541*8d67ca89SAndroid Build Coastguard Worker for (size_t size = 1; size <= 2048; size++) {
542*8d67ca89SAndroid Build Coastguard Worker void* pointer = malloc(size);
543*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(pointer != nullptr);
544*8d67ca89SAndroid Build Coastguard Worker memset(pointer, 0xeb, malloc_usable_size(pointer));
545*8d67ca89SAndroid Build Coastguard Worker free(pointer);
546*8d67ca89SAndroid Build Coastguard Worker
547*8d67ca89SAndroid Build Coastguard Worker // We should get a previous pointer that has been set to non-zero.
548*8d67ca89SAndroid Build Coastguard Worker // If calloc does not zero out all of the data, this will fail.
549*8d67ca89SAndroid Build Coastguard Worker uint8_t* zero_mem = reinterpret_cast<uint8_t*>(calloc(1, size));
550*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(pointer != nullptr);
551*8d67ca89SAndroid Build Coastguard Worker size_t usable_size = malloc_usable_size(zero_mem);
552*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < usable_size; i++) {
553*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, zero_mem[i]) << "Failed at allocation size " << size << " at byte " << i;
554*8d67ca89SAndroid Build Coastguard Worker }
555*8d67ca89SAndroid Build Coastguard Worker free(zero_mem);
556*8d67ca89SAndroid Build Coastguard Worker }
557*8d67ca89SAndroid Build Coastguard Worker }
558*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,malloc_0)559*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, malloc_0) {
560*8d67ca89SAndroid Build Coastguard Worker void* p = malloc(0);
561*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(p != nullptr);
562*8d67ca89SAndroid Build Coastguard Worker free(p);
563*8d67ca89SAndroid Build Coastguard Worker }
564*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,calloc_0_0)565*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, calloc_0_0) {
566*8d67ca89SAndroid Build Coastguard Worker void* p = calloc(0, 0);
567*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(p != nullptr);
568*8d67ca89SAndroid Build Coastguard Worker free(p);
569*8d67ca89SAndroid Build Coastguard Worker }
570*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,calloc_0_1)571*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, calloc_0_1) {
572*8d67ca89SAndroid Build Coastguard Worker void* p = calloc(0, 1);
573*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(p != nullptr);
574*8d67ca89SAndroid Build Coastguard Worker free(p);
575*8d67ca89SAndroid Build Coastguard Worker }
576*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,calloc_1_0)577*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, calloc_1_0) {
578*8d67ca89SAndroid Build Coastguard Worker void* p = calloc(1, 0);
579*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(p != nullptr);
580*8d67ca89SAndroid Build Coastguard Worker free(p);
581*8d67ca89SAndroid Build Coastguard Worker }
582*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,realloc_nullptr_0)583*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, realloc_nullptr_0) {
584*8d67ca89SAndroid Build Coastguard Worker // realloc(nullptr, size) is actually malloc(size).
585*8d67ca89SAndroid Build Coastguard Worker void* p = realloc(nullptr, 0);
586*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(p != nullptr);
587*8d67ca89SAndroid Build Coastguard Worker free(p);
588*8d67ca89SAndroid Build Coastguard Worker }
589*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,realloc_0)590*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, realloc_0) {
591*8d67ca89SAndroid Build Coastguard Worker void* p = malloc(1024);
592*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(p != nullptr);
593*8d67ca89SAndroid Build Coastguard Worker // realloc(p, 0) is actually free(p).
594*8d67ca89SAndroid Build Coastguard Worker void* p2 = realloc(p, 0);
595*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(p2 == nullptr);
596*8d67ca89SAndroid Build Coastguard Worker }
597*8d67ca89SAndroid Build Coastguard Worker
598*8d67ca89SAndroid Build Coastguard Worker constexpr size_t MAX_LOOPS = 200;
599*8d67ca89SAndroid Build Coastguard Worker
600*8d67ca89SAndroid Build Coastguard Worker // Make sure that memory returned by malloc is aligned to allow these data types.
TEST(malloc,verify_alignment)601*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, verify_alignment) {
602*8d67ca89SAndroid Build Coastguard Worker uint32_t** values_32 = new uint32_t*[MAX_LOOPS];
603*8d67ca89SAndroid Build Coastguard Worker uint64_t** values_64 = new uint64_t*[MAX_LOOPS];
604*8d67ca89SAndroid Build Coastguard Worker long double** values_ldouble = new long double*[MAX_LOOPS];
605*8d67ca89SAndroid Build Coastguard Worker // Use filler to attempt to force the allocator to get potentially bad alignments.
606*8d67ca89SAndroid Build Coastguard Worker void** filler = new void*[MAX_LOOPS];
607*8d67ca89SAndroid Build Coastguard Worker
608*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < MAX_LOOPS; i++) {
609*8d67ca89SAndroid Build Coastguard Worker // Check uint32_t pointers.
610*8d67ca89SAndroid Build Coastguard Worker filler[i] = malloc(1);
611*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(filler[i] != nullptr);
612*8d67ca89SAndroid Build Coastguard Worker
613*8d67ca89SAndroid Build Coastguard Worker values_32[i] = reinterpret_cast<uint32_t*>(malloc(sizeof(uint32_t)));
614*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(values_32[i] != nullptr);
615*8d67ca89SAndroid Build Coastguard Worker *values_32[i] = i;
616*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(*values_32[i], i);
617*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_32[i]) & (sizeof(uint32_t) - 1));
618*8d67ca89SAndroid Build Coastguard Worker
619*8d67ca89SAndroid Build Coastguard Worker free(filler[i]);
620*8d67ca89SAndroid Build Coastguard Worker }
621*8d67ca89SAndroid Build Coastguard Worker
622*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < MAX_LOOPS; i++) {
623*8d67ca89SAndroid Build Coastguard Worker // Check uint64_t pointers.
624*8d67ca89SAndroid Build Coastguard Worker filler[i] = malloc(1);
625*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(filler[i] != nullptr);
626*8d67ca89SAndroid Build Coastguard Worker
627*8d67ca89SAndroid Build Coastguard Worker values_64[i] = reinterpret_cast<uint64_t*>(malloc(sizeof(uint64_t)));
628*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(values_64[i] != nullptr);
629*8d67ca89SAndroid Build Coastguard Worker *values_64[i] = 0x1000 + i;
630*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(*values_64[i], 0x1000 + i);
631*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_64[i]) & (sizeof(uint64_t) - 1));
632*8d67ca89SAndroid Build Coastguard Worker
633*8d67ca89SAndroid Build Coastguard Worker free(filler[i]);
634*8d67ca89SAndroid Build Coastguard Worker }
635*8d67ca89SAndroid Build Coastguard Worker
636*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < MAX_LOOPS; i++) {
637*8d67ca89SAndroid Build Coastguard Worker // Check long double pointers.
638*8d67ca89SAndroid Build Coastguard Worker filler[i] = malloc(1);
639*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(filler[i] != nullptr);
640*8d67ca89SAndroid Build Coastguard Worker
641*8d67ca89SAndroid Build Coastguard Worker values_ldouble[i] = reinterpret_cast<long double*>(malloc(sizeof(long double)));
642*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(values_ldouble[i] != nullptr);
643*8d67ca89SAndroid Build Coastguard Worker *values_ldouble[i] = 5.5 + i;
644*8d67ca89SAndroid Build Coastguard Worker ASSERT_DOUBLE_EQ(*values_ldouble[i], 5.5 + i);
645*8d67ca89SAndroid Build Coastguard Worker // 32 bit glibc has a long double size of 12 bytes, so hardcode the
646*8d67ca89SAndroid Build Coastguard Worker // required alignment to 0x7.
647*8d67ca89SAndroid Build Coastguard Worker #if !defined(__BIONIC__) && !defined(__LP64__)
648*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_ldouble[i]) & 0x7);
649*8d67ca89SAndroid Build Coastguard Worker #else
650*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(values_ldouble[i]) & (sizeof(long double) - 1));
651*8d67ca89SAndroid Build Coastguard Worker #endif
652*8d67ca89SAndroid Build Coastguard Worker
653*8d67ca89SAndroid Build Coastguard Worker free(filler[i]);
654*8d67ca89SAndroid Build Coastguard Worker }
655*8d67ca89SAndroid Build Coastguard Worker
656*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < MAX_LOOPS; i++) {
657*8d67ca89SAndroid Build Coastguard Worker free(values_32[i]);
658*8d67ca89SAndroid Build Coastguard Worker free(values_64[i]);
659*8d67ca89SAndroid Build Coastguard Worker free(values_ldouble[i]);
660*8d67ca89SAndroid Build Coastguard Worker }
661*8d67ca89SAndroid Build Coastguard Worker
662*8d67ca89SAndroid Build Coastguard Worker delete[] filler;
663*8d67ca89SAndroid Build Coastguard Worker delete[] values_32;
664*8d67ca89SAndroid Build Coastguard Worker delete[] values_64;
665*8d67ca89SAndroid Build Coastguard Worker delete[] values_ldouble;
666*8d67ca89SAndroid Build Coastguard Worker }
667*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,mallopt_smoke)668*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, mallopt_smoke) {
669*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
670*8d67ca89SAndroid Build Coastguard Worker errno = 0;
671*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, mallopt(-1000, 1));
672*8d67ca89SAndroid Build Coastguard Worker // mallopt doesn't set errno.
673*8d67ca89SAndroid Build Coastguard Worker ASSERT_ERRNO(0);
674*8d67ca89SAndroid Build Coastguard Worker #else
675*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
676*8d67ca89SAndroid Build Coastguard Worker #endif
677*8d67ca89SAndroid Build Coastguard Worker }
678*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,mallopt_decay)679*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, mallopt_decay) {
680*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
681*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
682*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(1, mallopt(M_DECAY_TIME, -1));
683*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(1, mallopt(M_DECAY_TIME, 1));
684*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(1, mallopt(M_DECAY_TIME, 0));
685*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(1, mallopt(M_DECAY_TIME, 1));
686*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(1, mallopt(M_DECAY_TIME, 0));
687*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(1, mallopt(M_DECAY_TIME, -1));
688*8d67ca89SAndroid Build Coastguard Worker #else
689*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
690*8d67ca89SAndroid Build Coastguard Worker #endif
691*8d67ca89SAndroid Build Coastguard Worker }
692*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,mallopt_purge)693*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, mallopt_purge) {
694*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
695*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
696*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(1, mallopt(M_PURGE, 0));
697*8d67ca89SAndroid Build Coastguard Worker #else
698*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
699*8d67ca89SAndroid Build Coastguard Worker #endif
700*8d67ca89SAndroid Build Coastguard Worker }
701*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,mallopt_purge_all)702*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, mallopt_purge_all) {
703*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
704*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
705*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(1, mallopt(M_PURGE_ALL, 0));
706*8d67ca89SAndroid Build Coastguard Worker #else
707*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
708*8d67ca89SAndroid Build Coastguard Worker #endif
709*8d67ca89SAndroid Build Coastguard Worker }
710*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,mallopt_log_stats)711*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, mallopt_log_stats) {
712*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
713*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
714*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(1, mallopt(M_LOG_STATS, 0));
715*8d67ca89SAndroid Build Coastguard Worker #else
716*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
717*8d67ca89SAndroid Build Coastguard Worker #endif
718*8d67ca89SAndroid Build Coastguard Worker }
719*8d67ca89SAndroid Build Coastguard Worker
720*8d67ca89SAndroid Build Coastguard Worker // Verify that all of the mallopt values are unique.
TEST(malloc,mallopt_unique_params)721*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, mallopt_unique_params) {
722*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
723*8d67ca89SAndroid Build Coastguard Worker std::vector<std::pair<int, std::string>> params{
724*8d67ca89SAndroid Build Coastguard Worker std::make_pair(M_DECAY_TIME, "M_DECAY_TIME"),
725*8d67ca89SAndroid Build Coastguard Worker std::make_pair(M_PURGE, "M_PURGE"),
726*8d67ca89SAndroid Build Coastguard Worker std::make_pair(M_PURGE_ALL, "M_PURGE_ALL"),
727*8d67ca89SAndroid Build Coastguard Worker std::make_pair(M_MEMTAG_TUNING, "M_MEMTAG_TUNING"),
728*8d67ca89SAndroid Build Coastguard Worker std::make_pair(M_THREAD_DISABLE_MEM_INIT, "M_THREAD_DISABLE_MEM_INIT"),
729*8d67ca89SAndroid Build Coastguard Worker std::make_pair(M_CACHE_COUNT_MAX, "M_CACHE_COUNT_MAX"),
730*8d67ca89SAndroid Build Coastguard Worker std::make_pair(M_CACHE_SIZE_MAX, "M_CACHE_SIZE_MAX"),
731*8d67ca89SAndroid Build Coastguard Worker std::make_pair(M_TSDS_COUNT_MAX, "M_TSDS_COUNT_MAX"),
732*8d67ca89SAndroid Build Coastguard Worker std::make_pair(M_BIONIC_ZERO_INIT, "M_BIONIC_ZERO_INIT"),
733*8d67ca89SAndroid Build Coastguard Worker std::make_pair(M_BIONIC_SET_HEAP_TAGGING_LEVEL, "M_BIONIC_SET_HEAP_TAGGING_LEVEL"),
734*8d67ca89SAndroid Build Coastguard Worker std::make_pair(M_LOG_STATS, "M_LOG_STATS"),
735*8d67ca89SAndroid Build Coastguard Worker };
736*8d67ca89SAndroid Build Coastguard Worker
737*8d67ca89SAndroid Build Coastguard Worker std::unordered_map<int, std::string> all_params;
738*8d67ca89SAndroid Build Coastguard Worker for (const auto& param : params) {
739*8d67ca89SAndroid Build Coastguard Worker EXPECT_TRUE(all_params.count(param.first) == 0)
740*8d67ca89SAndroid Build Coastguard Worker << "mallopt params " << all_params[param.first] << " and " << param.second
741*8d67ca89SAndroid Build Coastguard Worker << " have the same value " << param.first;
742*8d67ca89SAndroid Build Coastguard Worker all_params.insert(param);
743*8d67ca89SAndroid Build Coastguard Worker }
744*8d67ca89SAndroid Build Coastguard Worker #else
745*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
746*8d67ca89SAndroid Build Coastguard Worker #endif
747*8d67ca89SAndroid Build Coastguard Worker }
748*8d67ca89SAndroid Build Coastguard Worker
749*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
GetAllocatorVersion(bool * allocator_scudo)750*8d67ca89SAndroid Build Coastguard Worker static void GetAllocatorVersion(bool* allocator_scudo) {
751*8d67ca89SAndroid Build Coastguard Worker TemporaryFile tf;
752*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(tf.fd != -1);
753*8d67ca89SAndroid Build Coastguard Worker FILE* fp = fdopen(tf.fd, "w+");
754*8d67ca89SAndroid Build Coastguard Worker tf.release();
755*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(fp != nullptr);
756*8d67ca89SAndroid Build Coastguard Worker if (malloc_info(0, fp) != 0) {
757*8d67ca89SAndroid Build Coastguard Worker *allocator_scudo = false;
758*8d67ca89SAndroid Build Coastguard Worker return;
759*8d67ca89SAndroid Build Coastguard Worker }
760*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, fclose(fp));
761*8d67ca89SAndroid Build Coastguard Worker
762*8d67ca89SAndroid Build Coastguard Worker std::string contents;
763*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFileToString(tf.path, &contents));
764*8d67ca89SAndroid Build Coastguard Worker
765*8d67ca89SAndroid Build Coastguard Worker tinyxml2::XMLDocument doc;
766*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(contents.c_str()));
767*8d67ca89SAndroid Build Coastguard Worker
768*8d67ca89SAndroid Build Coastguard Worker auto root = doc.FirstChildElement();
769*8d67ca89SAndroid Build Coastguard Worker ASSERT_NE(nullptr, root);
770*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("malloc", root->Name());
771*8d67ca89SAndroid Build Coastguard Worker std::string version(root->Attribute("version"));
772*8d67ca89SAndroid Build Coastguard Worker *allocator_scudo = (version == "scudo-1");
773*8d67ca89SAndroid Build Coastguard Worker }
774*8d67ca89SAndroid Build Coastguard Worker #endif
775*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,mallopt_scudo_only_options)776*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, mallopt_scudo_only_options) {
777*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
778*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
779*8d67ca89SAndroid Build Coastguard Worker bool allocator_scudo;
780*8d67ca89SAndroid Build Coastguard Worker GetAllocatorVersion(&allocator_scudo);
781*8d67ca89SAndroid Build Coastguard Worker if (!allocator_scudo) {
782*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "scudo allocator only test";
783*8d67ca89SAndroid Build Coastguard Worker }
784*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(1, mallopt(M_CACHE_COUNT_MAX, 100));
785*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(1, mallopt(M_CACHE_SIZE_MAX, 1024 * 1024 * 2));
786*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(1, mallopt(M_TSDS_COUNT_MAX, 8));
787*8d67ca89SAndroid Build Coastguard Worker #else
788*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
789*8d67ca89SAndroid Build Coastguard Worker #endif
790*8d67ca89SAndroid Build Coastguard Worker }
791*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,reallocarray_overflow)792*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, reallocarray_overflow) {
793*8d67ca89SAndroid Build Coastguard Worker #if HAVE_REALLOCARRAY
794*8d67ca89SAndroid Build Coastguard Worker // Values that cause overflow to a result small enough (8 on LP64) that malloc would "succeed".
795*8d67ca89SAndroid Build Coastguard Worker size_t a = static_cast<size_t>(INTPTR_MIN + 4);
796*8d67ca89SAndroid Build Coastguard Worker size_t b = 2;
797*8d67ca89SAndroid Build Coastguard Worker
798*8d67ca89SAndroid Build Coastguard Worker errno = 0;
799*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(reallocarray(nullptr, a, b) == nullptr);
800*8d67ca89SAndroid Build Coastguard Worker ASSERT_ERRNO(ENOMEM);
801*8d67ca89SAndroid Build Coastguard Worker
802*8d67ca89SAndroid Build Coastguard Worker errno = 0;
803*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(reallocarray(nullptr, b, a) == nullptr);
804*8d67ca89SAndroid Build Coastguard Worker ASSERT_ERRNO(ENOMEM);
805*8d67ca89SAndroid Build Coastguard Worker #else
806*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "reallocarray not available";
807*8d67ca89SAndroid Build Coastguard Worker #endif
808*8d67ca89SAndroid Build Coastguard Worker }
809*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,reallocarray)810*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, reallocarray) {
811*8d67ca89SAndroid Build Coastguard Worker #if HAVE_REALLOCARRAY
812*8d67ca89SAndroid Build Coastguard Worker void* p = reallocarray(nullptr, 2, 32);
813*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(p != nullptr);
814*8d67ca89SAndroid Build Coastguard Worker ASSERT_GE(malloc_usable_size(p), 64U);
815*8d67ca89SAndroid Build Coastguard Worker #else
816*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "reallocarray not available";
817*8d67ca89SAndroid Build Coastguard Worker #endif
818*8d67ca89SAndroid Build Coastguard Worker }
819*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,mallinfo)820*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, mallinfo) {
821*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__) || defined(ANDROID_HOST_MUSL)
822*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN << "hwasan does not implement mallinfo";
823*8d67ca89SAndroid Build Coastguard Worker static size_t sizes[] = {
824*8d67ca89SAndroid Build Coastguard Worker 8, 32, 128, 4096, 32768, 131072, 1024000, 10240000, 20480000, 300000000
825*8d67ca89SAndroid Build Coastguard Worker };
826*8d67ca89SAndroid Build Coastguard Worker
827*8d67ca89SAndroid Build Coastguard Worker static constexpr size_t kMaxAllocs = 50;
828*8d67ca89SAndroid Build Coastguard Worker
829*8d67ca89SAndroid Build Coastguard Worker for (size_t size : sizes) {
830*8d67ca89SAndroid Build Coastguard Worker // If some of these allocations are stuck in a thread cache, then keep
831*8d67ca89SAndroid Build Coastguard Worker // looping until we make an allocation that changes the total size of the
832*8d67ca89SAndroid Build Coastguard Worker // memory allocated.
833*8d67ca89SAndroid Build Coastguard Worker // jemalloc implementations counts the thread cache allocations against
834*8d67ca89SAndroid Build Coastguard Worker // total memory allocated.
835*8d67ca89SAndroid Build Coastguard Worker void* ptrs[kMaxAllocs] = {};
836*8d67ca89SAndroid Build Coastguard Worker bool pass = false;
837*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < kMaxAllocs; i++) {
838*8d67ca89SAndroid Build Coastguard Worker size_t allocated = mallinfo().uordblks;
839*8d67ca89SAndroid Build Coastguard Worker ptrs[i] = malloc(size);
840*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptrs[i] != nullptr);
841*8d67ca89SAndroid Build Coastguard Worker size_t new_allocated = mallinfo().uordblks;
842*8d67ca89SAndroid Build Coastguard Worker if (allocated != new_allocated) {
843*8d67ca89SAndroid Build Coastguard Worker size_t usable_size = malloc_usable_size(ptrs[i]);
844*8d67ca89SAndroid Build Coastguard Worker // Only check if the total got bigger by at least allocation size.
845*8d67ca89SAndroid Build Coastguard Worker // Sometimes the mallinfo numbers can go backwards due to compaction
846*8d67ca89SAndroid Build Coastguard Worker // and/or freeing of cached data.
847*8d67ca89SAndroid Build Coastguard Worker if (new_allocated >= allocated + usable_size) {
848*8d67ca89SAndroid Build Coastguard Worker pass = true;
849*8d67ca89SAndroid Build Coastguard Worker break;
850*8d67ca89SAndroid Build Coastguard Worker }
851*8d67ca89SAndroid Build Coastguard Worker }
852*8d67ca89SAndroid Build Coastguard Worker }
853*8d67ca89SAndroid Build Coastguard Worker for (void* ptr : ptrs) {
854*8d67ca89SAndroid Build Coastguard Worker free(ptr);
855*8d67ca89SAndroid Build Coastguard Worker }
856*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(pass)
857*8d67ca89SAndroid Build Coastguard Worker << "For size " << size << " allocated bytes did not increase after "
858*8d67ca89SAndroid Build Coastguard Worker << kMaxAllocs << " allocations.";
859*8d67ca89SAndroid Build Coastguard Worker }
860*8d67ca89SAndroid Build Coastguard Worker #else
861*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "glibc is broken";
862*8d67ca89SAndroid Build Coastguard Worker #endif
863*8d67ca89SAndroid Build Coastguard Worker }
864*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,mallinfo2)865*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, mallinfo2) {
866*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__) || defined(ANDROID_HOST_MUSL)
867*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN << "hwasan does not implement mallinfo2";
868*8d67ca89SAndroid Build Coastguard Worker static size_t sizes[] = {8, 32, 128, 4096, 32768, 131072, 1024000, 10240000, 20480000, 300000000};
869*8d67ca89SAndroid Build Coastguard Worker
870*8d67ca89SAndroid Build Coastguard Worker static constexpr size_t kMaxAllocs = 50;
871*8d67ca89SAndroid Build Coastguard Worker
872*8d67ca89SAndroid Build Coastguard Worker for (size_t size : sizes) {
873*8d67ca89SAndroid Build Coastguard Worker // If some of these allocations are stuck in a thread cache, then keep
874*8d67ca89SAndroid Build Coastguard Worker // looping until we make an allocation that changes the total size of the
875*8d67ca89SAndroid Build Coastguard Worker // memory allocated.
876*8d67ca89SAndroid Build Coastguard Worker // jemalloc implementations counts the thread cache allocations against
877*8d67ca89SAndroid Build Coastguard Worker // total memory allocated.
878*8d67ca89SAndroid Build Coastguard Worker void* ptrs[kMaxAllocs] = {};
879*8d67ca89SAndroid Build Coastguard Worker bool pass = false;
880*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < kMaxAllocs; i++) {
881*8d67ca89SAndroid Build Coastguard Worker struct mallinfo info = mallinfo();
882*8d67ca89SAndroid Build Coastguard Worker struct mallinfo2 info2 = mallinfo2();
883*8d67ca89SAndroid Build Coastguard Worker // Verify that mallinfo and mallinfo2 are exactly the same.
884*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.arena), info2.arena);
885*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.ordblks), info2.ordblks);
886*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.smblks), info2.smblks);
887*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.hblks), info2.hblks);
888*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.hblkhd), info2.hblkhd);
889*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.usmblks), info2.usmblks);
890*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.fsmblks), info2.fsmblks);
891*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.uordblks), info2.uordblks);
892*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.fordblks), info2.fordblks);
893*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.keepcost), info2.keepcost);
894*8d67ca89SAndroid Build Coastguard Worker
895*8d67ca89SAndroid Build Coastguard Worker size_t allocated = info2.uordblks;
896*8d67ca89SAndroid Build Coastguard Worker ptrs[i] = malloc(size);
897*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptrs[i] != nullptr);
898*8d67ca89SAndroid Build Coastguard Worker
899*8d67ca89SAndroid Build Coastguard Worker info = mallinfo();
900*8d67ca89SAndroid Build Coastguard Worker info2 = mallinfo2();
901*8d67ca89SAndroid Build Coastguard Worker // Verify that mallinfo and mallinfo2 are exactly the same.
902*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.arena), info2.arena);
903*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.ordblks), info2.ordblks);
904*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.smblks), info2.smblks);
905*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.hblks), info2.hblks);
906*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.hblkhd), info2.hblkhd);
907*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.usmblks), info2.usmblks);
908*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.fsmblks), info2.fsmblks);
909*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.uordblks), info2.uordblks);
910*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.fordblks), info2.fordblks);
911*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(info.keepcost), info2.keepcost);
912*8d67ca89SAndroid Build Coastguard Worker
913*8d67ca89SAndroid Build Coastguard Worker size_t new_allocated = info2.uordblks;
914*8d67ca89SAndroid Build Coastguard Worker if (allocated != new_allocated) {
915*8d67ca89SAndroid Build Coastguard Worker size_t usable_size = malloc_usable_size(ptrs[i]);
916*8d67ca89SAndroid Build Coastguard Worker // Only check if the total got bigger by at least allocation size.
917*8d67ca89SAndroid Build Coastguard Worker // Sometimes the mallinfo2 numbers can go backwards due to compaction
918*8d67ca89SAndroid Build Coastguard Worker // and/or freeing of cached data.
919*8d67ca89SAndroid Build Coastguard Worker if (new_allocated >= allocated + usable_size) {
920*8d67ca89SAndroid Build Coastguard Worker pass = true;
921*8d67ca89SAndroid Build Coastguard Worker break;
922*8d67ca89SAndroid Build Coastguard Worker }
923*8d67ca89SAndroid Build Coastguard Worker }
924*8d67ca89SAndroid Build Coastguard Worker }
925*8d67ca89SAndroid Build Coastguard Worker for (void* ptr : ptrs) {
926*8d67ca89SAndroid Build Coastguard Worker free(ptr);
927*8d67ca89SAndroid Build Coastguard Worker }
928*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(pass) << "For size " << size << " allocated bytes did not increase after "
929*8d67ca89SAndroid Build Coastguard Worker << kMaxAllocs << " allocations.";
930*8d67ca89SAndroid Build Coastguard Worker }
931*8d67ca89SAndroid Build Coastguard Worker #else
932*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "glibc is broken";
933*8d67ca89SAndroid Build Coastguard Worker #endif
934*8d67ca89SAndroid Build Coastguard Worker }
935*8d67ca89SAndroid Build Coastguard Worker
936*8d67ca89SAndroid Build Coastguard Worker template <typename Type>
VerifyAlignment(Type * floating)937*8d67ca89SAndroid Build Coastguard Worker void __attribute__((optnone)) VerifyAlignment(Type* floating) {
938*8d67ca89SAndroid Build Coastguard Worker size_t expected_alignment = alignof(Type);
939*8d67ca89SAndroid Build Coastguard Worker if (expected_alignment != 0) {
940*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0U, (expected_alignment - 1) & reinterpret_cast<uintptr_t>(floating))
941*8d67ca89SAndroid Build Coastguard Worker << "Expected alignment " << expected_alignment << " ptr value "
942*8d67ca89SAndroid Build Coastguard Worker << static_cast<void*>(floating);
943*8d67ca89SAndroid Build Coastguard Worker }
944*8d67ca89SAndroid Build Coastguard Worker }
945*8d67ca89SAndroid Build Coastguard Worker
946*8d67ca89SAndroid Build Coastguard Worker template <typename Type>
TestAllocateType()947*8d67ca89SAndroid Build Coastguard Worker void __attribute__((optnone)) TestAllocateType() {
948*8d67ca89SAndroid Build Coastguard Worker // The number of allocations to do in a row. This is to attempt to
949*8d67ca89SAndroid Build Coastguard Worker // expose the worst case alignment for native allocators that use
950*8d67ca89SAndroid Build Coastguard Worker // bins.
951*8d67ca89SAndroid Build Coastguard Worker static constexpr size_t kMaxConsecutiveAllocs = 100;
952*8d67ca89SAndroid Build Coastguard Worker
953*8d67ca89SAndroid Build Coastguard Worker // Verify using new directly.
954*8d67ca89SAndroid Build Coastguard Worker Type* types[kMaxConsecutiveAllocs];
955*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < kMaxConsecutiveAllocs; i++) {
956*8d67ca89SAndroid Build Coastguard Worker types[i] = new Type;
957*8d67ca89SAndroid Build Coastguard Worker VerifyAlignment(types[i]);
958*8d67ca89SAndroid Build Coastguard Worker if (::testing::Test::HasFatalFailure()) {
959*8d67ca89SAndroid Build Coastguard Worker return;
960*8d67ca89SAndroid Build Coastguard Worker }
961*8d67ca89SAndroid Build Coastguard Worker }
962*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < kMaxConsecutiveAllocs; i++) {
963*8d67ca89SAndroid Build Coastguard Worker delete types[i];
964*8d67ca89SAndroid Build Coastguard Worker }
965*8d67ca89SAndroid Build Coastguard Worker
966*8d67ca89SAndroid Build Coastguard Worker // Verify using malloc.
967*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < kMaxConsecutiveAllocs; i++) {
968*8d67ca89SAndroid Build Coastguard Worker types[i] = reinterpret_cast<Type*>(malloc(sizeof(Type)));
969*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(types[i] != nullptr);
970*8d67ca89SAndroid Build Coastguard Worker VerifyAlignment(types[i]);
971*8d67ca89SAndroid Build Coastguard Worker if (::testing::Test::HasFatalFailure()) {
972*8d67ca89SAndroid Build Coastguard Worker return;
973*8d67ca89SAndroid Build Coastguard Worker }
974*8d67ca89SAndroid Build Coastguard Worker }
975*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < kMaxConsecutiveAllocs; i++) {
976*8d67ca89SAndroid Build Coastguard Worker free(types[i]);
977*8d67ca89SAndroid Build Coastguard Worker }
978*8d67ca89SAndroid Build Coastguard Worker
979*8d67ca89SAndroid Build Coastguard Worker // Verify using a vector.
980*8d67ca89SAndroid Build Coastguard Worker std::vector<Type> type_vector(kMaxConsecutiveAllocs);
981*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < type_vector.size(); i++) {
982*8d67ca89SAndroid Build Coastguard Worker VerifyAlignment(&type_vector[i]);
983*8d67ca89SAndroid Build Coastguard Worker if (::testing::Test::HasFatalFailure()) {
984*8d67ca89SAndroid Build Coastguard Worker return;
985*8d67ca89SAndroid Build Coastguard Worker }
986*8d67ca89SAndroid Build Coastguard Worker }
987*8d67ca89SAndroid Build Coastguard Worker }
988*8d67ca89SAndroid Build Coastguard Worker
989*8d67ca89SAndroid Build Coastguard Worker #if defined(__ANDROID__)
AndroidVerifyAlignment(size_t alloc_size,size_t aligned_bytes)990*8d67ca89SAndroid Build Coastguard Worker static void __attribute__((optnone)) AndroidVerifyAlignment(size_t alloc_size, size_t aligned_bytes) {
991*8d67ca89SAndroid Build Coastguard Worker void* ptrs[100];
992*8d67ca89SAndroid Build Coastguard Worker uintptr_t mask = aligned_bytes - 1;
993*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < sizeof(ptrs) / sizeof(void*); i++) {
994*8d67ca89SAndroid Build Coastguard Worker ptrs[i] = malloc(alloc_size);
995*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptrs[i] != nullptr);
996*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptrs[i]) & mask)
997*8d67ca89SAndroid Build Coastguard Worker << "Expected at least " << aligned_bytes << " byte alignment: size "
998*8d67ca89SAndroid Build Coastguard Worker << alloc_size << " actual ptr " << ptrs[i];
999*8d67ca89SAndroid Build Coastguard Worker }
1000*8d67ca89SAndroid Build Coastguard Worker }
1001*8d67ca89SAndroid Build Coastguard Worker #endif
1002*8d67ca89SAndroid Build Coastguard Worker
AlignCheck()1003*8d67ca89SAndroid Build Coastguard Worker void AlignCheck() {
1004*8d67ca89SAndroid Build Coastguard Worker // See http://www.open-std.org/jtc1/sc22/wg14/www/docs/summary.htm#dr_445
1005*8d67ca89SAndroid Build Coastguard Worker // for a discussion of type alignment.
1006*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(TestAllocateType<float>());
1007*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(TestAllocateType<double>());
1008*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(TestAllocateType<long double>());
1009*8d67ca89SAndroid Build Coastguard Worker
1010*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(TestAllocateType<char>());
1011*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(TestAllocateType<char16_t>());
1012*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(TestAllocateType<char32_t>());
1013*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(TestAllocateType<wchar_t>());
1014*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(TestAllocateType<signed char>());
1015*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(TestAllocateType<short int>());
1016*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(TestAllocateType<int>());
1017*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(TestAllocateType<long int>());
1018*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(TestAllocateType<long long int>());
1019*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(TestAllocateType<unsigned char>());
1020*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(TestAllocateType<unsigned short int>());
1021*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(TestAllocateType<unsigned int>());
1022*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(TestAllocateType<unsigned long int>());
1023*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(TestAllocateType<unsigned long long int>());
1024*8d67ca89SAndroid Build Coastguard Worker
1025*8d67ca89SAndroid Build Coastguard Worker #if defined(__ANDROID__)
1026*8d67ca89SAndroid Build Coastguard Worker // On Android, there is a lot of code that expects certain alignments:
1027*8d67ca89SAndroid Build Coastguard Worker // 1. Allocations of a size that rounds up to a multiple of 16 bytes
1028*8d67ca89SAndroid Build Coastguard Worker // must have at least 16 byte alignment.
1029*8d67ca89SAndroid Build Coastguard Worker // 2. Allocations of a size that rounds up to a multiple of 8 bytes and
1030*8d67ca89SAndroid Build Coastguard Worker // not 16 bytes, are only required to have at least 8 byte alignment.
1031*8d67ca89SAndroid Build Coastguard Worker // In addition, on Android clang has been configured for 64 bit such that:
1032*8d67ca89SAndroid Build Coastguard Worker // 3. Allocations <= 8 bytes must be aligned to at least 8 bytes.
1033*8d67ca89SAndroid Build Coastguard Worker // 4. Allocations > 8 bytes must be aligned to at least 16 bytes.
1034*8d67ca89SAndroid Build Coastguard Worker // For 32 bit environments, only the first two requirements must be met.
1035*8d67ca89SAndroid Build Coastguard Worker
1036*8d67ca89SAndroid Build Coastguard Worker // See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2293.htm for
1037*8d67ca89SAndroid Build Coastguard Worker // a discussion of this alignment mess. The code below is enforcing
1038*8d67ca89SAndroid Build Coastguard Worker // strong-alignment, since who knows what code depends on this behavior now.
1039*8d67ca89SAndroid Build Coastguard Worker // As mentioned before, for 64 bit this will enforce the higher
1040*8d67ca89SAndroid Build Coastguard Worker // requirement since clang expects this behavior on Android now.
1041*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 1; i <= 128; i++) {
1042*8d67ca89SAndroid Build Coastguard Worker #if defined(__LP64__)
1043*8d67ca89SAndroid Build Coastguard Worker if (i <= 8) {
1044*8d67ca89SAndroid Build Coastguard Worker AndroidVerifyAlignment(i, 8);
1045*8d67ca89SAndroid Build Coastguard Worker } else {
1046*8d67ca89SAndroid Build Coastguard Worker AndroidVerifyAlignment(i, 16);
1047*8d67ca89SAndroid Build Coastguard Worker }
1048*8d67ca89SAndroid Build Coastguard Worker #else
1049*8d67ca89SAndroid Build Coastguard Worker size_t rounded = (i + 7) & ~7;
1050*8d67ca89SAndroid Build Coastguard Worker if ((rounded % 16) == 0) {
1051*8d67ca89SAndroid Build Coastguard Worker AndroidVerifyAlignment(i, 16);
1052*8d67ca89SAndroid Build Coastguard Worker } else {
1053*8d67ca89SAndroid Build Coastguard Worker AndroidVerifyAlignment(i, 8);
1054*8d67ca89SAndroid Build Coastguard Worker }
1055*8d67ca89SAndroid Build Coastguard Worker #endif
1056*8d67ca89SAndroid Build Coastguard Worker if (::testing::Test::HasFatalFailure()) {
1057*8d67ca89SAndroid Build Coastguard Worker return;
1058*8d67ca89SAndroid Build Coastguard Worker }
1059*8d67ca89SAndroid Build Coastguard Worker }
1060*8d67ca89SAndroid Build Coastguard Worker #endif
1061*8d67ca89SAndroid Build Coastguard Worker }
1062*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,align_check)1063*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, align_check) {
1064*8d67ca89SAndroid Build Coastguard Worker AlignCheck();
1065*8d67ca89SAndroid Build Coastguard Worker }
1066*8d67ca89SAndroid Build Coastguard Worker
1067*8d67ca89SAndroid Build Coastguard Worker // Jemalloc doesn't pass this test right now, so leave it as disabled.
TEST(malloc,DISABLED_alloc_after_fork)1068*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, DISABLED_alloc_after_fork) {
1069*8d67ca89SAndroid Build Coastguard Worker // Both of these need to be a power of 2.
1070*8d67ca89SAndroid Build Coastguard Worker static constexpr size_t kMinAllocationSize = 8;
1071*8d67ca89SAndroid Build Coastguard Worker static constexpr size_t kMaxAllocationSize = 2097152;
1072*8d67ca89SAndroid Build Coastguard Worker
1073*8d67ca89SAndroid Build Coastguard Worker static constexpr size_t kNumAllocatingThreads = 5;
1074*8d67ca89SAndroid Build Coastguard Worker static constexpr size_t kNumForkLoops = 100;
1075*8d67ca89SAndroid Build Coastguard Worker
1076*8d67ca89SAndroid Build Coastguard Worker std::atomic_bool stop;
1077*8d67ca89SAndroid Build Coastguard Worker
1078*8d67ca89SAndroid Build Coastguard Worker // Create threads that simply allocate and free different sizes.
1079*8d67ca89SAndroid Build Coastguard Worker std::vector<std::thread*> threads;
1080*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < kNumAllocatingThreads; i++) {
1081*8d67ca89SAndroid Build Coastguard Worker std::thread* t = new std::thread([&stop] {
1082*8d67ca89SAndroid Build Coastguard Worker while (!stop) {
1083*8d67ca89SAndroid Build Coastguard Worker for (size_t size = kMinAllocationSize; size <= kMaxAllocationSize; size <<= 1) {
1084*8d67ca89SAndroid Build Coastguard Worker void* ptr;
1085*8d67ca89SAndroid Build Coastguard Worker DoNotOptimize(ptr = malloc(size));
1086*8d67ca89SAndroid Build Coastguard Worker free(ptr);
1087*8d67ca89SAndroid Build Coastguard Worker }
1088*8d67ca89SAndroid Build Coastguard Worker }
1089*8d67ca89SAndroid Build Coastguard Worker });
1090*8d67ca89SAndroid Build Coastguard Worker threads.push_back(t);
1091*8d67ca89SAndroid Build Coastguard Worker }
1092*8d67ca89SAndroid Build Coastguard Worker
1093*8d67ca89SAndroid Build Coastguard Worker // Create a thread to fork and allocate.
1094*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < kNumForkLoops; i++) {
1095*8d67ca89SAndroid Build Coastguard Worker pid_t pid;
1096*8d67ca89SAndroid Build Coastguard Worker if ((pid = fork()) == 0) {
1097*8d67ca89SAndroid Build Coastguard Worker for (size_t size = kMinAllocationSize; size <= kMaxAllocationSize; size <<= 1) {
1098*8d67ca89SAndroid Build Coastguard Worker void* ptr;
1099*8d67ca89SAndroid Build Coastguard Worker DoNotOptimize(ptr = malloc(size));
1100*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptr != nullptr);
1101*8d67ca89SAndroid Build Coastguard Worker // Make sure we can touch all of the allocation.
1102*8d67ca89SAndroid Build Coastguard Worker memset(ptr, 0x1, size);
1103*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(size, malloc_usable_size(ptr));
1104*8d67ca89SAndroid Build Coastguard Worker free(ptr);
1105*8d67ca89SAndroid Build Coastguard Worker }
1106*8d67ca89SAndroid Build Coastguard Worker _exit(10);
1107*8d67ca89SAndroid Build Coastguard Worker }
1108*8d67ca89SAndroid Build Coastguard Worker ASSERT_NE(-1, pid);
1109*8d67ca89SAndroid Build Coastguard Worker AssertChildExited(pid, 10);
1110*8d67ca89SAndroid Build Coastguard Worker }
1111*8d67ca89SAndroid Build Coastguard Worker
1112*8d67ca89SAndroid Build Coastguard Worker stop = true;
1113*8d67ca89SAndroid Build Coastguard Worker for (auto thread : threads) {
1114*8d67ca89SAndroid Build Coastguard Worker thread->join();
1115*8d67ca89SAndroid Build Coastguard Worker delete thread;
1116*8d67ca89SAndroid Build Coastguard Worker }
1117*8d67ca89SAndroid Build Coastguard Worker }
1118*8d67ca89SAndroid Build Coastguard Worker
TEST(android_mallopt,error_on_unexpected_option)1119*8d67ca89SAndroid Build Coastguard Worker TEST(android_mallopt, error_on_unexpected_option) {
1120*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1121*8d67ca89SAndroid Build Coastguard Worker const int unrecognized_option = -1;
1122*8d67ca89SAndroid Build Coastguard Worker errno = 0;
1123*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(false, android_mallopt(unrecognized_option, nullptr, 0));
1124*8d67ca89SAndroid Build Coastguard Worker EXPECT_ERRNO(ENOTSUP);
1125*8d67ca89SAndroid Build Coastguard Worker #else
1126*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
1127*8d67ca89SAndroid Build Coastguard Worker #endif
1128*8d67ca89SAndroid Build Coastguard Worker }
1129*8d67ca89SAndroid Build Coastguard Worker
IsDynamic()1130*8d67ca89SAndroid Build Coastguard Worker bool IsDynamic() {
1131*8d67ca89SAndroid Build Coastguard Worker #if defined(__LP64__)
1132*8d67ca89SAndroid Build Coastguard Worker Elf64_Ehdr ehdr;
1133*8d67ca89SAndroid Build Coastguard Worker #else
1134*8d67ca89SAndroid Build Coastguard Worker Elf32_Ehdr ehdr;
1135*8d67ca89SAndroid Build Coastguard Worker #endif
1136*8d67ca89SAndroid Build Coastguard Worker std::string path(android::base::GetExecutablePath());
1137*8d67ca89SAndroid Build Coastguard Worker
1138*8d67ca89SAndroid Build Coastguard Worker int fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
1139*8d67ca89SAndroid Build Coastguard Worker if (fd == -1) {
1140*8d67ca89SAndroid Build Coastguard Worker // Assume dynamic on error.
1141*8d67ca89SAndroid Build Coastguard Worker return true;
1142*8d67ca89SAndroid Build Coastguard Worker }
1143*8d67ca89SAndroid Build Coastguard Worker bool read_completed = android::base::ReadFully(fd, &ehdr, sizeof(ehdr));
1144*8d67ca89SAndroid Build Coastguard Worker close(fd);
1145*8d67ca89SAndroid Build Coastguard Worker // Assume dynamic in error cases.
1146*8d67ca89SAndroid Build Coastguard Worker return !read_completed || ehdr.e_type == ET_DYN;
1147*8d67ca89SAndroid Build Coastguard Worker }
1148*8d67ca89SAndroid Build Coastguard Worker
TEST(android_mallopt,init_zygote_child_profiling)1149*8d67ca89SAndroid Build Coastguard Worker TEST(android_mallopt, init_zygote_child_profiling) {
1150*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1151*8d67ca89SAndroid Build Coastguard Worker // Successful call.
1152*8d67ca89SAndroid Build Coastguard Worker errno = 0;
1153*8d67ca89SAndroid Build Coastguard Worker if (IsDynamic()) {
1154*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(true, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0));
1155*8d67ca89SAndroid Build Coastguard Worker EXPECT_ERRNO(0);
1156*8d67ca89SAndroid Build Coastguard Worker } else {
1157*8d67ca89SAndroid Build Coastguard Worker // Not supported in static executables.
1158*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(false, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0));
1159*8d67ca89SAndroid Build Coastguard Worker EXPECT_ERRNO(ENOTSUP);
1160*8d67ca89SAndroid Build Coastguard Worker }
1161*8d67ca89SAndroid Build Coastguard Worker
1162*8d67ca89SAndroid Build Coastguard Worker // Unexpected arguments rejected.
1163*8d67ca89SAndroid Build Coastguard Worker errno = 0;
1164*8d67ca89SAndroid Build Coastguard Worker char unexpected = 0;
1165*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(false, android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, &unexpected, 1));
1166*8d67ca89SAndroid Build Coastguard Worker if (IsDynamic()) {
1167*8d67ca89SAndroid Build Coastguard Worker EXPECT_ERRNO(EINVAL);
1168*8d67ca89SAndroid Build Coastguard Worker } else {
1169*8d67ca89SAndroid Build Coastguard Worker EXPECT_ERRNO(ENOTSUP);
1170*8d67ca89SAndroid Build Coastguard Worker }
1171*8d67ca89SAndroid Build Coastguard Worker #else
1172*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
1173*8d67ca89SAndroid Build Coastguard Worker #endif
1174*8d67ca89SAndroid Build Coastguard Worker }
1175*8d67ca89SAndroid Build Coastguard Worker
1176*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1177*8d67ca89SAndroid Build Coastguard Worker template <typename FuncType>
CheckAllocationFunction(FuncType func)1178*8d67ca89SAndroid Build Coastguard Worker void CheckAllocationFunction(FuncType func) {
1179*8d67ca89SAndroid Build Coastguard Worker // Assumes that no more than 108MB of memory is allocated before this.
1180*8d67ca89SAndroid Build Coastguard Worker size_t limit = 128 * 1024 * 1024;
1181*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
1182*8d67ca89SAndroid Build Coastguard Worker if (!func(20 * 1024 * 1024))
1183*8d67ca89SAndroid Build Coastguard Worker exit(1);
1184*8d67ca89SAndroid Build Coastguard Worker if (func(128 * 1024 * 1024))
1185*8d67ca89SAndroid Build Coastguard Worker exit(1);
1186*8d67ca89SAndroid Build Coastguard Worker exit(0);
1187*8d67ca89SAndroid Build Coastguard Worker }
1188*8d67ca89SAndroid Build Coastguard Worker #endif
1189*8d67ca89SAndroid Build Coastguard Worker
TEST(android_mallopt,set_allocation_limit)1190*8d67ca89SAndroid Build Coastguard Worker TEST(android_mallopt, set_allocation_limit) {
1191*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1192*8d67ca89SAndroid Build Coastguard Worker EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) { return calloc(bytes, 1) != nullptr; }),
1193*8d67ca89SAndroid Build Coastguard Worker testing::ExitedWithCode(0), "");
1194*8d67ca89SAndroid Build Coastguard Worker EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) { return calloc(1, bytes) != nullptr; }),
1195*8d67ca89SAndroid Build Coastguard Worker testing::ExitedWithCode(0), "");
1196*8d67ca89SAndroid Build Coastguard Worker EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) { return malloc(bytes) != nullptr; }),
1197*8d67ca89SAndroid Build Coastguard Worker testing::ExitedWithCode(0), "");
1198*8d67ca89SAndroid Build Coastguard Worker EXPECT_EXIT(CheckAllocationFunction(
1199*8d67ca89SAndroid Build Coastguard Worker [](size_t bytes) { return memalign(sizeof(void*), bytes) != nullptr; }),
1200*8d67ca89SAndroid Build Coastguard Worker testing::ExitedWithCode(0), "");
1201*8d67ca89SAndroid Build Coastguard Worker EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) {
1202*8d67ca89SAndroid Build Coastguard Worker void* ptr;
1203*8d67ca89SAndroid Build Coastguard Worker return posix_memalign(&ptr, sizeof(void *), bytes) == 0;
1204*8d67ca89SAndroid Build Coastguard Worker }),
1205*8d67ca89SAndroid Build Coastguard Worker testing::ExitedWithCode(0), "");
1206*8d67ca89SAndroid Build Coastguard Worker EXPECT_EXIT(CheckAllocationFunction(
1207*8d67ca89SAndroid Build Coastguard Worker [](size_t bytes) { return aligned_alloc(sizeof(void*), bytes) != nullptr; }),
1208*8d67ca89SAndroid Build Coastguard Worker testing::ExitedWithCode(0), "");
1209*8d67ca89SAndroid Build Coastguard Worker EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) {
1210*8d67ca89SAndroid Build Coastguard Worker void* p = malloc(1024 * 1024);
1211*8d67ca89SAndroid Build Coastguard Worker return realloc(p, bytes) != nullptr;
1212*8d67ca89SAndroid Build Coastguard Worker }),
1213*8d67ca89SAndroid Build Coastguard Worker testing::ExitedWithCode(0), "");
1214*8d67ca89SAndroid Build Coastguard Worker #if !defined(__LP64__)
1215*8d67ca89SAndroid Build Coastguard Worker EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) { return pvalloc(bytes) != nullptr; }),
1216*8d67ca89SAndroid Build Coastguard Worker testing::ExitedWithCode(0), "");
1217*8d67ca89SAndroid Build Coastguard Worker EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) { return valloc(bytes) != nullptr; }),
1218*8d67ca89SAndroid Build Coastguard Worker testing::ExitedWithCode(0), "");
1219*8d67ca89SAndroid Build Coastguard Worker #endif
1220*8d67ca89SAndroid Build Coastguard Worker #else
1221*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic extension";
1222*8d67ca89SAndroid Build Coastguard Worker #endif
1223*8d67ca89SAndroid Build Coastguard Worker }
1224*8d67ca89SAndroid Build Coastguard Worker
TEST(android_mallopt,set_allocation_limit_multiple)1225*8d67ca89SAndroid Build Coastguard Worker TEST(android_mallopt, set_allocation_limit_multiple) {
1226*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1227*8d67ca89SAndroid Build Coastguard Worker // Only the first set should work.
1228*8d67ca89SAndroid Build Coastguard Worker size_t limit = 256 * 1024 * 1024;
1229*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
1230*8d67ca89SAndroid Build Coastguard Worker limit = 32 * 1024 * 1024;
1231*8d67ca89SAndroid Build Coastguard Worker ASSERT_FALSE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
1232*8d67ca89SAndroid Build Coastguard Worker #else
1233*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic extension";
1234*8d67ca89SAndroid Build Coastguard Worker #endif
1235*8d67ca89SAndroid Build Coastguard Worker }
1236*8d67ca89SAndroid Build Coastguard Worker
1237*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1238*8d67ca89SAndroid Build Coastguard Worker static constexpr size_t kAllocationSize = 8 * 1024 * 1024;
1239*8d67ca89SAndroid Build Coastguard Worker
GetMaxAllocations()1240*8d67ca89SAndroid Build Coastguard Worker static size_t GetMaxAllocations() {
1241*8d67ca89SAndroid Build Coastguard Worker size_t max_pointers = 0;
1242*8d67ca89SAndroid Build Coastguard Worker void* ptrs[20];
1243*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < sizeof(ptrs) / sizeof(void*); i++) {
1244*8d67ca89SAndroid Build Coastguard Worker ptrs[i] = malloc(kAllocationSize);
1245*8d67ca89SAndroid Build Coastguard Worker if (ptrs[i] == nullptr) {
1246*8d67ca89SAndroid Build Coastguard Worker max_pointers = i;
1247*8d67ca89SAndroid Build Coastguard Worker break;
1248*8d67ca89SAndroid Build Coastguard Worker }
1249*8d67ca89SAndroid Build Coastguard Worker }
1250*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < max_pointers; i++) {
1251*8d67ca89SAndroid Build Coastguard Worker free(ptrs[i]);
1252*8d67ca89SAndroid Build Coastguard Worker }
1253*8d67ca89SAndroid Build Coastguard Worker return max_pointers;
1254*8d67ca89SAndroid Build Coastguard Worker }
1255*8d67ca89SAndroid Build Coastguard Worker
VerifyMaxPointers(size_t max_pointers)1256*8d67ca89SAndroid Build Coastguard Worker static void VerifyMaxPointers(size_t max_pointers) {
1257*8d67ca89SAndroid Build Coastguard Worker // Now verify that we can allocate the same number as before.
1258*8d67ca89SAndroid Build Coastguard Worker void* ptrs[20];
1259*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < max_pointers; i++) {
1260*8d67ca89SAndroid Build Coastguard Worker ptrs[i] = malloc(kAllocationSize);
1261*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptrs[i] != nullptr) << "Failed to allocate on iteration " << i;
1262*8d67ca89SAndroid Build Coastguard Worker }
1263*8d67ca89SAndroid Build Coastguard Worker
1264*8d67ca89SAndroid Build Coastguard Worker // Make sure the next allocation still fails.
1265*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(malloc(kAllocationSize) == nullptr);
1266*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < max_pointers; i++) {
1267*8d67ca89SAndroid Build Coastguard Worker free(ptrs[i]);
1268*8d67ca89SAndroid Build Coastguard Worker }
1269*8d67ca89SAndroid Build Coastguard Worker }
1270*8d67ca89SAndroid Build Coastguard Worker #endif
1271*8d67ca89SAndroid Build Coastguard Worker
TEST(android_mallopt,set_allocation_limit_realloc_increase)1272*8d67ca89SAndroid Build Coastguard Worker TEST(android_mallopt, set_allocation_limit_realloc_increase) {
1273*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1274*8d67ca89SAndroid Build Coastguard Worker size_t limit = 128 * 1024 * 1024;
1275*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
1276*8d67ca89SAndroid Build Coastguard Worker
1277*8d67ca89SAndroid Build Coastguard Worker size_t max_pointers = GetMaxAllocations();
1278*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(max_pointers != 0) << "Limit never reached.";
1279*8d67ca89SAndroid Build Coastguard Worker
1280*8d67ca89SAndroid Build Coastguard Worker void* memory = malloc(10 * 1024 * 1024);
1281*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memory != nullptr);
1282*8d67ca89SAndroid Build Coastguard Worker
1283*8d67ca89SAndroid Build Coastguard Worker // Increase size.
1284*8d67ca89SAndroid Build Coastguard Worker memory = realloc(memory, 20 * 1024 * 1024);
1285*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memory != nullptr);
1286*8d67ca89SAndroid Build Coastguard Worker memory = realloc(memory, 40 * 1024 * 1024);
1287*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memory != nullptr);
1288*8d67ca89SAndroid Build Coastguard Worker memory = realloc(memory, 60 * 1024 * 1024);
1289*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memory != nullptr);
1290*8d67ca89SAndroid Build Coastguard Worker memory = realloc(memory, 80 * 1024 * 1024);
1291*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memory != nullptr);
1292*8d67ca89SAndroid Build Coastguard Worker // Now push past limit.
1293*8d67ca89SAndroid Build Coastguard Worker memory = realloc(memory, 130 * 1024 * 1024);
1294*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memory == nullptr);
1295*8d67ca89SAndroid Build Coastguard Worker
1296*8d67ca89SAndroid Build Coastguard Worker VerifyMaxPointers(max_pointers);
1297*8d67ca89SAndroid Build Coastguard Worker #else
1298*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic extension";
1299*8d67ca89SAndroid Build Coastguard Worker #endif
1300*8d67ca89SAndroid Build Coastguard Worker }
1301*8d67ca89SAndroid Build Coastguard Worker
TEST(android_mallopt,set_allocation_limit_realloc_decrease)1302*8d67ca89SAndroid Build Coastguard Worker TEST(android_mallopt, set_allocation_limit_realloc_decrease) {
1303*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1304*8d67ca89SAndroid Build Coastguard Worker size_t limit = 100 * 1024 * 1024;
1305*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
1306*8d67ca89SAndroid Build Coastguard Worker
1307*8d67ca89SAndroid Build Coastguard Worker size_t max_pointers = GetMaxAllocations();
1308*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(max_pointers != 0) << "Limit never reached.";
1309*8d67ca89SAndroid Build Coastguard Worker
1310*8d67ca89SAndroid Build Coastguard Worker void* memory = malloc(80 * 1024 * 1024);
1311*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memory != nullptr);
1312*8d67ca89SAndroid Build Coastguard Worker
1313*8d67ca89SAndroid Build Coastguard Worker // Decrease size.
1314*8d67ca89SAndroid Build Coastguard Worker memory = realloc(memory, 60 * 1024 * 1024);
1315*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memory != nullptr);
1316*8d67ca89SAndroid Build Coastguard Worker memory = realloc(memory, 40 * 1024 * 1024);
1317*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memory != nullptr);
1318*8d67ca89SAndroid Build Coastguard Worker memory = realloc(memory, 20 * 1024 * 1024);
1319*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memory != nullptr);
1320*8d67ca89SAndroid Build Coastguard Worker memory = realloc(memory, 10 * 1024 * 1024);
1321*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memory != nullptr);
1322*8d67ca89SAndroid Build Coastguard Worker free(memory);
1323*8d67ca89SAndroid Build Coastguard Worker
1324*8d67ca89SAndroid Build Coastguard Worker VerifyMaxPointers(max_pointers);
1325*8d67ca89SAndroid Build Coastguard Worker #else
1326*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic extension";
1327*8d67ca89SAndroid Build Coastguard Worker #endif
1328*8d67ca89SAndroid Build Coastguard Worker }
1329*8d67ca89SAndroid Build Coastguard Worker
TEST(android_mallopt,set_allocation_limit_realloc_free)1330*8d67ca89SAndroid Build Coastguard Worker TEST(android_mallopt, set_allocation_limit_realloc_free) {
1331*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1332*8d67ca89SAndroid Build Coastguard Worker size_t limit = 100 * 1024 * 1024;
1333*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
1334*8d67ca89SAndroid Build Coastguard Worker
1335*8d67ca89SAndroid Build Coastguard Worker size_t max_pointers = GetMaxAllocations();
1336*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(max_pointers != 0) << "Limit never reached.";
1337*8d67ca89SAndroid Build Coastguard Worker
1338*8d67ca89SAndroid Build Coastguard Worker void* memory = malloc(60 * 1024 * 1024);
1339*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memory != nullptr);
1340*8d67ca89SAndroid Build Coastguard Worker
1341*8d67ca89SAndroid Build Coastguard Worker memory = realloc(memory, 0);
1342*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(memory == nullptr);
1343*8d67ca89SAndroid Build Coastguard Worker
1344*8d67ca89SAndroid Build Coastguard Worker VerifyMaxPointers(max_pointers);
1345*8d67ca89SAndroid Build Coastguard Worker #else
1346*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic extension";
1347*8d67ca89SAndroid Build Coastguard Worker #endif
1348*8d67ca89SAndroid Build Coastguard Worker }
1349*8d67ca89SAndroid Build Coastguard Worker
1350*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
SetAllocationLimitMultipleThreads()1351*8d67ca89SAndroid Build Coastguard Worker static void SetAllocationLimitMultipleThreads() {
1352*8d67ca89SAndroid Build Coastguard Worker static constexpr size_t kNumThreads = 4;
1353*8d67ca89SAndroid Build Coastguard Worker std::atomic_bool start_running = false;
1354*8d67ca89SAndroid Build Coastguard Worker std::atomic<size_t> num_running;
1355*8d67ca89SAndroid Build Coastguard Worker std::atomic<size_t> num_successful;
1356*8d67ca89SAndroid Build Coastguard Worker std::unique_ptr<std::thread> threads[kNumThreads];
1357*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < kNumThreads; i++) {
1358*8d67ca89SAndroid Build Coastguard Worker threads[i].reset(new std::thread([&num_running, &start_running, &num_successful] {
1359*8d67ca89SAndroid Build Coastguard Worker ++num_running;
1360*8d67ca89SAndroid Build Coastguard Worker while (!start_running) {
1361*8d67ca89SAndroid Build Coastguard Worker }
1362*8d67ca89SAndroid Build Coastguard Worker size_t limit = 500 * 1024 * 1024;
1363*8d67ca89SAndroid Build Coastguard Worker if (android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit))) {
1364*8d67ca89SAndroid Build Coastguard Worker ++num_successful;
1365*8d67ca89SAndroid Build Coastguard Worker }
1366*8d67ca89SAndroid Build Coastguard Worker }));
1367*8d67ca89SAndroid Build Coastguard Worker }
1368*8d67ca89SAndroid Build Coastguard Worker
1369*8d67ca89SAndroid Build Coastguard Worker // Wait until all of the threads have started.
1370*8d67ca89SAndroid Build Coastguard Worker while (num_running != kNumThreads)
1371*8d67ca89SAndroid Build Coastguard Worker ;
1372*8d67ca89SAndroid Build Coastguard Worker
1373*8d67ca89SAndroid Build Coastguard Worker // Now start all of the threads setting the mallopt at once.
1374*8d67ca89SAndroid Build Coastguard Worker start_running = true;
1375*8d67ca89SAndroid Build Coastguard Worker
1376*8d67ca89SAndroid Build Coastguard Worker // Send hardcoded signal (BIONIC_SIGNAL_PROFILER with value 0) to trigger
1377*8d67ca89SAndroid Build Coastguard Worker // heapprofd handler. This will verify that changing the limit while
1378*8d67ca89SAndroid Build Coastguard Worker // the allocation handlers are being changed at the same time works,
1379*8d67ca89SAndroid Build Coastguard Worker // or that the limit handler is changed first and this also works properly.
1380*8d67ca89SAndroid Build Coastguard Worker union sigval signal_value {};
1381*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, sigqueue(getpid(), BIONIC_SIGNAL_PROFILER, signal_value));
1382*8d67ca89SAndroid Build Coastguard Worker
1383*8d67ca89SAndroid Build Coastguard Worker // Wait for all of the threads to finish.
1384*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < kNumThreads; i++) {
1385*8d67ca89SAndroid Build Coastguard Worker threads[i]->join();
1386*8d67ca89SAndroid Build Coastguard Worker }
1387*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(1U, num_successful) << "Only one thread should be able to set the limit.";
1388*8d67ca89SAndroid Build Coastguard Worker _exit(0);
1389*8d67ca89SAndroid Build Coastguard Worker }
1390*8d67ca89SAndroid Build Coastguard Worker #endif
1391*8d67ca89SAndroid Build Coastguard Worker
TEST(android_mallopt,set_allocation_limit_multiple_threads)1392*8d67ca89SAndroid Build Coastguard Worker TEST(android_mallopt, set_allocation_limit_multiple_threads) {
1393*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1394*8d67ca89SAndroid Build Coastguard Worker if (IsDynamic()) {
1395*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0));
1396*8d67ca89SAndroid Build Coastguard Worker }
1397*8d67ca89SAndroid Build Coastguard Worker
1398*8d67ca89SAndroid Build Coastguard Worker // Run this a number of times as a stress test.
1399*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < 100; i++) {
1400*8d67ca89SAndroid Build Coastguard Worker // Not using ASSERT_EXIT because errors messages are not displayed.
1401*8d67ca89SAndroid Build Coastguard Worker pid_t pid;
1402*8d67ca89SAndroid Build Coastguard Worker if ((pid = fork()) == 0) {
1403*8d67ca89SAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(SetAllocationLimitMultipleThreads());
1404*8d67ca89SAndroid Build Coastguard Worker }
1405*8d67ca89SAndroid Build Coastguard Worker ASSERT_NE(-1, pid);
1406*8d67ca89SAndroid Build Coastguard Worker int status;
1407*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(pid, wait(&status));
1408*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, WEXITSTATUS(status));
1409*8d67ca89SAndroid Build Coastguard Worker }
1410*8d67ca89SAndroid Build Coastguard Worker #else
1411*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic extension";
1412*8d67ca89SAndroid Build Coastguard Worker #endif
1413*8d67ca89SAndroid Build Coastguard Worker }
1414*8d67ca89SAndroid Build Coastguard Worker
1415*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1416*8d67ca89SAndroid Build Coastguard Worker using Mode = android_mallopt_gwp_asan_options_t::Mode;
TEST(android_mallopt,DISABLED_multiple_enable_gwp_asan)1417*8d67ca89SAndroid Build Coastguard Worker TEST(android_mallopt, DISABLED_multiple_enable_gwp_asan) {
1418*8d67ca89SAndroid Build Coastguard Worker android_mallopt_gwp_asan_options_t options;
1419*8d67ca89SAndroid Build Coastguard Worker options.program_name = ""; // Don't infer GWP-ASan options from sysprops.
1420*8d67ca89SAndroid Build Coastguard Worker options.mode = Mode::APP_MANIFEST_NEVER;
1421*8d67ca89SAndroid Build Coastguard Worker // GWP-ASan should already be enabled. Trying to enable or disable it should
1422*8d67ca89SAndroid Build Coastguard Worker // always pass.
1423*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(android_mallopt(M_INITIALIZE_GWP_ASAN, &options, sizeof(options)));
1424*8d67ca89SAndroid Build Coastguard Worker options.mode = Mode::APP_MANIFEST_DEFAULT;
1425*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(android_mallopt(M_INITIALIZE_GWP_ASAN, &options, sizeof(options)));
1426*8d67ca89SAndroid Build Coastguard Worker }
1427*8d67ca89SAndroid Build Coastguard Worker #endif // defined(__BIONIC__)
1428*8d67ca89SAndroid Build Coastguard Worker
TEST(android_mallopt,multiple_enable_gwp_asan)1429*8d67ca89SAndroid Build Coastguard Worker TEST(android_mallopt, multiple_enable_gwp_asan) {
1430*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1431*8d67ca89SAndroid Build Coastguard Worker // Always enable GWP-Asan, with default options.
1432*8d67ca89SAndroid Build Coastguard Worker RunGwpAsanTest("*.DISABLED_multiple_enable_gwp_asan");
1433*8d67ca89SAndroid Build Coastguard Worker #else
1434*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic extension";
1435*8d67ca89SAndroid Build Coastguard Worker #endif
1436*8d67ca89SAndroid Build Coastguard Worker }
1437*8d67ca89SAndroid Build Coastguard Worker
TEST(android_mallopt,memtag_stack_is_on)1438*8d67ca89SAndroid Build Coastguard Worker TEST(android_mallopt, memtag_stack_is_on) {
1439*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1440*8d67ca89SAndroid Build Coastguard Worker bool memtag_stack;
1441*8d67ca89SAndroid Build Coastguard Worker EXPECT_TRUE(android_mallopt(M_MEMTAG_STACK_IS_ON, &memtag_stack, sizeof(memtag_stack)));
1442*8d67ca89SAndroid Build Coastguard Worker #else
1443*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic extension";
1444*8d67ca89SAndroid Build Coastguard Worker #endif
1445*8d67ca89SAndroid Build Coastguard Worker }
1446*8d67ca89SAndroid Build Coastguard Worker
TestHeapZeroing(int num_iterations,int (* get_alloc_size)(int iteration))1447*8d67ca89SAndroid Build Coastguard Worker void TestHeapZeroing(int num_iterations, int (*get_alloc_size)(int iteration)) {
1448*8d67ca89SAndroid Build Coastguard Worker std::vector<void*> allocs;
1449*8d67ca89SAndroid Build Coastguard Worker constexpr int kMaxBytesToCheckZero = 64;
1450*8d67ca89SAndroid Build Coastguard Worker const char kBlankMemory[kMaxBytesToCheckZero] = {};
1451*8d67ca89SAndroid Build Coastguard Worker
1452*8d67ca89SAndroid Build Coastguard Worker for (int i = 0; i < num_iterations; ++i) {
1453*8d67ca89SAndroid Build Coastguard Worker int size = get_alloc_size(i);
1454*8d67ca89SAndroid Build Coastguard Worker allocs.push_back(malloc(size));
1455*8d67ca89SAndroid Build Coastguard Worker memset(allocs.back(), 'X', std::min(size, kMaxBytesToCheckZero));
1456*8d67ca89SAndroid Build Coastguard Worker }
1457*8d67ca89SAndroid Build Coastguard Worker
1458*8d67ca89SAndroid Build Coastguard Worker for (void* alloc : allocs) {
1459*8d67ca89SAndroid Build Coastguard Worker free(alloc);
1460*8d67ca89SAndroid Build Coastguard Worker }
1461*8d67ca89SAndroid Build Coastguard Worker allocs.clear();
1462*8d67ca89SAndroid Build Coastguard Worker
1463*8d67ca89SAndroid Build Coastguard Worker for (int i = 0; i < num_iterations; ++i) {
1464*8d67ca89SAndroid Build Coastguard Worker int size = get_alloc_size(i);
1465*8d67ca89SAndroid Build Coastguard Worker allocs.push_back(malloc(size));
1466*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(allocs.back(), kBlankMemory, std::min(size, kMaxBytesToCheckZero)));
1467*8d67ca89SAndroid Build Coastguard Worker }
1468*8d67ca89SAndroid Build Coastguard Worker
1469*8d67ca89SAndroid Build Coastguard Worker for (void* alloc : allocs) {
1470*8d67ca89SAndroid Build Coastguard Worker free(alloc);
1471*8d67ca89SAndroid Build Coastguard Worker }
1472*8d67ca89SAndroid Build Coastguard Worker }
1473*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,zero_init)1474*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, zero_init) {
1475*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1476*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
1477*8d67ca89SAndroid Build Coastguard Worker bool allocator_scudo;
1478*8d67ca89SAndroid Build Coastguard Worker GetAllocatorVersion(&allocator_scudo);
1479*8d67ca89SAndroid Build Coastguard Worker if (!allocator_scudo) {
1480*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "scudo allocator only test";
1481*8d67ca89SAndroid Build Coastguard Worker }
1482*8d67ca89SAndroid Build Coastguard Worker
1483*8d67ca89SAndroid Build Coastguard Worker mallopt(M_BIONIC_ZERO_INIT, 1);
1484*8d67ca89SAndroid Build Coastguard Worker
1485*8d67ca89SAndroid Build Coastguard Worker // Test using a block of 4K small (1-32 byte) allocations.
1486*8d67ca89SAndroid Build Coastguard Worker TestHeapZeroing(/* num_iterations */ 0x1000, [](int iteration) -> int {
1487*8d67ca89SAndroid Build Coastguard Worker return 1 + iteration % 32;
1488*8d67ca89SAndroid Build Coastguard Worker });
1489*8d67ca89SAndroid Build Coastguard Worker
1490*8d67ca89SAndroid Build Coastguard Worker // Also test large allocations that land in the scudo secondary, as this is
1491*8d67ca89SAndroid Build Coastguard Worker // the only part of Scudo that's changed by enabling zero initialization with
1492*8d67ca89SAndroid Build Coastguard Worker // MTE. Uses 32 allocations, totalling 60MiB memory. Decay time (time to
1493*8d67ca89SAndroid Build Coastguard Worker // release secondary allocations back to the OS) was modified to 0ms/1ms by
1494*8d67ca89SAndroid Build Coastguard Worker // mallopt_decay. Ensure that we delay for at least a second before releasing
1495*8d67ca89SAndroid Build Coastguard Worker // pages to the OS in order to avoid implicit zeroing by the kernel.
1496*8d67ca89SAndroid Build Coastguard Worker mallopt(M_DECAY_TIME, 1);
1497*8d67ca89SAndroid Build Coastguard Worker TestHeapZeroing(/* num_iterations */ 32, [](int iteration) -> int {
1498*8d67ca89SAndroid Build Coastguard Worker return 1 << (19 + iteration % 4);
1499*8d67ca89SAndroid Build Coastguard Worker });
1500*8d67ca89SAndroid Build Coastguard Worker
1501*8d67ca89SAndroid Build Coastguard Worker #else
1502*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
1503*8d67ca89SAndroid Build Coastguard Worker #endif
1504*8d67ca89SAndroid Build Coastguard Worker }
1505*8d67ca89SAndroid Build Coastguard Worker
1506*8d67ca89SAndroid Build Coastguard Worker // Note that MTE is enabled on cc_tests on devices that support MTE.
TEST(malloc,disable_mte)1507*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, disable_mte) {
1508*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1509*8d67ca89SAndroid Build Coastguard Worker if (!mte_supported()) {
1510*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "This function can only be tested with MTE";
1511*8d67ca89SAndroid Build Coastguard Worker }
1512*8d67ca89SAndroid Build Coastguard Worker
1513*8d67ca89SAndroid Build Coastguard Worker sem_t sem;
1514*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, sem_init(&sem, 0, 0));
1515*8d67ca89SAndroid Build Coastguard Worker
1516*8d67ca89SAndroid Build Coastguard Worker pthread_t thread;
1517*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, pthread_create(
1518*8d67ca89SAndroid Build Coastguard Worker &thread, nullptr,
1519*8d67ca89SAndroid Build Coastguard Worker [](void* ptr) -> void* {
1520*8d67ca89SAndroid Build Coastguard Worker auto* sem = reinterpret_cast<sem_t*>(ptr);
1521*8d67ca89SAndroid Build Coastguard Worker sem_wait(sem);
1522*8d67ca89SAndroid Build Coastguard Worker return reinterpret_cast<void*>(prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0));
1523*8d67ca89SAndroid Build Coastguard Worker },
1524*8d67ca89SAndroid Build Coastguard Worker &sem));
1525*8d67ca89SAndroid Build Coastguard Worker
1526*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(1, mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL, M_HEAP_TAGGING_LEVEL_NONE));
1527*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, sem_post(&sem));
1528*8d67ca89SAndroid Build Coastguard Worker
1529*8d67ca89SAndroid Build Coastguard Worker int my_tagged_addr_ctrl = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);
1530*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<unsigned long>(PR_MTE_TCF_NONE), my_tagged_addr_ctrl & PR_MTE_TCF_MASK);
1531*8d67ca89SAndroid Build Coastguard Worker
1532*8d67ca89SAndroid Build Coastguard Worker void* retval;
1533*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, pthread_join(thread, &retval));
1534*8d67ca89SAndroid Build Coastguard Worker int thread_tagged_addr_ctrl = reinterpret_cast<uintptr_t>(retval);
1535*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(my_tagged_addr_ctrl, thread_tagged_addr_ctrl);
1536*8d67ca89SAndroid Build Coastguard Worker #else
1537*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic extension";
1538*8d67ca89SAndroid Build Coastguard Worker #endif
1539*8d67ca89SAndroid Build Coastguard Worker }
1540*8d67ca89SAndroid Build Coastguard Worker
TEST(malloc,allocation_slack)1541*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, allocation_slack) {
1542*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1543*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_NATIVE_BRIDGE; // http://b/189606147
1544*8d67ca89SAndroid Build Coastguard Worker
1545*8d67ca89SAndroid Build Coastguard Worker bool allocator_scudo;
1546*8d67ca89SAndroid Build Coastguard Worker GetAllocatorVersion(&allocator_scudo);
1547*8d67ca89SAndroid Build Coastguard Worker if (!allocator_scudo) {
1548*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "scudo allocator only test";
1549*8d67ca89SAndroid Build Coastguard Worker }
1550*8d67ca89SAndroid Build Coastguard Worker
1551*8d67ca89SAndroid Build Coastguard Worker // Test that older target SDK levels let you access a few bytes off the end of
1552*8d67ca89SAndroid Build Coastguard Worker // a large allocation.
1553*8d67ca89SAndroid Build Coastguard Worker android_set_application_target_sdk_version(29);
1554*8d67ca89SAndroid Build Coastguard Worker auto p = std::make_unique<char[]>(131072);
1555*8d67ca89SAndroid Build Coastguard Worker volatile char *vp = p.get();
1556*8d67ca89SAndroid Build Coastguard Worker volatile char oob ATTRIBUTE_UNUSED = vp[131072];
1557*8d67ca89SAndroid Build Coastguard Worker #else
1558*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic extension";
1559*8d67ca89SAndroid Build Coastguard Worker #endif
1560*8d67ca89SAndroid Build Coastguard Worker }
1561*8d67ca89SAndroid Build Coastguard Worker
1562*8d67ca89SAndroid Build Coastguard Worker // Regression test for b/206701345 -- scudo bug, MTE only.
1563*8d67ca89SAndroid Build Coastguard Worker // Fix: https://reviews.llvm.org/D105261
1564*8d67ca89SAndroid Build Coastguard Worker // Fix: https://android-review.googlesource.com/c/platform/external/scudo/+/1763655
TEST(malloc,realloc_mte_crash_b206701345)1565*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, realloc_mte_crash_b206701345) {
1566*8d67ca89SAndroid Build Coastguard Worker // We want to hit in-place realloc at the very end of an mmap-ed region. Not
1567*8d67ca89SAndroid Build Coastguard Worker // all size classes allow such placement - mmap size has to be divisible by
1568*8d67ca89SAndroid Build Coastguard Worker // the block size. At the time of writing this could only be reproduced with
1569*8d67ca89SAndroid Build Coastguard Worker // 64 byte size class (i.e. 48 byte allocations), but that may change in the
1570*8d67ca89SAndroid Build Coastguard Worker // future. Try several different classes at the lower end.
1571*8d67ca89SAndroid Build Coastguard Worker std::vector<void*> ptrs(10000);
1572*8d67ca89SAndroid Build Coastguard Worker for (int i = 1; i < 32; ++i) {
1573*8d67ca89SAndroid Build Coastguard Worker size_t sz = 16 * i - 1;
1574*8d67ca89SAndroid Build Coastguard Worker for (void*& p : ptrs) {
1575*8d67ca89SAndroid Build Coastguard Worker p = realloc(malloc(sz), sz + 1);
1576*8d67ca89SAndroid Build Coastguard Worker }
1577*8d67ca89SAndroid Build Coastguard Worker
1578*8d67ca89SAndroid Build Coastguard Worker for (void* p : ptrs) {
1579*8d67ca89SAndroid Build Coastguard Worker free(p);
1580*8d67ca89SAndroid Build Coastguard Worker }
1581*8d67ca89SAndroid Build Coastguard Worker }
1582*8d67ca89SAndroid Build Coastguard Worker }
1583*8d67ca89SAndroid Build Coastguard Worker
VerifyAllocationsAreZero(std::function<void * (size_t)> alloc_func,std::string function_name,std::vector<size_t> & test_sizes,size_t max_allocations)1584*8d67ca89SAndroid Build Coastguard Worker void VerifyAllocationsAreZero(std::function<void*(size_t)> alloc_func, std::string function_name,
1585*8d67ca89SAndroid Build Coastguard Worker std::vector<size_t>& test_sizes, size_t max_allocations) {
1586*8d67ca89SAndroid Build Coastguard Worker // Vector of zero'd data used for comparisons. Make it twice the largest size.
1587*8d67ca89SAndroid Build Coastguard Worker std::vector<char> zero(test_sizes.back() * 2, 0);
1588*8d67ca89SAndroid Build Coastguard Worker
1589*8d67ca89SAndroid Build Coastguard Worker SCOPED_TRACE(testing::Message() << function_name << " failed to zero memory");
1590*8d67ca89SAndroid Build Coastguard Worker
1591*8d67ca89SAndroid Build Coastguard Worker for (size_t test_size : test_sizes) {
1592*8d67ca89SAndroid Build Coastguard Worker std::vector<void*> ptrs(max_allocations);
1593*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < ptrs.size(); i++) {
1594*8d67ca89SAndroid Build Coastguard Worker SCOPED_TRACE(testing::Message() << "size " << test_size << " at iteration " << i);
1595*8d67ca89SAndroid Build Coastguard Worker ptrs[i] = alloc_func(test_size);
1596*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptrs[i] != nullptr);
1597*8d67ca89SAndroid Build Coastguard Worker size_t alloc_size = malloc_usable_size(ptrs[i]);
1598*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(alloc_size, zero.size());
1599*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(ptrs[i], zero.data(), alloc_size));
1600*8d67ca89SAndroid Build Coastguard Worker
1601*8d67ca89SAndroid Build Coastguard Worker // Set the memory to non-zero to make sure if the pointer
1602*8d67ca89SAndroid Build Coastguard Worker // is reused it's still zero.
1603*8d67ca89SAndroid Build Coastguard Worker memset(ptrs[i], 0xab, alloc_size);
1604*8d67ca89SAndroid Build Coastguard Worker }
1605*8d67ca89SAndroid Build Coastguard Worker // Free the pointers.
1606*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < ptrs.size(); i++) {
1607*8d67ca89SAndroid Build Coastguard Worker free(ptrs[i]);
1608*8d67ca89SAndroid Build Coastguard Worker }
1609*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < ptrs.size(); i++) {
1610*8d67ca89SAndroid Build Coastguard Worker SCOPED_TRACE(testing::Message() << "size " << test_size << " at iteration " << i);
1611*8d67ca89SAndroid Build Coastguard Worker ptrs[i] = malloc(test_size);
1612*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptrs[i] != nullptr);
1613*8d67ca89SAndroid Build Coastguard Worker size_t alloc_size = malloc_usable_size(ptrs[i]);
1614*8d67ca89SAndroid Build Coastguard Worker ASSERT_LE(alloc_size, zero.size());
1615*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(ptrs[i], zero.data(), alloc_size));
1616*8d67ca89SAndroid Build Coastguard Worker }
1617*8d67ca89SAndroid Build Coastguard Worker // Free all of the pointers later to maximize the chance of reusing from
1618*8d67ca89SAndroid Build Coastguard Worker // the first loop.
1619*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < ptrs.size(); i++) {
1620*8d67ca89SAndroid Build Coastguard Worker free(ptrs[i]);
1621*8d67ca89SAndroid Build Coastguard Worker }
1622*8d67ca89SAndroid Build Coastguard Worker }
1623*8d67ca89SAndroid Build Coastguard Worker }
1624*8d67ca89SAndroid Build Coastguard Worker
1625*8d67ca89SAndroid Build Coastguard Worker // Verify that small and medium allocations are always zero.
1626*8d67ca89SAndroid Build Coastguard Worker // @CddTest = 9.7/C-4-1
TEST(malloc,zeroed_allocations_small_medium_sizes)1627*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, zeroed_allocations_small_medium_sizes) {
1628*8d67ca89SAndroid Build Coastguard Worker #if !defined(__BIONIC__)
1629*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "Only valid on bionic";
1630*8d67ca89SAndroid Build Coastguard Worker #endif
1631*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN << "Only test system allocator, not hwasan allocator.";
1632*8d67ca89SAndroid Build Coastguard Worker
1633*8d67ca89SAndroid Build Coastguard Worker if (IsLowRamDevice()) {
1634*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "Skipped on low memory devices.";
1635*8d67ca89SAndroid Build Coastguard Worker }
1636*8d67ca89SAndroid Build Coastguard Worker
1637*8d67ca89SAndroid Build Coastguard Worker constexpr size_t kMaxAllocations = 1024;
1638*8d67ca89SAndroid Build Coastguard Worker std::vector<size_t> test_sizes = {16, 48, 128, 1024, 4096, 65536};
1639*8d67ca89SAndroid Build Coastguard Worker VerifyAllocationsAreZero([](size_t size) -> void* { return malloc(size); }, "malloc", test_sizes,
1640*8d67ca89SAndroid Build Coastguard Worker kMaxAllocations);
1641*8d67ca89SAndroid Build Coastguard Worker
1642*8d67ca89SAndroid Build Coastguard Worker VerifyAllocationsAreZero([](size_t size) -> void* { return memalign(64, size); }, "memalign",
1643*8d67ca89SAndroid Build Coastguard Worker test_sizes, kMaxAllocations);
1644*8d67ca89SAndroid Build Coastguard Worker
1645*8d67ca89SAndroid Build Coastguard Worker VerifyAllocationsAreZero(
1646*8d67ca89SAndroid Build Coastguard Worker [](size_t size) -> void* {
1647*8d67ca89SAndroid Build Coastguard Worker void* ptr;
1648*8d67ca89SAndroid Build Coastguard Worker if (posix_memalign(&ptr, 64, size) == 0) {
1649*8d67ca89SAndroid Build Coastguard Worker return ptr;
1650*8d67ca89SAndroid Build Coastguard Worker }
1651*8d67ca89SAndroid Build Coastguard Worker return nullptr;
1652*8d67ca89SAndroid Build Coastguard Worker },
1653*8d67ca89SAndroid Build Coastguard Worker "posix_memalign", test_sizes, kMaxAllocations);
1654*8d67ca89SAndroid Build Coastguard Worker }
1655*8d67ca89SAndroid Build Coastguard Worker
1656*8d67ca89SAndroid Build Coastguard Worker // Verify that large allocations are always zero.
1657*8d67ca89SAndroid Build Coastguard Worker // @CddTest = 9.7/C-4-1
TEST(malloc,zeroed_allocations_large_sizes)1658*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, zeroed_allocations_large_sizes) {
1659*8d67ca89SAndroid Build Coastguard Worker #if !defined(__BIONIC__)
1660*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "Only valid on bionic";
1661*8d67ca89SAndroid Build Coastguard Worker #endif
1662*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN << "Only test system allocator, not hwasan allocator.";
1663*8d67ca89SAndroid Build Coastguard Worker
1664*8d67ca89SAndroid Build Coastguard Worker if (IsLowRamDevice()) {
1665*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "Skipped on low memory devices.";
1666*8d67ca89SAndroid Build Coastguard Worker }
1667*8d67ca89SAndroid Build Coastguard Worker
1668*8d67ca89SAndroid Build Coastguard Worker constexpr size_t kMaxAllocations = 20;
1669*8d67ca89SAndroid Build Coastguard Worker std::vector<size_t> test_sizes = {1000000, 2000000, 3000000, 4000000};
1670*8d67ca89SAndroid Build Coastguard Worker VerifyAllocationsAreZero([](size_t size) -> void* { return malloc(size); }, "malloc", test_sizes,
1671*8d67ca89SAndroid Build Coastguard Worker kMaxAllocations);
1672*8d67ca89SAndroid Build Coastguard Worker
1673*8d67ca89SAndroid Build Coastguard Worker VerifyAllocationsAreZero([](size_t size) -> void* { return memalign(64, size); }, "memalign",
1674*8d67ca89SAndroid Build Coastguard Worker test_sizes, kMaxAllocations);
1675*8d67ca89SAndroid Build Coastguard Worker
1676*8d67ca89SAndroid Build Coastguard Worker VerifyAllocationsAreZero(
1677*8d67ca89SAndroid Build Coastguard Worker [](size_t size) -> void* {
1678*8d67ca89SAndroid Build Coastguard Worker void* ptr;
1679*8d67ca89SAndroid Build Coastguard Worker if (posix_memalign(&ptr, 64, size) == 0) {
1680*8d67ca89SAndroid Build Coastguard Worker return ptr;
1681*8d67ca89SAndroid Build Coastguard Worker }
1682*8d67ca89SAndroid Build Coastguard Worker return nullptr;
1683*8d67ca89SAndroid Build Coastguard Worker },
1684*8d67ca89SAndroid Build Coastguard Worker "posix_memalign", test_sizes, kMaxAllocations);
1685*8d67ca89SAndroid Build Coastguard Worker }
1686*8d67ca89SAndroid Build Coastguard Worker
1687*8d67ca89SAndroid Build Coastguard Worker // Verify that reallocs are zeroed when expanded.
1688*8d67ca89SAndroid Build Coastguard Worker // @CddTest = 9.7/C-4-1
TEST(malloc,zeroed_allocations_realloc)1689*8d67ca89SAndroid Build Coastguard Worker TEST(malloc, zeroed_allocations_realloc) {
1690*8d67ca89SAndroid Build Coastguard Worker #if !defined(__BIONIC__)
1691*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "Only valid on bionic";
1692*8d67ca89SAndroid Build Coastguard Worker #endif
1693*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN << "Only test system allocator, not hwasan allocator.";
1694*8d67ca89SAndroid Build Coastguard Worker
1695*8d67ca89SAndroid Build Coastguard Worker if (IsLowRamDevice()) {
1696*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "Skipped on low memory devices.";
1697*8d67ca89SAndroid Build Coastguard Worker }
1698*8d67ca89SAndroid Build Coastguard Worker
1699*8d67ca89SAndroid Build Coastguard Worker // Vector of zero'd data used for comparisons.
1700*8d67ca89SAndroid Build Coastguard Worker constexpr size_t kMaxMemorySize = 131072;
1701*8d67ca89SAndroid Build Coastguard Worker std::vector<char> zero(kMaxMemorySize, 0);
1702*8d67ca89SAndroid Build Coastguard Worker
1703*8d67ca89SAndroid Build Coastguard Worker constexpr size_t kMaxAllocations = 1024;
1704*8d67ca89SAndroid Build Coastguard Worker std::vector<size_t> test_sizes = {16, 48, 128, 1024, 4096, 65536};
1705*8d67ca89SAndroid Build Coastguard Worker // Do a number of allocations and set them to non-zero.
1706*8d67ca89SAndroid Build Coastguard Worker for (size_t test_size : test_sizes) {
1707*8d67ca89SAndroid Build Coastguard Worker std::vector<void*> ptrs(kMaxAllocations);
1708*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < kMaxAllocations; i++) {
1709*8d67ca89SAndroid Build Coastguard Worker ptrs[i] = malloc(test_size);
1710*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptrs[i] != nullptr);
1711*8d67ca89SAndroid Build Coastguard Worker
1712*8d67ca89SAndroid Build Coastguard Worker // Set the memory to non-zero to make sure if the pointer
1713*8d67ca89SAndroid Build Coastguard Worker // is reused it's still zero.
1714*8d67ca89SAndroid Build Coastguard Worker memset(ptrs[i], 0xab, malloc_usable_size(ptrs[i]));
1715*8d67ca89SAndroid Build Coastguard Worker }
1716*8d67ca89SAndroid Build Coastguard Worker // Free the pointers.
1717*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < kMaxAllocations; i++) {
1718*8d67ca89SAndroid Build Coastguard Worker free(ptrs[i]);
1719*8d67ca89SAndroid Build Coastguard Worker }
1720*8d67ca89SAndroid Build Coastguard Worker }
1721*8d67ca89SAndroid Build Coastguard Worker
1722*8d67ca89SAndroid Build Coastguard Worker // Do the reallocs to a larger size and verify the rest of the allocation
1723*8d67ca89SAndroid Build Coastguard Worker // is zero.
1724*8d67ca89SAndroid Build Coastguard Worker constexpr size_t kInitialSize = 8;
1725*8d67ca89SAndroid Build Coastguard Worker for (size_t test_size : test_sizes) {
1726*8d67ca89SAndroid Build Coastguard Worker std::vector<void*> ptrs(kMaxAllocations);
1727*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < kMaxAllocations; i++) {
1728*8d67ca89SAndroid Build Coastguard Worker ptrs[i] = malloc(kInitialSize);
1729*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptrs[i] != nullptr);
1730*8d67ca89SAndroid Build Coastguard Worker size_t orig_alloc_size = malloc_usable_size(ptrs[i]);
1731*8d67ca89SAndroid Build Coastguard Worker
1732*8d67ca89SAndroid Build Coastguard Worker ptrs[i] = realloc(ptrs[i], test_size);
1733*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ptrs[i] != nullptr);
1734*8d67ca89SAndroid Build Coastguard Worker size_t new_alloc_size = malloc_usable_size(ptrs[i]);
1735*8d67ca89SAndroid Build Coastguard Worker char* ptr = reinterpret_cast<char*>(ptrs[i]);
1736*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(&ptr[orig_alloc_size], zero.data(), new_alloc_size - orig_alloc_size))
1737*8d67ca89SAndroid Build Coastguard Worker << "realloc from " << kInitialSize << " to size " << test_size << " at iteration " << i;
1738*8d67ca89SAndroid Build Coastguard Worker }
1739*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < kMaxAllocations; i++) {
1740*8d67ca89SAndroid Build Coastguard Worker free(ptrs[i]);
1741*8d67ca89SAndroid Build Coastguard Worker }
1742*8d67ca89SAndroid Build Coastguard Worker }
1743*8d67ca89SAndroid Build Coastguard Worker }
1744*8d67ca89SAndroid Build Coastguard Worker
TEST(android_mallopt,get_decay_time_enabled_errors)1745*8d67ca89SAndroid Build Coastguard Worker TEST(android_mallopt, get_decay_time_enabled_errors) {
1746*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1747*8d67ca89SAndroid Build Coastguard Worker errno = 0;
1748*8d67ca89SAndroid Build Coastguard Worker EXPECT_FALSE(android_mallopt(M_GET_DECAY_TIME_ENABLED, nullptr, sizeof(bool)));
1749*8d67ca89SAndroid Build Coastguard Worker EXPECT_ERRNO(EINVAL);
1750*8d67ca89SAndroid Build Coastguard Worker
1751*8d67ca89SAndroid Build Coastguard Worker errno = 0;
1752*8d67ca89SAndroid Build Coastguard Worker int value;
1753*8d67ca89SAndroid Build Coastguard Worker EXPECT_FALSE(android_mallopt(M_GET_DECAY_TIME_ENABLED, &value, sizeof(value)));
1754*8d67ca89SAndroid Build Coastguard Worker EXPECT_ERRNO(EINVAL);
1755*8d67ca89SAndroid Build Coastguard Worker #else
1756*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
1757*8d67ca89SAndroid Build Coastguard Worker #endif
1758*8d67ca89SAndroid Build Coastguard Worker }
1759*8d67ca89SAndroid Build Coastguard Worker
TEST(android_mallopt,get_decay_time_enabled)1760*8d67ca89SAndroid Build Coastguard Worker TEST(android_mallopt, get_decay_time_enabled) {
1761*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
1762*8d67ca89SAndroid Build Coastguard Worker SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
1763*8d67ca89SAndroid Build Coastguard Worker
1764*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(1, mallopt(M_DECAY_TIME, 0));
1765*8d67ca89SAndroid Build Coastguard Worker
1766*8d67ca89SAndroid Build Coastguard Worker bool value;
1767*8d67ca89SAndroid Build Coastguard Worker EXPECT_TRUE(android_mallopt(M_GET_DECAY_TIME_ENABLED, &value, sizeof(value)));
1768*8d67ca89SAndroid Build Coastguard Worker EXPECT_FALSE(value);
1769*8d67ca89SAndroid Build Coastguard Worker
1770*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(1, mallopt(M_DECAY_TIME, 1));
1771*8d67ca89SAndroid Build Coastguard Worker EXPECT_TRUE(android_mallopt(M_GET_DECAY_TIME_ENABLED, &value, sizeof(value)));
1772*8d67ca89SAndroid Build Coastguard Worker EXPECT_TRUE(value);
1773*8d67ca89SAndroid Build Coastguard Worker
1774*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(1, mallopt(M_DECAY_TIME, -1));
1775*8d67ca89SAndroid Build Coastguard Worker EXPECT_TRUE(android_mallopt(M_GET_DECAY_TIME_ENABLED, &value, sizeof(value)));
1776*8d67ca89SAndroid Build Coastguard Worker EXPECT_FALSE(value);
1777*8d67ca89SAndroid Build Coastguard Worker #else
1778*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
1779*8d67ca89SAndroid Build Coastguard Worker #endif
1780*8d67ca89SAndroid Build Coastguard Worker }
1781