summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorotto <>2010-10-21 08:09:35 +0000
committerotto <>2010-10-21 08:09:35 +0000
commitbfe014bfc1f0c4f1f2fa0b62d6fe461095ffa933 (patch)
tree1ffe88508054f4a0a44fd38523c84a47dede1a68 /src/lib
parente3813d6d8526e5e3f8bfe5a9a780570befb27d5a (diff)
downloadopenbsd-bfe014bfc1f0c4f1f2fa0b62d6fe461095ffa933.tar.gz
openbsd-bfe014bfc1f0c4f1f2fa0b62d6fe461095ffa933.tar.bz2
openbsd-bfe014bfc1f0c4f1f2fa0b62d6fe461095ffa933.zip
print the pointer value that caused the error (if available); ok
deraadt@ nicm@ (on an earlier version)
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libc/stdlib/malloc.c101
1 files changed, 54 insertions, 47 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index 902b69c216..566e1e72e6 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.125 2010/05/18 22:24:55 tedu Exp $ */ 1/* $OpenBSD: malloc.c,v 1.126 2010/10/21 08:09:35 otto Exp $ */
2/* 2/*
3 * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> 3 * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
4 * 4 *
@@ -352,12 +352,12 @@ malloc_exit(void)
352#endif /* MALLOC_STATS */ 352#endif /* MALLOC_STATS */
353 353
354 354
355
356static void 355static void
357wrterror(char *p) 356wrterror(char *msg, void *p)
358{ 357{
359 char *q = " error: "; 358 char *q = " error: ";
360 struct iovec iov[5]; 359 struct iovec iov[6];
360 char buf[20];
361 361
362 iov[0].iov_base = __progname; 362 iov[0].iov_base = __progname;
363 iov[0].iov_len = strlen(__progname); 363 iov[0].iov_len = strlen(__progname);
@@ -365,11 +365,18 @@ wrterror(char *p)
365 iov[1].iov_len = strlen(malloc_func); 365 iov[1].iov_len = strlen(malloc_func);
366 iov[2].iov_base = q; 366 iov[2].iov_base = q;
367 iov[2].iov_len = strlen(q); 367 iov[2].iov_len = strlen(q);
368 iov[3].iov_base = p; 368 iov[3].iov_base = msg;
369 iov[3].iov_len = strlen(p); 369 iov[3].iov_len = strlen(msg);
370 iov[4].iov_base = "\n"; 370 iov[4].iov_base = buf;
371 iov[4].iov_len = 1; 371 if (p == NULL)
372 writev(STDERR_FILENO, iov, 5); 372 iov[4].iov_len = 0;
373 else {
374 snprintf(buf, sizeof(buf), " %p", p);
375 iov[4].iov_len = strlen(buf);
376 }
377 iov[5].iov_base = "\n";
378 iov[5].iov_len = 1;
379 writev(STDERR_FILENO, iov, 6);
373 380
374#ifdef MALLOC_STATS 381#ifdef MALLOC_STATS
375 if (mopts.malloc_stats) 382 if (mopts.malloc_stats)
@@ -414,13 +421,13 @@ unmap(struct dir_info *d, void *p, size_t sz)
414 u_int i, offset; 421 u_int i, offset;
415 422
416 if (sz != PAGEROUND(sz)) { 423 if (sz != PAGEROUND(sz)) {
417 wrterror("munmap round"); 424 wrterror("munmap round", NULL);
418 return; 425 return;
419 } 426 }
420 427
421 if (psz > mopts.malloc_cache) { 428 if (psz > mopts.malloc_cache) {
422 if (munmap(p, sz)) 429 if (munmap(p, sz))
423 wrterror("munmap"); 430 wrterror("munmap", p);
424 malloc_used -= sz; 431 malloc_used -= sz;
425 return; 432 return;
426 } 433 }
@@ -434,7 +441,7 @@ unmap(struct dir_info *d, void *p, size_t sz)
434 if (r->p != NULL) { 441 if (r->p != NULL) {
435 rsz = r->size << MALLOC_PAGESHIFT; 442 rsz = r->size << MALLOC_PAGESHIFT;
436 if (munmap(r->p, rsz)) 443 if (munmap(r->p, rsz))
437 wrterror("munmap"); 444 wrterror("munmap", r->p);
438 r->p = NULL; 445 r->p = NULL;
439 if (tounmap > r->size) 446 if (tounmap > r->size)
440 tounmap -= r->size; 447 tounmap -= r->size;
@@ -446,7 +453,7 @@ unmap(struct dir_info *d, void *p, size_t sz)
446 } 453 }
447 } 454 }
448 if (tounmap > 0) 455 if (tounmap > 0)
449 wrterror("malloc cache underflow"); 456 wrterror("malloc cache underflow", NULL);
450 for (i = 0; i < mopts.malloc_cache; i++) { 457 for (i = 0; i < mopts.malloc_cache; i++) {
451 r = &d->free_regions[i]; 458 r = &d->free_regions[i];
452 if (r->p == NULL) { 459 if (r->p == NULL) {
@@ -461,9 +468,9 @@ unmap(struct dir_info *d, void *p, size_t sz)
461 } 468 }
462 } 469 }
463 if (i == mopts.malloc_cache) 470 if (i == mopts.malloc_cache)
464 wrterror("malloc free slot lost"); 471 wrterror("malloc free slot lost", NULL);
465 if (d->free_regions_size > mopts.malloc_cache) 472 if (d->free_regions_size > mopts.malloc_cache)
466 wrterror("malloc cache overflow"); 473 wrterror("malloc cache overflow", NULL);
467} 474}
468 475
469static void 476static void
@@ -478,7 +485,7 @@ zapcacheregion(struct dir_info *d, void *p)
478 if (r->p == p) { 485 if (r->p == p) {
479 rsz = r->size << MALLOC_PAGESHIFT; 486 rsz = r->size << MALLOC_PAGESHIFT;
480 if (munmap(r->p, rsz)) 487 if (munmap(r->p, rsz))
481 wrterror("munmap"); 488 wrterror("munmap", r->p);
482 r->p = NULL; 489 r->p = NULL;
483 d->free_regions_size -= r->size; 490 d->free_regions_size -= r->size;
484 r->size = 0; 491 r->size = 0;
@@ -497,9 +504,9 @@ map(struct dir_info *d, size_t sz, int zero_fill)
497 504
498 if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) || 505 if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) ||
499 d->canary1 != ~d->canary2) 506 d->canary1 != ~d->canary2)
500 wrterror("internal struct corrupt"); 507 wrterror("internal struct corrupt", NULL);
501 if (sz != PAGEROUND(sz)) { 508 if (sz != PAGEROUND(sz)) {
502 wrterror("map round"); 509 wrterror("map round", NULL);
503 return NULL; 510 return NULL;
504 } 511 }
505 if (psz > d->free_regions_size) { 512 if (psz > d->free_regions_size) {
@@ -551,7 +558,7 @@ map(struct dir_info *d, size_t sz, int zero_fill)
551 if (p != MAP_FAILED) 558 if (p != MAP_FAILED)
552 malloc_used += sz; 559 malloc_used += sz;
553 if (d->free_regions_size > mopts.malloc_cache) 560 if (d->free_regions_size > mopts.malloc_cache)
554 wrterror("malloc cache"); 561 wrterror("malloc cache", NULL);
555 /* zero fill not needed */ 562 /* zero fill not needed */
556 return p; 563 return p;
557} 564}
@@ -724,7 +731,7 @@ omalloc_init(struct dir_info **dp)
724 regioninfo_size = d->regions_total * sizeof(struct region_info); 731 regioninfo_size = d->regions_total * sizeof(struct region_info);
725 d->r = MMAP(regioninfo_size); 732 d->r = MMAP(regioninfo_size);
726 if (d->r == MAP_FAILED) { 733 if (d->r == MAP_FAILED) {
727 wrterror("malloc init mmap failed"); 734 wrterror("malloc init mmap failed", NULL);
728 d->regions_total = 0; 735 d->regions_total = 0;
729 return 1; 736 return 1;
730 } 737 }
@@ -787,7 +794,7 @@ omalloc_grow(struct dir_info *d)
787 } 794 }
788 /* avoid pages containing meta info to end up in cache */ 795 /* avoid pages containing meta info to end up in cache */
789 if (munmap(d->r, d->regions_total * sizeof(struct region_info))) 796 if (munmap(d->r, d->regions_total * sizeof(struct region_info)))
790 wrterror("munmap"); 797 wrterror("munmap", d->r);
791 else 798 else
792 malloc_used -= d->regions_total * sizeof(struct region_info); 799 malloc_used -= d->regions_total * sizeof(struct region_info);
793 d->regions_free = d->regions_free + d->regions_total; 800 d->regions_free = d->regions_free + d->regions_total;
@@ -853,7 +860,7 @@ find(struct dir_info *d, void *p)
853 860
854 if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) || 861 if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) ||
855 d->canary1 != ~d->canary2) 862 d->canary1 != ~d->canary2)
856 wrterror("internal struct corrupt"); 863 wrterror("internal struct corrupt", NULL);
857 p = MASK_POINTER(p); 864 p = MASK_POINTER(p);
858 index = hash(p) & mask; 865 index = hash(p) & mask;
859 r = d->r[index].p; 866 r = d->r[index].p;
@@ -876,7 +883,7 @@ delete(struct dir_info *d, struct region_info *ri)
876 size_t i, j, r; 883 size_t i, j, r;
877 884
878 if (d->regions_total & (d->regions_total - 1)) 885 if (d->regions_total & (d->regions_total - 1))
879 wrterror("regions_total not 2^x"); 886 wrterror("regions_total not 2^x", NULL);
880 d->regions_free++; 887 d->regions_free++;
881 STATS_INC(g_pool->deletes); 888 STATS_INC(g_pool->deletes);
882 889
@@ -960,7 +967,7 @@ omalloc_make_chunks(struct dir_info *d, int bits)
960 967
961 bits++; 968 bits++;
962 if ((uintptr_t)pp & bits) 969 if ((uintptr_t)pp & bits)
963 wrterror("pp & bits"); 970 wrterror("pp & bits", pp);
964 971
965 insert(d, (void *)((uintptr_t)pp | bits), (uintptr_t)bp); 972 insert(d, (void *)((uintptr_t)pp | bits), (uintptr_t)bp);
966 return bp; 973 return bp;
@@ -980,7 +987,7 @@ malloc_bytes(struct dir_info *d, size_t size)
980 987
981 if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) || 988 if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) ||
982 d->canary1 != ~d->canary2) 989 d->canary1 != ~d->canary2)
983 wrterror("internal struct corrupt"); 990 wrterror("internal struct corrupt", NULL);
984 /* Don't bother with anything less than this */ 991 /* Don't bother with anything less than this */
985 /* unless we have a malloc(0) requests */ 992 /* unless we have a malloc(0) requests */
986 if (size != 0 && size < MALLOC_MINSIZE) 993 if (size != 0 && size < MALLOC_MINSIZE)
@@ -1005,7 +1012,7 @@ malloc_bytes(struct dir_info *d, size_t size)
1005 bp = LIST_FIRST(&d->chunk_dir[j]); 1012 bp = LIST_FIRST(&d->chunk_dir[j]);
1006 1013
1007 if (bp->canary != d->canary1) 1014 if (bp->canary != d->canary1)
1008 wrterror("chunk info corrupted"); 1015 wrterror("chunk info corrupted", NULL);
1009 /* Find first word of bitmap which isn't empty */ 1016 /* Find first word of bitmap which isn't empty */
1010 for (lp = bp->bits; !*lp; lp++) 1017 for (lp = bp->bits; !*lp; lp++)
1011 /* EMPTY */; 1018 /* EMPTY */;
@@ -1029,7 +1036,7 @@ malloc_bytes(struct dir_info *d, size_t size)
1029 k = 0; 1036 k = 0;
1030 } 1037 }
1031 if (lp - bp->bits > (bp->total - 1) / MALLOC_BITS) { 1038 if (lp - bp->bits > (bp->total - 1) / MALLOC_BITS) {
1032 wrterror("chunk overflow"); 1039 wrterror("chunk overflow", NULL);
1033 errno = EFAULT; 1040 errno = EFAULT;
1034 return (NULL); 1041 return (NULL);
1035 } 1042 }
@@ -1065,17 +1072,17 @@ free_bytes(struct dir_info *d, struct region_info *r, void *ptr)
1065 1072
1066 info = (struct chunk_info *)r->size; 1073 info = (struct chunk_info *)r->size;
1067 if (info->canary != d->canary1) 1074 if (info->canary != d->canary1)
1068 wrterror("chunk info corrupted"); 1075 wrterror("chunk info corrupted", NULL);
1069 1076
1070 /* Find the chunk number on the page */ 1077 /* Find the chunk number on the page */
1071 i = ((uintptr_t)ptr & MALLOC_PAGEMASK) >> info->shift; 1078 i = ((uintptr_t)ptr & MALLOC_PAGEMASK) >> info->shift;
1072 1079
1073 if ((uintptr_t)ptr & ((1UL << (info->shift)) - 1)) { 1080 if ((uintptr_t)ptr & ((1UL << (info->shift)) - 1)) {
1074 wrterror("modified chunk-pointer"); 1081 wrterror("modified chunk-pointer", ptr);
1075 return; 1082 return;
1076 } 1083 }
1077 if (info->bits[i / MALLOC_BITS] & (1UL << (i % MALLOC_BITS))) { 1084 if (info->bits[i / MALLOC_BITS] & (1UL << (i % MALLOC_BITS))) {
1078 wrterror("chunk is already free"); 1085 wrterror("chunk is already free", ptr);
1079 return; 1086 return;
1080 } 1087 }
1081 1088
@@ -1133,7 +1140,7 @@ omalloc(size_t sz, int zero_fill)
1133 if (mopts.malloc_guard) { 1140 if (mopts.malloc_guard) {
1134 if (mprotect((char *)p + psz - mopts.malloc_guard, 1141 if (mprotect((char *)p + psz - mopts.malloc_guard,
1135 mopts.malloc_guard, PROT_NONE)) 1142 mopts.malloc_guard, PROT_NONE))
1136 wrterror("mprotect"); 1143 wrterror("mprotect", NULL);
1137 malloc_guarded += mopts.malloc_guard; 1144 malloc_guarded += mopts.malloc_guard;
1138 } 1145 }
1139 1146
@@ -1182,7 +1189,7 @@ malloc_recurse(void)
1182 1189
1183 if (noprint == 0) { 1190 if (noprint == 0) {
1184 noprint = 1; 1191 noprint = 1;
1185 wrterror("recursive call"); 1192 wrterror("recursive call", NULL);
1186 } 1193 }
1187 malloc_active--; 1194 malloc_active--;
1188 _MALLOC_UNLOCK(); 1195 _MALLOC_UNLOCK();
@@ -1195,7 +1202,7 @@ malloc_init(void)
1195 if (omalloc_init(&g_pool)) { 1202 if (omalloc_init(&g_pool)) {
1196 _MALLOC_UNLOCK(); 1203 _MALLOC_UNLOCK();
1197 if (mopts.malloc_xmalloc) 1204 if (mopts.malloc_xmalloc)
1198 wrterror("out of memory"); 1205 wrterror("out of memory", NULL);
1199 errno = ENOMEM; 1206 errno = ENOMEM;
1200 return -1; 1207 return -1;
1201 } 1208 }
@@ -1222,7 +1229,7 @@ malloc(size_t size)
1222 malloc_active--; 1229 malloc_active--;
1223 _MALLOC_UNLOCK(); 1230 _MALLOC_UNLOCK();
1224 if (r == NULL && mopts.malloc_xmalloc) { 1231 if (r == NULL && mopts.malloc_xmalloc) {
1225 wrterror("out of memory"); 1232 wrterror("out of memory", NULL);
1226 errno = ENOMEM; 1233 errno = ENOMEM;
1227 } 1234 }
1228 if (r != NULL) 1235 if (r != NULL)
@@ -1238,7 +1245,7 @@ ofree(void *p)
1238 1245
1239 r = find(g_pool, p); 1246 r = find(g_pool, p);
1240 if (r == NULL) { 1247 if (r == NULL) {
1241 wrterror("bogus pointer (double free?)"); 1248 wrterror("bogus pointer (double free?)", p);
1242 return; 1249 return;
1243 } 1250 }
1244 REALSIZE(sz, r); 1251 REALSIZE(sz, r);
@@ -1246,7 +1253,7 @@ ofree(void *p)
1246 if (sz - mopts.malloc_guard >= MALLOC_PAGESIZE - 1253 if (sz - mopts.malloc_guard >= MALLOC_PAGESIZE -
1247 MALLOC_LEEWAY) { 1254 MALLOC_LEEWAY) {
1248 if (r->p != p) { 1255 if (r->p != p) {
1249 wrterror("bogus pointer"); 1256 wrterror("bogus pointer", p);
1250 return; 1257 return;
1251 } 1258 }
1252 } else { 1259 } else {
@@ -1261,12 +1268,12 @@ ofree(void *p)
1261 } 1268 }
1262 if (mopts.malloc_guard) { 1269 if (mopts.malloc_guard) {
1263 if (sz < mopts.malloc_guard) 1270 if (sz < mopts.malloc_guard)
1264 wrterror("guard size"); 1271 wrterror("guard size", NULL);
1265 if (!mopts.malloc_freeprot) { 1272 if (!mopts.malloc_freeprot) {
1266 if (mprotect((char *)p + PAGEROUND(sz) - 1273 if (mprotect((char *)p + PAGEROUND(sz) -
1267 mopts.malloc_guard, mopts.malloc_guard, 1274 mopts.malloc_guard, mopts.malloc_guard,
1268 PROT_READ | PROT_WRITE)) 1275 PROT_READ | PROT_WRITE))
1269 wrterror("mprotect"); 1276 wrterror("mprotect", NULL);
1270 } 1277 }
1271 malloc_guarded -= mopts.malloc_guard; 1278 malloc_guarded -= mopts.malloc_guard;
1272 } 1279 }
@@ -1290,7 +1297,7 @@ ofree(void *p)
1290 if (p != NULL) { 1297 if (p != NULL) {
1291 r = find(g_pool, p); 1298 r = find(g_pool, p);
1292 if (r == NULL) { 1299 if (r == NULL) {
1293 wrterror("bogus pointer (double free?)"); 1300 wrterror("bogus pointer (double free?)", p);
1294 return; 1301 return;
1295 } 1302 }
1296 free_bytes(g_pool, r, p); 1303 free_bytes(g_pool, r, p);
@@ -1311,7 +1318,7 @@ free(void *ptr)
1311 malloc_func = " in free():"; 1318 malloc_func = " in free():";
1312 if (g_pool == NULL) { 1319 if (g_pool == NULL) {
1313 _MALLOC_UNLOCK(); 1320 _MALLOC_UNLOCK();
1314 wrterror("free() called before allocation"); 1321 wrterror("free() called before allocation", NULL);
1315 return; 1322 return;
1316 } 1323 }
1317 if (malloc_active++) { 1324 if (malloc_active++) {
@@ -1337,7 +1344,7 @@ orealloc(void *p, size_t newsz)
1337 1344
1338 r = find(g_pool, p); 1345 r = find(g_pool, p);
1339 if (r == NULL) { 1346 if (r == NULL) {
1340 wrterror("bogus pointer (double free?)"); 1347 wrterror("bogus pointer (double free?)", p);
1341 return NULL; 1348 return NULL;
1342 } 1349 }
1343 if (newsz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) { 1350 if (newsz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) {
@@ -1349,7 +1356,7 @@ orealloc(void *p, size_t newsz)
1349 goldsz = oldsz; 1356 goldsz = oldsz;
1350 if (oldsz > MALLOC_MAXCHUNK) { 1357 if (oldsz > MALLOC_MAXCHUNK) {
1351 if (oldsz < mopts.malloc_guard) 1358 if (oldsz < mopts.malloc_guard)
1352 wrterror("guard size"); 1359 wrterror("guard size", NULL);
1353 oldsz -= mopts.malloc_guard; 1360 oldsz -= mopts.malloc_guard;
1354 } 1361 }
1355 1362
@@ -1383,11 +1390,11 @@ orealloc(void *p, size_t newsz)
1383 if (mprotect((char *)p + roldsz - 1390 if (mprotect((char *)p + roldsz -
1384 mopts.malloc_guard, mopts.malloc_guard, 1391 mopts.malloc_guard, mopts.malloc_guard,
1385 PROT_READ | PROT_WRITE)) 1392 PROT_READ | PROT_WRITE))
1386 wrterror("mprotect"); 1393 wrterror("mprotect", NULL);
1387 if (mprotect((char *)p + rnewsz - 1394 if (mprotect((char *)p + rnewsz -
1388 mopts.malloc_guard, mopts.malloc_guard, 1395 mopts.malloc_guard, mopts.malloc_guard,
1389 PROT_NONE)) 1396 PROT_NONE))
1390 wrterror("mprotect"); 1397 wrterror("mprotect", NULL);
1391 } 1398 }
1392 unmap(g_pool, (char *)p + rnewsz, roldsz - rnewsz); 1399 unmap(g_pool, (char *)p + rnewsz, roldsz - rnewsz);
1393 r->size = gnewsz; 1400 r->size = gnewsz;
@@ -1437,7 +1444,7 @@ realloc(void *ptr, size_t size)
1437 malloc_active--; 1444 malloc_active--;
1438 _MALLOC_UNLOCK(); 1445 _MALLOC_UNLOCK();
1439 if (r == NULL && mopts.malloc_xmalloc) { 1446 if (r == NULL && mopts.malloc_xmalloc) {
1440 wrterror("out of memory"); 1447 wrterror("out of memory", NULL);
1441 errno = ENOMEM; 1448 errno = ENOMEM;
1442 } 1449 }
1443 if (r != NULL) 1450 if (r != NULL)
@@ -1464,7 +1471,7 @@ calloc(size_t nmemb, size_t size)
1464 nmemb > 0 && SIZE_MAX / nmemb < size) { 1471 nmemb > 0 && SIZE_MAX / nmemb < size) {
1465 _MALLOC_UNLOCK(); 1472 _MALLOC_UNLOCK();
1466 if (mopts.malloc_xmalloc) 1473 if (mopts.malloc_xmalloc)
1467 wrterror("out of memory"); 1474 wrterror("out of memory", NULL);
1468 errno = ENOMEM; 1475 errno = ENOMEM;
1469 return NULL; 1476 return NULL;
1470 } 1477 }
@@ -1480,7 +1487,7 @@ calloc(size_t nmemb, size_t size)
1480 malloc_active--; 1487 malloc_active--;
1481 _MALLOC_UNLOCK(); 1488 _MALLOC_UNLOCK();
1482 if (r == NULL && mopts.malloc_xmalloc) { 1489 if (r == NULL && mopts.malloc_xmalloc) {
1483 wrterror("out of memory"); 1490 wrterror("out of memory", NULL);
1484 errno = ENOMEM; 1491 errno = ENOMEM;
1485 } 1492 }
1486 if (r != NULL) 1493 if (r != NULL)