]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/platform-bionic.git/blob - tests/malloc_test.cpp
Merge "Remove bogus transitive includes."
[android-sdk/platform-bionic.git] / tests / malloc_test.cpp
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
17 #include <gtest/gtest.h>
19 #include <limits.h>
20 #include <stdint.h>
21 #include <stdlib.h>
22 #include <malloc.h>
23 #include <unistd.h>
25 #include <tinyxml2.h>
27 #include "private/bionic_config.h"
29 TEST(malloc, malloc_std) {
30   // Simple malloc test.
31   void *ptr = malloc(100);
32   ASSERT_TRUE(ptr != NULL);
33   ASSERT_LE(100U, malloc_usable_size(ptr));
34   free(ptr);
35 }
37 TEST(malloc, malloc_overflow) {
38   errno = 0;
39   ASSERT_EQ(NULL, malloc(SIZE_MAX));
40   ASSERT_EQ(ENOMEM, errno);
41 }
43 TEST(malloc, calloc_std) {
44   // Simple calloc test.
45   size_t alloc_len = 100;
46   char *ptr = (char *)calloc(1, alloc_len);
47   ASSERT_TRUE(ptr != NULL);
48   ASSERT_LE(alloc_len, malloc_usable_size(ptr));
49   for (size_t i = 0; i < alloc_len; i++) {
50     ASSERT_EQ(0, ptr[i]);
51   }
52   free(ptr);
53 }
55 TEST(malloc, calloc_illegal) {
56   errno = 0;
57   ASSERT_EQ(NULL, calloc(-1, 100));
58   ASSERT_EQ(ENOMEM, errno);
59 }
61 TEST(malloc, calloc_overflow) {
62   errno = 0;
63   ASSERT_EQ(NULL, calloc(1, SIZE_MAX));
64   ASSERT_EQ(ENOMEM, errno);
65   errno = 0;
66   ASSERT_EQ(NULL, calloc(SIZE_MAX, SIZE_MAX));
67   ASSERT_EQ(ENOMEM, errno);
68   errno = 0;
69   ASSERT_EQ(NULL, calloc(2, SIZE_MAX));
70   ASSERT_EQ(ENOMEM, errno);
71   errno = 0;
72   ASSERT_EQ(NULL, calloc(SIZE_MAX, 2));
73   ASSERT_EQ(ENOMEM, errno);
74 }
76 TEST(malloc, memalign_multiple) {
77   // Memalign test where the alignment is any value.
78   for (size_t i = 0; i <= 12; i++) {
79     for (size_t alignment = 1 << i; alignment < (1U << (i+1)); alignment++) {
80       char *ptr = reinterpret_cast<char*>(memalign(alignment, 100));
81       ASSERT_TRUE(ptr != NULL) << "Failed at alignment " << alignment;
82       ASSERT_LE(100U, malloc_usable_size(ptr)) << "Failed at alignment " << alignment;
83       ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) % ((1U << i)))
84           << "Failed at alignment " << alignment;
85       free(ptr);
86     }
87   }
88 }
90 TEST(malloc, memalign_overflow) {
91   ASSERT_EQ(NULL, memalign(4096, SIZE_MAX));
92 }
94 TEST(malloc, memalign_non_power2) {
95   void* ptr;
96   for (size_t align = 0; align <= 256; align++) {
97     ptr = memalign(align, 1024);
98     ASSERT_TRUE(ptr != NULL) << "Failed at align " << align;
99     free(ptr);
100   }
103 TEST(malloc, posix_memalign_non_power2) {
104   void* ptr;
105   ASSERT_EQ(EINVAL, posix_memalign(&ptr, 17, 1024));
108 TEST(malloc, posix_memalign_overflow) {
109   void* ptr;
110   ASSERT_NE(0, posix_memalign(&ptr, 16, SIZE_MAX));
113 TEST(malloc, memalign_realloc) {
114   // Memalign and then realloc the pointer a couple of times.
115   for (size_t alignment = 1; alignment <= 4096; alignment <<= 1) {
116     char *ptr = (char*)memalign(alignment, 100);
117     ASSERT_TRUE(ptr != NULL);
118     ASSERT_LE(100U, malloc_usable_size(ptr));
119     ASSERT_EQ(0U, (intptr_t)ptr % alignment);
120     memset(ptr, 0x23, 100);
122     ptr = (char*)realloc(ptr, 200);
123     ASSERT_TRUE(ptr != NULL);
124     ASSERT_LE(200U, malloc_usable_size(ptr));
125     ASSERT_TRUE(ptr != NULL);
126     for (size_t i = 0; i < 100; i++) {
127       ASSERT_EQ(0x23, ptr[i]);
128     }
129     memset(ptr, 0x45, 200);
131     ptr = (char*)realloc(ptr, 300);
132     ASSERT_TRUE(ptr != NULL);
133     ASSERT_LE(300U, malloc_usable_size(ptr));
134     for (size_t i = 0; i < 200; i++) {
135       ASSERT_EQ(0x45, ptr[i]);
136     }
137     memset(ptr, 0x67, 300);
139     ptr = (char*)realloc(ptr, 250);
140     ASSERT_TRUE(ptr != NULL);
141     ASSERT_LE(250U, malloc_usable_size(ptr));
142     for (size_t i = 0; i < 250; i++) {
143       ASSERT_EQ(0x67, ptr[i]);
144     }
145     free(ptr);
146   }
149 TEST(malloc, malloc_realloc_larger) {
150   // Realloc to a larger size, malloc is used for the original allocation.
151   char *ptr = (char *)malloc(100);
152   ASSERT_TRUE(ptr != NULL);
153   ASSERT_LE(100U, malloc_usable_size(ptr));
154   memset(ptr, 67, 100);
156   ptr = (char *)realloc(ptr, 200);
157   ASSERT_TRUE(ptr != NULL);
158   ASSERT_LE(200U, malloc_usable_size(ptr));
159   for (size_t i = 0; i < 100; i++) {
160     ASSERT_EQ(67, ptr[i]);
161   }
162   free(ptr);
165 TEST(malloc, malloc_realloc_smaller) {
166   // Realloc to a smaller size, malloc is used for the original allocation.
167   char *ptr = (char *)malloc(200);
168   ASSERT_TRUE(ptr != NULL);
169   ASSERT_LE(200U, malloc_usable_size(ptr));
170   memset(ptr, 67, 200);
172   ptr = (char *)realloc(ptr, 100);
173   ASSERT_TRUE(ptr != NULL);
174   ASSERT_LE(100U, malloc_usable_size(ptr));
175   for (size_t i = 0; i < 100; i++) {
176     ASSERT_EQ(67, ptr[i]);
177   }
178   free(ptr);
181 TEST(malloc, malloc_multiple_realloc) {
182   // Multiple reallocs, malloc is used for the original allocation.
183   char *ptr = (char *)malloc(200);
184   ASSERT_TRUE(ptr != NULL);
185   ASSERT_LE(200U, malloc_usable_size(ptr));
186   memset(ptr, 0x23, 200);
188   ptr = (char *)realloc(ptr, 100);
189   ASSERT_TRUE(ptr != NULL);
190   ASSERT_LE(100U, malloc_usable_size(ptr));
191   for (size_t i = 0; i < 100; i++) {
192     ASSERT_EQ(0x23, ptr[i]);
193   }
195   ptr = (char*)realloc(ptr, 50);
196   ASSERT_TRUE(ptr != NULL);
197   ASSERT_LE(50U, malloc_usable_size(ptr));
198   for (size_t i = 0; i < 50; i++) {
199     ASSERT_EQ(0x23, ptr[i]);
200   }
202   ptr = (char*)realloc(ptr, 150);
203   ASSERT_TRUE(ptr != NULL);
204   ASSERT_LE(150U, malloc_usable_size(ptr));
205   for (size_t i = 0; i < 50; i++) {
206     ASSERT_EQ(0x23, ptr[i]);
207   }
208   memset(ptr, 0x23, 150);
210   ptr = (char*)realloc(ptr, 425);
211   ASSERT_TRUE(ptr != NULL);
212   ASSERT_LE(425U, malloc_usable_size(ptr));
213   for (size_t i = 0; i < 150; i++) {
214     ASSERT_EQ(0x23, ptr[i]);
215   }
216   free(ptr);
219 TEST(malloc, calloc_realloc_larger) {
220   // Realloc to a larger size, calloc is used for the original allocation.
221   char *ptr = (char *)calloc(1, 100);
222   ASSERT_TRUE(ptr != NULL);
223   ASSERT_LE(100U, malloc_usable_size(ptr));
225   ptr = (char *)realloc(ptr, 200);
226   ASSERT_TRUE(ptr != NULL);
227   ASSERT_LE(200U, malloc_usable_size(ptr));
228   for (size_t i = 0; i < 100; i++) {
229     ASSERT_EQ(0, ptr[i]);
230   }
231   free(ptr);
234 TEST(malloc, calloc_realloc_smaller) {
235   // Realloc to a smaller size, calloc is used for the original allocation.
236   char *ptr = (char *)calloc(1, 200);
237   ASSERT_TRUE(ptr != NULL);
238   ASSERT_LE(200U, malloc_usable_size(ptr));
240   ptr = (char *)realloc(ptr, 100);
241   ASSERT_TRUE(ptr != NULL);
242   ASSERT_LE(100U, malloc_usable_size(ptr));
243   for (size_t i = 0; i < 100; i++) {
244     ASSERT_EQ(0, ptr[i]);
245   }
246   free(ptr);
249 TEST(malloc, calloc_multiple_realloc) {
250   // Multiple reallocs, calloc is used for the original allocation.
251   char *ptr = (char *)calloc(1, 200);
252   ASSERT_TRUE(ptr != NULL);
253   ASSERT_LE(200U, malloc_usable_size(ptr));
255   ptr = (char *)realloc(ptr, 100);
256   ASSERT_TRUE(ptr != NULL);
257   ASSERT_LE(100U, malloc_usable_size(ptr));
258   for (size_t i = 0; i < 100; i++) {
259     ASSERT_EQ(0, ptr[i]);
260   }
262   ptr = (char*)realloc(ptr, 50);
263   ASSERT_TRUE(ptr != NULL);
264   ASSERT_LE(50U, malloc_usable_size(ptr));
265   for (size_t i = 0; i < 50; i++) {
266     ASSERT_EQ(0, ptr[i]);
267   }
269   ptr = (char*)realloc(ptr, 150);
270   ASSERT_TRUE(ptr != NULL);
271   ASSERT_LE(150U, malloc_usable_size(ptr));
272   for (size_t i = 0; i < 50; i++) {
273     ASSERT_EQ(0, ptr[i]);
274   }
275   memset(ptr, 0, 150);
277   ptr = (char*)realloc(ptr, 425);
278   ASSERT_TRUE(ptr != NULL);
279   ASSERT_LE(425U, malloc_usable_size(ptr));
280   for (size_t i = 0; i < 150; i++) {
281     ASSERT_EQ(0, ptr[i]);
282   }
283   free(ptr);
286 TEST(malloc, realloc_overflow) {
287   errno = 0;
288   ASSERT_EQ(NULL, realloc(NULL, SIZE_MAX));
289   ASSERT_EQ(ENOMEM, errno);
290   void* ptr = malloc(100);
291   ASSERT_TRUE(ptr != NULL);
292   errno = 0;
293   ASSERT_EQ(NULL, realloc(ptr, SIZE_MAX));
294   ASSERT_EQ(ENOMEM, errno);
295   free(ptr);
298 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
299 extern "C" void* pvalloc(size_t);
300 extern "C" void* valloc(size_t);
302 TEST(malloc, pvalloc_std) {
303   size_t pagesize = sysconf(_SC_PAGESIZE);
304   void* ptr = pvalloc(100);
305   ASSERT_TRUE(ptr != NULL);
306   ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0);
307   ASSERT_LE(pagesize, malloc_usable_size(ptr));
308   free(ptr);
311 TEST(malloc, pvalloc_overflow) {
312   ASSERT_EQ(NULL, pvalloc(SIZE_MAX));
315 TEST(malloc, valloc_std) {
316   size_t pagesize = sysconf(_SC_PAGESIZE);
317   void* ptr = pvalloc(100);
318   ASSERT_TRUE(ptr != NULL);
319   ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0);
320   free(ptr);
323 TEST(malloc, valloc_overflow) {
324   ASSERT_EQ(NULL, valloc(SIZE_MAX));
326 #endif
328 TEST(malloc, malloc_info) {
329 #ifdef __BIONIC__
330   char* buf;
331   size_t bufsize;
332   FILE* memstream = open_memstream(&buf, &bufsize);
333   ASSERT_NE(nullptr, memstream);
334   ASSERT_EQ(0, malloc_info(0, memstream));
335   ASSERT_EQ(0, fclose(memstream));
337   tinyxml2::XMLDocument doc;
338   ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(buf));
340   auto root = doc.FirstChildElement();
341   ASSERT_NE(nullptr, root);
342   ASSERT_STREQ("malloc", root->Name());
343   ASSERT_STREQ("jemalloc-1", root->Attribute("version"));
345   auto arena = root->FirstChildElement();
346   for (; arena != nullptr; arena = arena->NextSiblingElement()) {
347     int val;
349     ASSERT_STREQ("heap", arena->Name());
350     ASSERT_EQ(tinyxml2::XML_SUCCESS, arena->QueryIntAttribute("nr", &val));
351     ASSERT_EQ(tinyxml2::XML_SUCCESS,
352               arena->FirstChildElement("allocated-large")->QueryIntText(&val));
353     ASSERT_EQ(tinyxml2::XML_SUCCESS,
354               arena->FirstChildElement("allocated-huge")->QueryIntText(&val));
355     ASSERT_EQ(tinyxml2::XML_SUCCESS,
356               arena->FirstChildElement("allocated-bins")->QueryIntText(&val));
357     ASSERT_EQ(tinyxml2::XML_SUCCESS,
358               arena->FirstChildElement("bins-total")->QueryIntText(&val));
360     auto bin = arena->FirstChildElement("bin");
361     for (; bin != nullptr; bin = bin ->NextSiblingElement()) {
362       if (strcmp(bin->Name(), "bin") == 0) {
363         ASSERT_EQ(tinyxml2::XML_SUCCESS, bin->QueryIntAttribute("nr", &val));
364         ASSERT_EQ(tinyxml2::XML_SUCCESS,
365                   bin->FirstChildElement("allocated")->QueryIntText(&val));
366         ASSERT_EQ(tinyxml2::XML_SUCCESS,
367                   bin->FirstChildElement("nmalloc")->QueryIntText(&val));
368         ASSERT_EQ(tinyxml2::XML_SUCCESS,
369                   bin->FirstChildElement("ndalloc")->QueryIntText(&val));
370       }
371     }
372   }
373 #endif