diff options
author | otto <> | 2017-03-24 16:15:31 +0000 |
---|---|---|
committer | otto <> | 2017-03-24 16:15:31 +0000 |
commit | 3a16763c8564004e0dfb455abfd9170748794dbc (patch) | |
tree | f0b8a9d4f947cb5a6fdc8c1a93ea1cb57d1cc283 | |
parent | e1241ed83025168e532623e524bd473811278001 (diff) | |
download | openbsd-3a16763c8564004e0dfb455abfd9170748794dbc.tar.gz openbsd-3a16763c8564004e0dfb455abfd9170748794dbc.tar.bz2 openbsd-3a16763c8564004e0dfb455abfd9170748794dbc.zip |
move recallocarray to malloc.c and
- use internal meta-data to do more consistency checking (especially with
option C)
- use cheap free if possible
ok deraadt@
-rw-r--r-- | src/lib/libc/stdlib/Makefile.inc | 3 | ||||
-rw-r--r-- | src/lib/libc/stdlib/malloc.c | 223 |
2 files changed, 207 insertions, 19 deletions
diff --git a/src/lib/libc/stdlib/Makefile.inc b/src/lib/libc/stdlib/Makefile.inc index 36b5869adb..e754e09196 100644 --- a/src/lib/libc/stdlib/Makefile.inc +++ b/src/lib/libc/stdlib/Makefile.inc | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: Makefile.inc,v 1.62 2017/03/06 18:44:21 otto Exp $ | 1 | # $OpenBSD: Makefile.inc,v 1.63 2017/03/24 16:15:31 otto Exp $ |
2 | 2 | ||
3 | # stdlib sources | 3 | # stdlib sources |
4 | .PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/stdlib ${LIBCSRCDIR}/stdlib | 4 | .PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/stdlib ${LIBCSRCDIR}/stdlib |
@@ -7,7 +7,6 @@ SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \ | |||
7 | exit.c ecvt.c gcvt.c getenv.c getopt_long.c \ | 7 | exit.c ecvt.c gcvt.c getenv.c getopt_long.c \ |
8 | getsubopt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c insque.c \ | 8 | getsubopt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c insque.c \ |
9 | l64a.c llabs.c lldiv.c lsearch.c malloc.c reallocarray.c \ | 9 | l64a.c llabs.c lldiv.c lsearch.c malloc.c reallocarray.c \ |
10 | recallocarray.c \ | ||
11 | merge.c posix_pty.c qsort.c radixsort.c rand.c random.c \ | 10 | merge.c posix_pty.c qsort.c radixsort.c rand.c random.c \ |
12 | realpath.c remque.c setenv.c strtoimax.c \ | 11 | realpath.c remque.c setenv.c strtoimax.c \ |
13 | strtol.c strtoll.c strtonum.c strtoul.c strtoull.c strtoumax.c \ | 12 | strtol.c strtoll.c strtonum.c strtoul.c strtoull.c strtoumax.c \ |
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c index 0b071e6743..c67607e8fe 100644 --- a/src/lib/libc/stdlib/malloc.c +++ b/src/lib/libc/stdlib/malloc.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: malloc.c,v 1.215 2017/02/15 12:31:57 jsg Exp $ */ | 1 | /* $OpenBSD: malloc.c,v 1.216 2017/03/24 16:15:31 otto Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net> | 3 | * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net> |
4 | * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> | 4 | * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> |
@@ -185,6 +185,7 @@ struct malloc_readonly { | |||
185 | int malloc_realloc; /* always realloc? */ | 185 | int malloc_realloc; /* always realloc? */ |
186 | int malloc_xmalloc; /* xmalloc behaviour? */ | 186 | int malloc_xmalloc; /* xmalloc behaviour? */ |
187 | int chunk_canaries; /* use canaries after chunks? */ | 187 | int chunk_canaries; /* use canaries after chunks? */ |
188 | int internal_recallocarray; /* use better recallocarray? */ | ||
188 | u_int malloc_cache; /* free pages we cache */ | 189 | u_int malloc_cache; /* free pages we cache */ |
189 | size_t malloc_guard; /* use guard pages after allocations? */ | 190 | size_t malloc_guard; /* use guard pages after allocations? */ |
190 | #ifdef MALLOC_STATS | 191 | #ifdef MALLOC_STATS |
@@ -330,7 +331,7 @@ getrbyte(struct dir_info *d) | |||
330 | * cache are in MALLOC_PAGESIZE units. | 331 | * cache are in MALLOC_PAGESIZE units. |
331 | */ | 332 | */ |
332 | static void | 333 | static void |
333 | unmap(struct dir_info *d, void *p, size_t sz) | 334 | unmap(struct dir_info *d, void *p, size_t sz, int clear) |
334 | { | 335 | { |
335 | size_t psz = sz >> MALLOC_PAGESHIFT; | 336 | size_t psz = sz >> MALLOC_PAGESHIFT; |
336 | size_t rsz, tounmap; | 337 | size_t rsz, tounmap; |
@@ -373,6 +374,8 @@ unmap(struct dir_info *d, void *p, size_t sz) | |||
373 | for (i = 0; i < mopts.malloc_cache; i++) { | 374 | for (i = 0; i < mopts.malloc_cache; i++) { |
374 | r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)]; | 375 | r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)]; |
375 | if (r->p == NULL) { | 376 | if (r->p == NULL) { |
377 | if (clear) | ||
378 | memset(p, 0, sz - mopts.malloc_guard); | ||
376 | if (mopts.malloc_junk && !mopts.malloc_freeunmap) { | 379 | if (mopts.malloc_junk && !mopts.malloc_freeunmap) { |
377 | size_t amt = mopts.malloc_junk == 1 ? | 380 | size_t amt = mopts.malloc_junk == 1 ? |
378 | MALLOC_MAXCHUNK : sz; | 381 | MALLOC_MAXCHUNK : sz; |
@@ -863,7 +866,7 @@ omalloc_make_chunks(struct dir_info *d, int bits, int listnum) | |||
863 | 866 | ||
864 | bp = alloc_chunk_info(d, bits); | 867 | bp = alloc_chunk_info(d, bits); |
865 | if (bp == NULL) { | 868 | if (bp == NULL) { |
866 | unmap(d, pp, MALLOC_PAGESIZE); | 869 | unmap(d, pp, MALLOC_PAGESIZE, 0); |
867 | return NULL; | 870 | return NULL; |
868 | } | 871 | } |
869 | 872 | ||
@@ -879,7 +882,7 @@ omalloc_make_chunks(struct dir_info *d, int bits, int listnum) | |||
879 | 882 | ||
880 | k = mprotect(pp, MALLOC_PAGESIZE, PROT_NONE); | 883 | k = mprotect(pp, MALLOC_PAGESIZE, PROT_NONE); |
881 | if (k < 0) { | 884 | if (k < 0) { |
882 | unmap(d, pp, MALLOC_PAGESIZE); | 885 | unmap(d, pp, MALLOC_PAGESIZE, 0); |
883 | LIST_INSERT_HEAD(&d->chunk_info_list[0], bp, entries); | 886 | LIST_INSERT_HEAD(&d->chunk_info_list[0], bp, entries); |
884 | return NULL; | 887 | return NULL; |
885 | } | 888 | } |
@@ -1106,7 +1109,7 @@ free_bytes(struct dir_info *d, struct region_info *r, void *ptr) | |||
1106 | 1109 | ||
1107 | if (info->size == 0 && !mopts.malloc_freeunmap) | 1110 | if (info->size == 0 && !mopts.malloc_freeunmap) |
1108 | mprotect(info->page, MALLOC_PAGESIZE, PROT_READ | PROT_WRITE); | 1111 | mprotect(info->page, MALLOC_PAGESIZE, PROT_READ | PROT_WRITE); |
1109 | unmap(d, info->page, MALLOC_PAGESIZE); | 1112 | unmap(d, info->page, MALLOC_PAGESIZE, 0); |
1110 | 1113 | ||
1111 | delete(d, r); | 1114 | delete(d, r); |
1112 | if (info->size != 0) | 1115 | if (info->size != 0) |
@@ -1137,7 +1140,7 @@ omalloc(struct dir_info *pool, size_t sz, int zero_fill, void *f) | |||
1137 | return NULL; | 1140 | return NULL; |
1138 | } | 1141 | } |
1139 | if (insert(pool, p, sz, f)) { | 1142 | if (insert(pool, p, sz, f)) { |
1140 | unmap(pool, p, psz); | 1143 | unmap(pool, p, psz, 0); |
1141 | errno = ENOMEM; | 1144 | errno = ENOMEM; |
1142 | return NULL; | 1145 | return NULL; |
1143 | } | 1146 | } |
@@ -1228,6 +1231,8 @@ _malloc_init(int from_rthreads) | |||
1228 | 1231 | ||
1229 | if (from_rthreads) | 1232 | if (from_rthreads) |
1230 | mopts.malloc_mt = 1; | 1233 | mopts.malloc_mt = 1; |
1234 | else | ||
1235 | mopts.internal_recallocarray = 1; | ||
1231 | 1236 | ||
1232 | /* | 1237 | /* |
1233 | * Options have been set and will never be reset. | 1238 | * Options have been set and will never be reset. |
@@ -1290,7 +1295,7 @@ validate_junk(struct dir_info *pool, void *p) | |||
1290 | } | 1295 | } |
1291 | 1296 | ||
1292 | static void | 1297 | static void |
1293 | ofree(struct dir_info *argpool, void *p) | 1298 | ofree(struct dir_info *argpool, void *p, int clear) |
1294 | { | 1299 | { |
1295 | struct dir_info *pool; | 1300 | struct dir_info *pool; |
1296 | struct region_info *r; | 1301 | struct region_info *r; |
@@ -1344,7 +1349,7 @@ ofree(struct dir_info *argpool, void *p) | |||
1344 | } | 1349 | } |
1345 | STATS_SUB(pool->malloc_guarded, mopts.malloc_guard); | 1350 | STATS_SUB(pool->malloc_guarded, mopts.malloc_guard); |
1346 | } | 1351 | } |
1347 | unmap(pool, p, PAGEROUND(sz)); | 1352 | unmap(pool, p, PAGEROUND(sz), clear); |
1348 | delete(pool, r); | 1353 | delete(pool, r); |
1349 | } else { | 1354 | } else { |
1350 | void *tmp; | 1355 | void *tmp; |
@@ -1353,7 +1358,7 @@ ofree(struct dir_info *argpool, void *p) | |||
1353 | /* Delayed free or canaries? Extra check */ | 1358 | /* Delayed free or canaries? Extra check */ |
1354 | if (!mopts.malloc_freenow || mopts.chunk_canaries) | 1359 | if (!mopts.malloc_freenow || mopts.chunk_canaries) |
1355 | find_chunknum(pool, r, p, mopts.chunk_canaries); | 1360 | find_chunknum(pool, r, p, mopts.chunk_canaries); |
1356 | if (!mopts.malloc_freenow) { | 1361 | if (!clear && !mopts.malloc_freenow) { |
1357 | if (mopts.malloc_junk && sz > 0) | 1362 | if (mopts.malloc_junk && sz > 0) |
1358 | memset(p, SOME_FREEJUNK, sz); | 1363 | memset(p, SOME_FREEJUNK, sz); |
1359 | i = getrbyte(pool) & MALLOC_DELAYED_CHUNK_MASK; | 1364 | i = getrbyte(pool) & MALLOC_DELAYED_CHUNK_MASK; |
@@ -1365,8 +1370,8 @@ ofree(struct dir_info *argpool, void *p) | |||
1365 | validate_junk(pool, p); | 1370 | validate_junk(pool, p); |
1366 | pool->delayed_chunks[i] = tmp; | 1371 | pool->delayed_chunks[i] = tmp; |
1367 | } else { | 1372 | } else { |
1368 | if (mopts.malloc_junk && sz > 0) | 1373 | if ((clear || mopts.malloc_junk) && sz > 0) |
1369 | memset(p, SOME_FREEJUNK, sz); | 1374 | memset(p, clear ? 0 : SOME_FREEJUNK, sz); |
1370 | } | 1375 | } |
1371 | if (p != NULL) { | 1376 | if (p != NULL) { |
1372 | r = find(pool, p); | 1377 | r = find(pool, p); |
@@ -1404,7 +1409,7 @@ free(void *ptr) | |||
1404 | malloc_recurse(d); | 1409 | malloc_recurse(d); |
1405 | return; | 1410 | return; |
1406 | } | 1411 | } |
1407 | ofree(d, ptr); | 1412 | ofree(d, ptr, 0); |
1408 | d->active--; | 1413 | d->active--; |
1409 | _MALLOC_UNLOCK(d->mutex); | 1414 | _MALLOC_UNLOCK(d->mutex); |
1410 | errno = saved_errno; | 1415 | errno = saved_errno; |
@@ -1528,7 +1533,7 @@ gotit: | |||
1528 | PROT_NONE)) | 1533 | PROT_NONE)) |
1529 | wrterror(pool, "mprotect"); | 1534 | wrterror(pool, "mprotect"); |
1530 | } | 1535 | } |
1531 | unmap(pool, (char *)r->p + rnewsz, roldsz - rnewsz); | 1536 | unmap(pool, (char *)r->p + rnewsz, roldsz - rnewsz, 0); |
1532 | r->size = gnewsz; | 1537 | r->size = gnewsz; |
1533 | if (MALLOC_MOVE_COND(gnewsz)) { | 1538 | if (MALLOC_MOVE_COND(gnewsz)) { |
1534 | void *pp = MALLOC_MOVE(r->p, gnewsz); | 1539 | void *pp = MALLOC_MOVE(r->p, gnewsz); |
@@ -1584,7 +1589,7 @@ gotit: | |||
1584 | } | 1589 | } |
1585 | if (newsz != 0 && oldsz != 0) | 1590 | if (newsz != 0 && oldsz != 0) |
1586 | memcpy(q, p, oldsz < newsz ? oldsz : newsz); | 1591 | memcpy(q, p, oldsz < newsz ? oldsz : newsz); |
1587 | ofree(pool, p); | 1592 | ofree(pool, p, 0); |
1588 | ret = q; | 1593 | ret = q; |
1589 | } else { | 1594 | } else { |
1590 | /* oldsz == newsz */ | 1595 | /* oldsz == newsz */ |
@@ -1682,6 +1687,189 @@ calloc(size_t nmemb, size_t size) | |||
1682 | /*DEF_STRONG(calloc);*/ | 1687 | /*DEF_STRONG(calloc);*/ |
1683 | 1688 | ||
1684 | static void * | 1689 | static void * |
1690 | orecallocarray(struct dir_info *argpool, void *p, size_t oldsize, | ||
1691 | size_t newsize, void *f) | ||
1692 | { | ||
1693 | struct dir_info *pool; | ||
1694 | struct region_info *r; | ||
1695 | void *newptr; | ||
1696 | size_t sz; | ||
1697 | int i; | ||
1698 | |||
1699 | pool = argpool; | ||
1700 | |||
1701 | if (p == NULL) | ||
1702 | return omalloc(pool, newsize, 1, f); | ||
1703 | |||
1704 | r = find(pool, p); | ||
1705 | if (r == NULL) { | ||
1706 | if (mopts.malloc_mt) { | ||
1707 | for (i = 0; i < _MALLOC_MUTEXES; i++) { | ||
1708 | if (i == argpool->mutex) | ||
1709 | continue; | ||
1710 | pool->active--; | ||
1711 | _MALLOC_UNLOCK(pool->mutex); | ||
1712 | pool = mopts.malloc_pool[i]; | ||
1713 | _MALLOC_LOCK(pool->mutex); | ||
1714 | pool->active++; | ||
1715 | r = find(pool, p); | ||
1716 | if (r != NULL) | ||
1717 | break; | ||
1718 | } | ||
1719 | } | ||
1720 | if (r == NULL) | ||
1721 | wrterror(pool, "bogus pointer (double free?) %p", p); | ||
1722 | } | ||
1723 | |||
1724 | REALSIZE(sz, r); | ||
1725 | if (sz <= MALLOC_MAXCHUNK) { | ||
1726 | if (mopts.chunk_canaries) { | ||
1727 | struct chunk_info *info = (struct chunk_info *)r->size; | ||
1728 | uint32_t chunknum = find_chunknum(pool, r, p, 0); | ||
1729 | |||
1730 | if (info->bits[info->offset + chunknum] != oldsize) | ||
1731 | wrterror(pool, "recorded old size %hu != %zu", | ||
1732 | info->bits[info->offset + chunknum], | ||
1733 | oldsize); | ||
1734 | } | ||
1735 | } else if (oldsize != sz - mopts.malloc_guard) | ||
1736 | wrterror(pool, "recorded old size %zu != %zu", oldsize, | ||
1737 | sz - mopts.malloc_guard); | ||
1738 | |||
1739 | newptr = omalloc(pool, newsize, 0, f); | ||
1740 | if (newptr == NULL) | ||
1741 | goto done; | ||
1742 | |||
1743 | if (newsize > oldsize) { | ||
1744 | memcpy(newptr, p, oldsize); | ||
1745 | memset((char *)newptr + oldsize, 0, newsize - oldsize); | ||
1746 | } else | ||
1747 | memcpy(newptr, p, newsize); | ||
1748 | |||
1749 | ofree(pool, p, 1); | ||
1750 | |||
1751 | done: | ||
1752 | if (argpool != pool) { | ||
1753 | pool->active--; | ||
1754 | _MALLOC_UNLOCK(pool->mutex); | ||
1755 | _MALLOC_LOCK(argpool->mutex); | ||
1756 | argpool->active++; | ||
1757 | } | ||
1758 | |||
1759 | return newptr; | ||
1760 | } | ||
1761 | |||
1762 | static void * | ||
1763 | recallocarray_p(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size) | ||
1764 | { | ||
1765 | size_t oldsize, newsize; | ||
1766 | void *newptr; | ||
1767 | |||
1768 | if (ptr == NULL) | ||
1769 | return calloc(newnmemb, size); | ||
1770 | |||
1771 | if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && | ||
1772 | newnmemb > 0 && SIZE_MAX / newnmemb < size) { | ||
1773 | errno = ENOMEM; | ||
1774 | return NULL; | ||
1775 | } | ||
1776 | newsize = newnmemb * size; | ||
1777 | |||
1778 | if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && | ||
1779 | oldnmemb > 0 && SIZE_MAX / oldnmemb < size) { | ||
1780 | errno = EINVAL; | ||
1781 | return NULL; | ||
1782 | } | ||
1783 | oldsize = oldnmemb * size; | ||
1784 | |||
1785 | /* | ||
1786 | * Don't bother too much if we're shrinking just a bit, | ||
1787 | * we do not shrink for series of small steps, oh well. | ||
1788 | */ | ||
1789 | if (newsize <= oldsize) { | ||
1790 | size_t d = oldsize - newsize; | ||
1791 | |||
1792 | if (d < oldsize / 2 && d < getpagesize()) { | ||
1793 | memset((char *)ptr + newsize, 0, d); | ||
1794 | return ptr; | ||
1795 | } | ||
1796 | } | ||
1797 | |||
1798 | newptr = malloc(newsize); | ||
1799 | if (newptr == NULL) | ||
1800 | return NULL; | ||
1801 | |||
1802 | if (newsize > oldsize) { | ||
1803 | memcpy(newptr, ptr, oldsize); | ||
1804 | memset((char *)newptr + oldsize, 0, newsize - oldsize); | ||
1805 | } else | ||
1806 | memcpy(newptr, ptr, newsize); | ||
1807 | |||
1808 | explicit_bzero(ptr, oldsize); | ||
1809 | free(ptr); | ||
1810 | |||
1811 | return newptr; | ||
1812 | } | ||
1813 | |||
1814 | void * | ||
1815 | recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size) | ||
1816 | { | ||
1817 | struct dir_info *d; | ||
1818 | size_t oldsize = 0, newsize; | ||
1819 | void *r; | ||
1820 | int saved_errno = errno; | ||
1821 | |||
1822 | if (!mopts.internal_recallocarray) | ||
1823 | return recallocarray_p(ptr, oldnmemb, newnmemb, size); | ||
1824 | |||
1825 | d = getpool(); | ||
1826 | if (d == NULL) { | ||
1827 | _malloc_init(0); | ||
1828 | d = getpool(); | ||
1829 | } | ||
1830 | |||
1831 | _MALLOC_LOCK(d->mutex); | ||
1832 | d->func = "recallocarray"; | ||
1833 | |||
1834 | if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && | ||
1835 | newnmemb > 0 && SIZE_MAX / newnmemb < size) { | ||
1836 | _MALLOC_UNLOCK(d->mutex); | ||
1837 | if (mopts.malloc_xmalloc) | ||
1838 | wrterror(d, "out of memory"); | ||
1839 | errno = ENOMEM; | ||
1840 | return NULL; | ||
1841 | } | ||
1842 | newsize = newnmemb * size; | ||
1843 | |||
1844 | if (ptr != NULL) { | ||
1845 | if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && | ||
1846 | oldnmemb > 0 && SIZE_MAX / oldnmemb < size) { | ||
1847 | _MALLOC_UNLOCK(d->mutex); | ||
1848 | errno = EINVAL; | ||
1849 | return NULL; | ||
1850 | } | ||
1851 | oldsize = oldnmemb * size; | ||
1852 | } | ||
1853 | |||
1854 | if (d->active++) { | ||
1855 | malloc_recurse(d); | ||
1856 | return NULL; | ||
1857 | } | ||
1858 | |||
1859 | r = orecallocarray(d, ptr, oldsize, newsize, CALLER); | ||
1860 | |||
1861 | d->active--; | ||
1862 | _MALLOC_UNLOCK(d->mutex); | ||
1863 | if (r == NULL && mopts.malloc_xmalloc) | ||
1864 | wrterror(d, "out of memory"); | ||
1865 | if (r != NULL) | ||
1866 | errno = saved_errno; | ||
1867 | return r; | ||
1868 | } | ||
1869 | DEF_WEAK(recallocarray); | ||
1870 | |||
1871 | |||
1872 | static void * | ||
1685 | mapalign(struct dir_info *d, size_t alignment, size_t sz, int zero_fill) | 1873 | mapalign(struct dir_info *d, size_t alignment, size_t sz, int zero_fill) |
1686 | { | 1874 | { |
1687 | char *p, *q; | 1875 | char *p, *q; |
@@ -1746,7 +1934,7 @@ omemalign(struct dir_info *pool, size_t alignment, size_t sz, int zero_fill, voi | |||
1746 | } | 1934 | } |
1747 | 1935 | ||
1748 | if (insert(pool, p, sz, f)) { | 1936 | if (insert(pool, p, sz, f)) { |
1749 | unmap(pool, p, psz); | 1937 | unmap(pool, p, psz, 0); |
1750 | errno = ENOMEM; | 1938 | errno = ENOMEM; |
1751 | return NULL; | 1939 | return NULL; |
1752 | } | 1940 | } |
@@ -2069,8 +2257,9 @@ malloc_exit(void) | |||
2069 | __progname); | 2257 | __progname); |
2070 | write(fd, buf, strlen(buf)); | 2258 | write(fd, buf, strlen(buf)); |
2071 | snprintf(buf, sizeof(buf), | 2259 | snprintf(buf, sizeof(buf), |
2072 | "MT=%d F=%d U=%d J=%d R=%d X=%d C=%d cache=%u G=%zu\n", | 2260 | "MT=%d IRC=%d F=%d U=%d J=%d R=%d X=%d C=%d cache=%u G=%zu\n", |
2073 | mopts.malloc_mt, mopts.malloc_freenow, | 2261 | mopts.malloc_mt, mopts.internal_recallocarray, |
2262 | mopts.malloc_freenow, | ||
2074 | mopts.malloc_freeunmap, mopts.malloc_junk, | 2263 | mopts.malloc_freeunmap, mopts.malloc_junk, |
2075 | mopts.malloc_realloc, mopts.malloc_xmalloc, | 2264 | mopts.malloc_realloc, mopts.malloc_xmalloc, |
2076 | mopts.chunk_canaries, mopts.malloc_cache, | 2265 | mopts.chunk_canaries, mopts.malloc_cache, |