summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libc/stdlib/malloc.344
-rw-r--r--src/lib/libc/stdlib/malloc.c67
2 files changed, 38 insertions, 73 deletions
diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3
index b9d62d04d0..8da3a299e1 100644
--- a/src/lib/libc/stdlib/malloc.3
+++ b/src/lib/libc/stdlib/malloc.3
@@ -30,9 +30,9 @@
30.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31.\" SUCH DAMAGE. 31.\" SUCH DAMAGE.
32.\" 32.\"
33.\" $OpenBSD: malloc.3,v 1.54 2008/08/07 18:41:47 otto Exp $ 33.\" $OpenBSD: malloc.3,v 1.55 2008/11/02 08:50:41 otto Exp $
34.\" 34.\"
35.Dd $Mdocdate: August 7 2008 $ 35.Dd $Mdocdate: November 2 2008 $
36.Dt MALLOC 3 36.Dt MALLOC 3
37.Os 37.Os
38.Sh NAME 38.Sh NAME
@@ -215,9 +215,11 @@ Flags are single letters, uppercase means on, lowercase means off.
215.It Cm A 215.It Cm A
216.Dq Abort . 216.Dq Abort .
217.Fn malloc 217.Fn malloc
218will coredump the process, rather than tolerate failure. 218will coredump the process, rather than tolerate internal
219This is a very handy debugging aid, since the core file will represent the 219inconsistencies or incorrect usage.
220time of failure, rather than when the null pointer was accessed. 220This is the default and a very handy debugging aid,
221since the core file represents the time of failure,
222rather than when the bogus pointer was used.
221.It Cm D 223.It Cm D
222.Dq Dump . 224.Dq Dump .
223.Fn malloc 225.Fn malloc
@@ -248,9 +250,6 @@ Currently junk is bytes of 0xd0 when allocating; this is pronounced
248.Dq Duh . 250.Dq Duh .
249\&:-) 251\&:-)
250Freed chunks are filled with 0xdf. 252Freed chunks are filled with 0xdf.
251.It Cm N
252Do not output warning messages when encountering possible corruption
253or bad pointers.
254.It Cm P 253.It Cm P
255.Dq Move allocations within a page. 254.Dq Move allocations within a page.
256Allocations larger than half a page but smaller that a page 255Allocations larger than half a page but smaller that a page
@@ -297,7 +296,7 @@ Increase the size of the free page cache by a factor of two.
297.El 296.El
298.Pp 297.Pp
299So to set a systemwide reduction of cache size and coredumps on problems: 298So to set a systemwide reduction of cache size and coredumps on problems:
300.Li ln -s 'A<' /etc/malloc.conf 299.Li ln -s 'G<' /etc/malloc.conf
301.Pp 300.Pp
302The 301The
303.Cm J 302.Cm J
@@ -349,22 +348,19 @@ If
349.Fn realloc , 348.Fn realloc ,
350or 349or
351.Fn free 350.Fn free
352detect an error or warning condition, 351detect an error condition,
353a message will be printed to file descriptor 352a message will be printed to file descriptor
3542 (not using stdio). 3532 (not using stdio).
355Errors will always result in the process being 354Errors will result in the process being aborted,
356.Xr abort 3 'ed. 355unless the
357If the 356.Cm a
358.Cm A 357option has been specified.
359option has been specified, warnings will also
360.Xr abort 3
361the process.
362.Pp 358.Pp
363Here is a brief description of the error messages and what they mean: 359Here is a brief description of the error messages and what they mean:
364.Bl -tag -width Ds 360.Bl -tag -width Ds
365.It Dq out of memory 361.It Dq out of memory
366If the 362If the
367.Cm A 363.Cm X
368option is specified it is an error for 364option is specified it is an error for
369.Fn malloc , 365.Fn malloc ,
370.Fn calloc , 366.Fn calloc ,
@@ -375,14 +371,6 @@ to return
375.It Dq malloc init mmap failed 371.It Dq malloc init mmap failed
376This is a rather weird condition that is most likely to indicate a 372This is a rather weird condition that is most likely to indicate a
377seriously overloaded system or a ulimit restriction. 373seriously overloaded system or a ulimit restriction.
378.It any other error
379.Fn malloc
380detected an internal error;
381consult sources and/or wizards.
382.El
383.Pp
384Here is a brief description of the warning messages and what they mean:
385.Bl -tag -width Ds
386.It Dq bogus pointer (double free?) 374.It Dq bogus pointer (double free?)
387An attempt to 375An attempt to
388.Fn free 376.Fn free
@@ -418,6 +406,10 @@ The internal malloc page cache has been corrupted.
418The internal malloc page cache has been corrupted. 406The internal malloc page cache has been corrupted.
419.It Dq guard size 407.It Dq guard size
420An inconsistent guard size was detected. 408An inconsistent guard size was detected.
409.It any other error
410.Fn malloc
411detected an internal error;
412consult sources and/or wizards.
421.El 413.El
422.Sh SEE ALSO 414.Sh SEE ALSO
423.Xr brk 2 , 415.Xr brk 2 ,
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index 603cc55f18..0af2e2fdea 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.104 2008/10/29 14:05:15 otto Exp $ */ 1/* $OpenBSD: malloc.c,v 1.105 2008/11/02 08:50:41 otto Exp $ */
2/* 2/*
3 * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> 3 * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
4 * 4 *
@@ -149,7 +149,6 @@ static int malloc_hint; /* call madvice on free pages? */
149static int malloc_junk; /* junk fill? */ 149static int malloc_junk; /* junk fill? */
150static int malloc_move; /* move allocations to end of page? */ 150static int malloc_move; /* move allocations to end of page? */
151static int malloc_realloc; /* always realloc? */ 151static int malloc_realloc; /* always realloc? */
152static int malloc_silent; /* avoid outputting warnings? */
153static int malloc_xmalloc; /* xmalloc behaviour? */ 152static int malloc_xmalloc; /* xmalloc behaviour? */
154static int malloc_zero; /* zero fill? */ 153static int malloc_zero; /* zero fill? */
155static size_t malloc_guard; /* use guard pages after allocations? */ 154static size_t malloc_guard; /* use guard pages after allocations? */
@@ -355,31 +354,6 @@ wrterror(char *p)
355 abort(); 354 abort();
356} 355}
357 356
358static void
359wrtwarning(char *p)
360{
361 char *q = " warning: ";
362 struct iovec iov[5];
363
364 if (malloc_abort)
365 wrterror(p);
366 else if (malloc_silent)
367 return;
368
369 iov[0].iov_base = __progname;
370 iov[0].iov_len = strlen(__progname);
371 iov[1].iov_base = malloc_func;
372 iov[1].iov_len = strlen(malloc_func);
373 iov[2].iov_base = q;
374 iov[2].iov_len = strlen(q);
375 iov[3].iov_base = p;
376 iov[3].iov_len = strlen(p);
377 iov[4].iov_base = "\n";
378 iov[4].iov_len = 1;
379
380 writev(STDERR_FILENO, iov, 5);
381}
382
383/* 357/*
384 * Cache maintenance. We keep at most malloc_cache pages cached. 358 * Cache maintenance. We keep at most malloc_cache pages cached.
385 * If the cache is becoming full, unmap pages in the cache for real, 359 * If the cache is becoming full, unmap pages in the cache for real,
@@ -428,7 +402,7 @@ unmap(struct dir_info *d, void *p, size_t sz)
428 } 402 }
429 } 403 }
430 if (tounmap > 0) 404 if (tounmap > 0)
431 wrtwarning("malloc cache underflow"); 405 wrterror("malloc cache underflow");
432 for (i = 0; i < malloc_cache; i++) { 406 for (i = 0; i < malloc_cache; i++) {
433 r = &d->free_regions[i]; 407 r = &d->free_regions[i];
434 if (r->p == NULL) { 408 if (r->p == NULL) {
@@ -443,9 +417,9 @@ unmap(struct dir_info *d, void *p, size_t sz)
443 } 417 }
444 } 418 }
445 if (i == malloc_cache) 419 if (i == malloc_cache)
446 wrtwarning("malloc free slot lost"); 420 wrterror("malloc free slot lost");
447 if (d->free_regions_size > malloc_cache) 421 if (d->free_regions_size > malloc_cache)
448 wrtwarning("malloc cache overflow"); 422 wrterror("malloc cache overflow");
449} 423}
450 424
451static void 425static void
@@ -525,7 +499,7 @@ map(struct dir_info *d, size_t sz, int zero_fill)
525 if (p != MAP_FAILED) 499 if (p != MAP_FAILED)
526 malloc_used += sz; 500 malloc_used += sz;
527 if (d->free_regions_size > malloc_cache) 501 if (d->free_regions_size > malloc_cache)
528 wrtwarning("malloc cache"); 502 wrterror("malloc cache");
529 /* zero fill not needed */ 503 /* zero fill not needed */
530 return p; 504 return p;
531} 505}
@@ -628,10 +602,7 @@ omalloc_init(struct dir_info *d)
628 malloc_junk = 1; 602 malloc_junk = 1;
629 break; 603 break;
630 case 'n': 604 case 'n':
631 malloc_silent = 0;
632 break;
633 case 'N': 605 case 'N':
634 malloc_silent = 1;
635 break; 606 break;
636 case 'p': 607 case 'p':
637 malloc_move = 0; 608 malloc_move = 0;
@@ -660,7 +631,7 @@ omalloc_init(struct dir_info *d)
660 default: 631 default:
661 j = malloc_abort; 632 j = malloc_abort;
662 malloc_abort = 0; 633 malloc_abort = 0;
663 wrtwarning("unknown char in MALLOC_OPTIONS"); 634 wrterror("unknown char in MALLOC_OPTIONS");
664 malloc_abort = j; 635 malloc_abort = j;
665 break; 636 break;
666 } 637 }
@@ -675,9 +646,11 @@ omalloc_init(struct dir_info *d)
675 malloc_junk = 1; 646 malloc_junk = 1;
676 647
677#ifdef MALLOC_STATS 648#ifdef MALLOC_STATS
678 if (malloc_stats && (atexit(malloc_exit) == -1)) 649 if (malloc_stats && (atexit(malloc_exit) == -1)) {
679 wrtwarning("atexit(2) failed." 650 char *q = "malloc() warning: atexit(2) failed."
680 " Will not be able to dump malloc stats on exit"); 651 " Will not be able to dump stats on exit\n";
652 write(STDERR_FILENO, q, strlen(q));
653 }
681#endif /* MALLOC_STATS */ 654#endif /* MALLOC_STATS */
682 655
683 d->regions_bits = 9; 656 d->regions_bits = 9;
@@ -1024,11 +997,11 @@ free_bytes(struct dir_info *d, struct region_info *r, void *ptr)
1024 i = ((uintptr_t)ptr & MALLOC_PAGEMASK) >> info->shift; 997 i = ((uintptr_t)ptr & MALLOC_PAGEMASK) >> info->shift;
1025 998
1026 if ((uintptr_t)ptr & ((1UL << (info->shift)) - 1)) { 999 if ((uintptr_t)ptr & ((1UL << (info->shift)) - 1)) {
1027 wrtwarning("modified chunk-pointer"); 1000 wrterror("modified chunk-pointer");
1028 return; 1001 return;
1029 } 1002 }
1030 if (info->bits[i / MALLOC_BITS] & (1UL << (i % MALLOC_BITS))) { 1003 if (info->bits[i / MALLOC_BITS] & (1UL << (i % MALLOC_BITS))) {
1031 wrtwarning("chunk is already free"); 1004 wrterror("chunk is already free");
1032 return; 1005 return;
1033 } 1006 }
1034 1007
@@ -1149,7 +1122,7 @@ malloc_recurse(void)
1149 1122
1150 if (noprint == 0) { 1123 if (noprint == 0) {
1151 noprint = 1; 1124 noprint = 1;
1152 wrtwarning("recursive call"); 1125 wrterror("recursive call");
1153 } 1126 }
1154 malloc_active--; 1127 malloc_active--;
1155 _MALLOC_UNLOCK(); 1128 _MALLOC_UNLOCK();
@@ -1197,14 +1170,14 @@ ofree(void *p)
1197 1170
1198 r = find(&g_pool, p); 1171 r = find(&g_pool, p);
1199 if (r == NULL) { 1172 if (r == NULL) {
1200 wrtwarning("bogus pointer (double free?)"); 1173 wrterror("bogus pointer (double free?)");
1201 return; 1174 return;
1202 } 1175 }
1203 REALSIZE(sz, r); 1176 REALSIZE(sz, r);
1204 if (sz > MALLOC_MAXCHUNK) { 1177 if (sz > MALLOC_MAXCHUNK) {
1205 if (sz - malloc_guard >= MALLOC_PAGESIZE - MALLOC_MINSIZE) { 1178 if (sz - malloc_guard >= MALLOC_PAGESIZE - MALLOC_MINSIZE) {
1206 if (r->p != p) 1179 if (r->p != p)
1207 wrtwarning("bogus pointer"); 1180 wrterror("bogus pointer");
1208 } else { 1181 } else {
1209#if notyetbecause_of_realloc 1182#if notyetbecause_of_realloc
1210 /* shifted towards the end */ 1183 /* shifted towards the end */
@@ -1217,7 +1190,7 @@ ofree(void *p)
1217 } 1190 }
1218 if (malloc_guard) { 1191 if (malloc_guard) {
1219 if (sz < malloc_guard) 1192 if (sz < malloc_guard)
1220 wrtwarning("guard size"); 1193 wrterror("guard size");
1221 if (!malloc_freeprot) { 1194 if (!malloc_freeprot) {
1222 if (mprotect((char *)p + PAGEROUND(sz) - 1195 if (mprotect((char *)p + PAGEROUND(sz) -
1223 malloc_guard, malloc_guard, 1196 malloc_guard, malloc_guard,
@@ -1243,7 +1216,7 @@ ofree(void *p)
1243 if (p != NULL) { 1216 if (p != NULL) {
1244 r = find(&g_pool, p); 1217 r = find(&g_pool, p);
1245 if (r == NULL) { 1218 if (r == NULL) {
1246 wrtwarning("bogus pointer (double free?)"); 1219 wrterror("bogus pointer (double free?)");
1247 return; 1220 return;
1248 } 1221 }
1249 free_bytes(&g_pool, r, p); 1222 free_bytes(&g_pool, r, p);
@@ -1285,7 +1258,7 @@ orealloc(void *p, size_t newsz)
1285 1258
1286 r = find(&g_pool, p); 1259 r = find(&g_pool, p);
1287 if (r == NULL) { 1260 if (r == NULL) {
1288 wrtwarning("bogus pointer (double free?)"); 1261 wrterror("bogus pointer (double free?)");
1289 return NULL; 1262 return NULL;
1290 } 1263 }
1291 if (newsz >= SIZE_MAX - malloc_guard - MALLOC_PAGESIZE) { 1264 if (newsz >= SIZE_MAX - malloc_guard - MALLOC_PAGESIZE) {
@@ -1297,7 +1270,7 @@ orealloc(void *p, size_t newsz)
1297 goldsz = oldsz; 1270 goldsz = oldsz;
1298 if (oldsz > MALLOC_MAXCHUNK) { 1271 if (oldsz > MALLOC_MAXCHUNK) {
1299 if (oldsz < malloc_guard) 1272 if (oldsz < malloc_guard)
1300 wrtwarning("guard size"); 1273 wrterror("guard size");
1301 oldsz -= malloc_guard; 1274 oldsz -= malloc_guard;
1302 } 1275 }
1303 1276