Browse Source

remove distinction between warnings and errors, ok deraadt@ djm@

OPENBSD_4_5
otto 15 years ago
parent
commit
96f3e731f5
2 changed files with 38 additions and 73 deletions
  1. +18
    -26
      src/lib/libc/stdlib/malloc.3
  2. +20
    -47
      src/lib/libc/stdlib/malloc.c

+ 18
- 26
src/lib/libc/stdlib/malloc.3 View File

@ -30,9 +30,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $OpenBSD: malloc.3,v 1.54 2008/08/07 18:41:47 otto Exp $
.\" $OpenBSD: malloc.3,v 1.55 2008/11/02 08:50:41 otto Exp $
.\"
.Dd $Mdocdate: August 7 2008 $
.Dd $Mdocdate: November 2 2008 $
.Dt MALLOC 3
.Os
.Sh NAME
@ -215,9 +215,11 @@ Flags are single letters, uppercase means on, lowercase means off.
.It Cm A
.Dq Abort .
.Fn malloc
will coredump the process, rather than tolerate failure.
This is a very handy debugging aid, since the core file will represent the
time of failure, rather than when the null pointer was accessed.
will coredump the process, rather than tolerate internal
inconsistencies or incorrect usage.
This is the default and a very handy debugging aid,
since the core file represents the time of failure,
rather than when the bogus pointer was used.
.It Cm D
.Dq Dump .
.Fn malloc
@ -248,9 +250,6 @@ Currently junk is bytes of 0xd0 when allocating; this is pronounced
.Dq Duh .
\&:-)
Freed chunks are filled with 0xdf.
.It Cm N
Do not output warning messages when encountering possible corruption
or bad pointers.
.It Cm P
.Dq Move allocations within a page.
Allocations 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.
.El
.Pp
So to set a systemwide reduction of cache size and coredumps on problems:
.Li ln -s 'A<' /etc/malloc.conf
.Li ln -s 'G<' /etc/malloc.conf
.Pp
The
.Cm J
@ -349,22 +348,19 @@ If
.Fn realloc ,
or
.Fn free
detect an error or warning condition,
detect an error condition,
a message will be printed to file descriptor
2 (not using stdio).
Errors will always result in the process being
.Xr abort 3 'ed.
If the
.Cm A
option has been specified, warnings will also
.Xr abort 3
the process.
Errors will result in the process being aborted,
unless the
.Cm a
option has been specified.
.Pp
Here is a brief description of the error messages and what they mean:
.Bl -tag -width Ds
.It Dq out of memory
If the
.Cm A
.Cm X
option is specified it is an error for
.Fn malloc ,
.Fn calloc ,
@ -375,14 +371,6 @@ to return
.It Dq malloc init mmap failed
This is a rather weird condition that is most likely to indicate a
seriously overloaded system or a ulimit restriction.
.It any other error
.Fn malloc
detected an internal error;
consult sources and/or wizards.
.El
.Pp
Here is a brief description of the warning messages and what they mean:
.Bl -tag -width Ds
.It Dq bogus pointer (double free?)
An attempt to
.Fn free
@ -418,6 +406,10 @@ The internal malloc page cache has been corrupted.
The internal malloc page cache has been corrupted.
.It Dq guard size
An inconsistent guard size was detected.
.It any other error
.Fn malloc
detected an internal error;
consult sources and/or wizards.
.El
.Sh SEE ALSO
.Xr brk 2 ,


+ 20
- 47
src/lib/libc/stdlib/malloc.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: malloc.c,v 1.104 2008/10/29 14:05:15 otto Exp $ */
/* $OpenBSD: malloc.c,v 1.105 2008/11/02 08:50:41 otto Exp $ */
/*
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
*
@ -149,7 +149,6 @@ static int malloc_hint; /* call madvice on free pages? */
static int malloc_junk; /* junk fill? */
static int malloc_move; /* move allocations to end of page? */
static int malloc_realloc; /* always realloc? */
static int malloc_silent; /* avoid outputting warnings? */
static int malloc_xmalloc; /* xmalloc behaviour? */
static int malloc_zero; /* zero fill? */
static size_t malloc_guard; /* use guard pages after allocations? */
@ -355,31 +354,6 @@ wrterror(char *p)
abort();
}
static void
wrtwarning(char *p)
{
char *q = " warning: ";
struct iovec iov[5];
if (malloc_abort)
wrterror(p);
else if (malloc_silent)
return;
iov[0].iov_base = __progname;
iov[0].iov_len = strlen(__progname);
iov[1].iov_base = malloc_func;
iov[1].iov_len = strlen(malloc_func);
iov[2].iov_base = q;
iov[2].iov_len = strlen(q);
iov[3].iov_base = p;
iov[3].iov_len = strlen(p);
iov[4].iov_base = "\n";
iov[4].iov_len = 1;
writev(STDERR_FILENO, iov, 5);
}
/*
* Cache maintenance. We keep at most malloc_cache pages cached.
* 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)
}
}
if (tounmap > 0)
wrtwarning("malloc cache underflow");
wrterror("malloc cache underflow");
for (i = 0; i < malloc_cache; i++) {
r = &d->free_regions[i];
if (r->p == NULL) {
@ -443,9 +417,9 @@ unmap(struct dir_info *d, void *p, size_t sz)
}
}
if (i == malloc_cache)
wrtwarning("malloc free slot lost");
wrterror("malloc free slot lost");
if (d->free_regions_size > malloc_cache)
wrtwarning("malloc cache overflow");
wrterror("malloc cache overflow");
}
static void
@ -525,7 +499,7 @@ map(struct dir_info *d, size_t sz, int zero_fill)
if (p != MAP_FAILED)
malloc_used += sz;
if (d->free_regions_size > malloc_cache)
wrtwarning("malloc cache");
wrterror("malloc cache");
/* zero fill not needed */
return p;
}
@ -628,10 +602,7 @@ omalloc_init(struct dir_info *d)
malloc_junk = 1;
break;
case 'n':
malloc_silent = 0;
break;
case 'N':
malloc_silent = 1;
break;
case 'p':
malloc_move = 0;
@ -660,7 +631,7 @@ omalloc_init(struct dir_info *d)
default:
j = malloc_abort;
malloc_abort = 0;
wrtwarning("unknown char in MALLOC_OPTIONS");
wrterror("unknown char in MALLOC_OPTIONS");
malloc_abort = j;
break;
}
@ -675,9 +646,11 @@ omalloc_init(struct dir_info *d)
malloc_junk = 1;
#ifdef MALLOC_STATS
if (malloc_stats && (atexit(malloc_exit) == -1))
wrtwarning("atexit(2) failed."
" Will not be able to dump malloc stats on exit");
if (malloc_stats && (atexit(malloc_exit) == -1)) {
char *q = "malloc() warning: atexit(2) failed."
" Will not be able to dump stats on exit\n";
write(STDERR_FILENO, q, strlen(q));
}
#endif /* MALLOC_STATS */
d->regions_bits = 9;
@ -1024,11 +997,11 @@ free_bytes(struct dir_info *d, struct region_info *r, void *ptr)
i = ((uintptr_t)ptr & MALLOC_PAGEMASK) >> info->shift;
if ((uintptr_t)ptr & ((1UL << (info->shift)) - 1)) {
wrtwarning("modified chunk-pointer");
wrterror("modified chunk-pointer");
return;
}
if (info->bits[i / MALLOC_BITS] & (1UL << (i % MALLOC_BITS))) {
wrtwarning("chunk is already free");
wrterror("chunk is already free");
return;
}
@ -1149,7 +1122,7 @@ malloc_recurse(void)
if (noprint == 0) {
noprint = 1;
wrtwarning("recursive call");
wrterror("recursive call");
}
malloc_active--;
_MALLOC_UNLOCK();
@ -1197,14 +1170,14 @@ ofree(void *p)
r = find(&g_pool, p);
if (r == NULL) {
wrtwarning("bogus pointer (double free?)");
wrterror("bogus pointer (double free?)");
return;
}
REALSIZE(sz, r);
if (sz > MALLOC_MAXCHUNK) {
if (sz - malloc_guard >= MALLOC_PAGESIZE - MALLOC_MINSIZE) {
if (r->p != p)
wrtwarning("bogus pointer");
wrterror("bogus pointer");
} else {
#if notyetbecause_of_realloc
/* shifted towards the end */
@ -1217,7 +1190,7 @@ ofree(void *p)
}
if (malloc_guard) {
if (sz < malloc_guard)
wrtwarning("guard size");
wrterror("guard size");
if (!malloc_freeprot) {
if (mprotect((char *)p + PAGEROUND(sz) -
malloc_guard, malloc_guard,
@ -1243,7 +1216,7 @@ ofree(void *p)
if (p != NULL) {
r = find(&g_pool, p);
if (r == NULL) {
wrtwarning("bogus pointer (double free?)");
wrterror("bogus pointer (double free?)");
return;
}
free_bytes(&g_pool, r, p);
@ -1285,7 +1258,7 @@ orealloc(void *p, size_t newsz)
r = find(&g_pool, p);
if (r == NULL) {
wrtwarning("bogus pointer (double free?)");
wrterror("bogus pointer (double free?)");
return NULL;
}
if (newsz >= SIZE_MAX - malloc_guard - MALLOC_PAGESIZE) {
@ -1297,7 +1270,7 @@ orealloc(void *p, size_t newsz)
goldsz = oldsz;
if (oldsz > MALLOC_MAXCHUNK) {
if (oldsz < malloc_guard)
wrtwarning("guard size");
wrterror("guard size");
oldsz -= malloc_guard;
}


Loading…
Cancel
Save