From 0213791d0c3b3678984244d185fea0d534fd3432 Mon Sep 17 00:00:00 2001 From: christos Date: Thu, 16 Feb 2006 20:48:42 +0000 Subject: [PATCH] 1. Eliminate some unnecessary to kvm_{m,re}alloc. 2. Don't malloc/free procbase/procbase2/lwpbase continuously. Keep track of the size, and only do it if necessary. 3. Write a macro to malloc/realloc and set the size of members so that it is done correctly. Previous open coded version in kvm_file.c always set the length, which is incorrect. 4. Remove bogus check against INT_MAX. 5. use NULL to initialize pointers instead of 0. --- lib/libkvm/kvm.c | 31 +++++----- lib/libkvm/kvm_file.c | 22 ++----- lib/libkvm/kvm_private.h | 19 ++++++- lib/libkvm/kvm_proc.c | 120 ++++++++++----------------------------- 4 files changed, 68 insertions(+), 124 deletions(-) diff --git a/lib/libkvm/kvm.c b/lib/libkvm/kvm.c index b98d66d26af7..a24aa341cce4 100644 --- a/lib/libkvm/kvm.c +++ b/lib/libkvm/kvm.c @@ -1,4 +1,4 @@ -/* $NetBSD: kvm.c,v 1.84 2005/07/30 16:32:29 yamt Exp $ */ +/* $NetBSD: kvm.c,v 1.85 2006/02/16 20:48:42 christos Exp $ */ /*- * Copyright (c) 1989, 1992, 1993 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)kvm.c 8.2 (Berkeley) 2/13/94"; #else -__RCSID("$NetBSD: kvm.c,v 1.84 2005/07/30 16:32:29 yamt Exp $"); +__RCSID("$NetBSD: kvm.c,v 1.85 2006/02/16 20:48:42 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -229,20 +229,23 @@ _kvm_open(kd, uf, mf, sf, flag, errout) kd->swfd = -1; kd->nlfd = -1; kd->alive = KVM_ALIVE_DEAD; - kd->procbase = 0; - kd->procbase2 = 0; - kd->lwpbase = 0; + kd->procbase = NULL; + kd->procbase_len = 0; + kd->procbase2 = NULL; + kd->procbase2_len = 0; + kd->lwpbase = NULL; + kd->lwpbase_len = 0; kd->nbpg = getpagesize(); - kd->swapspc = 0; - kd->argspc = 0; - kd->arglen = 0; - kd->argbuf = 0; - kd->argv = 0; - kd->vmst = 0; - kd->vm_page_buckets = 0; - kd->kcore_hdr = 0; + kd->swapspc = NULL; + kd->argspc = NULL; + kd->argspc_len = 0; + kd->argbuf = NULL; + kd->argv = NULL; + kd->vmst = NULL; + kd->vm_page_buckets = NULL; + kd->kcore_hdr = NULL; kd->cpu_dsize = 0; - kd->cpu_data = 0; + kd->cpu_data = NULL; kd->dump_off = 0; if (flag & KVM_NO_FILES) { diff --git a/lib/libkvm/kvm_file.c b/lib/libkvm/kvm_file.c index 6ce0f901ab87..976cc6a3294a 100644 --- a/lib/libkvm/kvm_file.c +++ b/lib/libkvm/kvm_file.c @@ -1,4 +1,4 @@ -/* $NetBSD: kvm_file.c,v 1.23 2003/08/07 16:44:36 agc Exp $ */ +/* $NetBSD: kvm_file.c,v 1.24 2006/02/16 20:48:42 christos Exp $ */ /*- * Copyright (c) 1989, 1992, 1993 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)kvm_file.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: kvm_file.c,v 1.23 2003/08/07 16:44:36 agc Exp $"); +__RCSID("$NetBSD: kvm_file.c,v 1.24 2006/02/16 20:48:42 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -86,7 +86,7 @@ kvm_deadfiles(kd, op, arg, ofhead, numfiles) int op, arg, numfiles; long ofhead; { - int buflen = kd->arglen, n = 0; + size_t buflen = kd->argspc_len, n = 0; struct file *fp; struct filelist fhead; char *where = kd->argspc; @@ -146,13 +146,7 @@ kvm_getfiles(kd, op, arg, cnt) _kvm_syserr(kd, kd->program, "kvm_getprocs"); return (0); } - if (kd->argspc == 0) - kd->argspc = (char *)_kvm_malloc(kd, size); - else if (kd->arglen < size) - kd->argspc = (char *)_kvm_realloc(kd, kd->argspc, size); - if (kd->argspc == 0) - return (0); - kd->arglen = size; + KVM_ALLOC(kd, argspc, size); st = sysctl(mib, 2, kd->argspc, &size, NULL, 0); if (st == -1 || size < sizeof(fhead)) { _kvm_syserr(kd, kd->program, "kvm_getfiles"); @@ -183,13 +177,7 @@ kvm_getfiles(kd, op, arg, cnt) return (0); } size = sizeof(fhead) + (numfiles + 10) * sizeof(struct file); - if (kd->argspc == 0) - kd->argspc = (char *)_kvm_malloc(kd, size); - else if (kd->arglen < size) - kd->argspc = (char *)_kvm_realloc(kd, kd->argspc, size); - if (kd->argspc == 0) - return (0); - kd->arglen = size; + KVM_ALLOC(kd, argspc, size); numfiles = kvm_deadfiles(kd, op, arg, (long)nl[1].n_value, numfiles); if (numfiles == 0) diff --git a/lib/libkvm/kvm_private.h b/lib/libkvm/kvm_private.h index ece6f65896c3..68aeeed5dffa 100644 --- a/lib/libkvm/kvm_private.h +++ b/lib/libkvm/kvm_private.h @@ -1,4 +1,4 @@ -/* $NetBSD: kvm_private.h,v 1.14 2003/08/07 16:44:39 agc Exp $ */ +/* $NetBSD: kvm_private.h,v 1.15 2006/02/16 20:48:42 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -52,12 +52,15 @@ struct __kvm { struct kinfo_proc *procbase; struct kinfo_proc2 *procbase2; struct kinfo_lwp *lwpbase; + size_t procbase_len; + size_t procbase2_len; + size_t lwpbase_len; u_long usrstack; /* address of end of user stack */ u_long min_uva, max_uva; /* min/max user virtual address */ int nbpg; /* page size */ char *swapspc; /* (dynamic) storage for swapped pages */ char *argspc, *argbuf; /* (dynamic) storage for argv strings */ - int arglen; /* length of the above */ + size_t argspc_len; /* length of the above */ char **argv; /* (dynamic) storage for argv pointers */ int argc; /* length of above (not actual # present) */ @@ -112,3 +115,15 @@ void _kvm_syserr __P((kvm_t *kd, const char *program, const char *fmt, ...)) __attribute__((__format__(__printf__, 3, 4))); +#define KVM_ALLOC(kd, member, size) \ + do { \ + if (kd->member == NULL) \ + kd->member = _kvm_malloc(kd, kd->member ## _len = size); \ + else if (kd->member ## _len < size) \ + kd->member = _kvm_realloc(kd, kd->member, \ + kd->member ## _len = size); \ + if (kd->member == NULL) { \ + kd->member ## _len = 0; \ + return (NULL); \ + } \ + } while (/*CONSTCOND*/0) diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c index a39b4bd2227e..9dc9ccc571c3 100644 --- a/lib/libkvm/kvm_proc.c +++ b/lib/libkvm/kvm_proc.c @@ -1,4 +1,4 @@ -/* $NetBSD: kvm_proc.c,v 1.60 2005/07/30 16:32:29 yamt Exp $ */ +/* $NetBSD: kvm_proc.c,v 1.61 2006/02/16 20:48:42 christos Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -74,7 +74,7 @@ #if 0 static char sccsid[] = "@(#)kvm_proc.c 8.3 (Berkeley) 9/23/93"; #else -__RCSID("$NetBSD: kvm_proc.c,v 1.60 2005/07/30 16:32:29 yamt Exp $"); +__RCSID("$NetBSD: kvm_proc.c,v 1.61 2006/02/16 20:48:42 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -193,7 +193,7 @@ _kvm_ureadm(kd, p, va, cnt) u_long slot; if (kd->swapspc == NULL) { - kd->swapspc = (char *)_kvm_malloc(kd, (size_t)kd->nbpg); + kd->swapspc = _kvm_malloc(kd, (size_t)kd->nbpg); if (kd->swapspc == NULL) return (NULL); } @@ -463,15 +463,6 @@ kvm_getproc2(kd, op, arg, esize, cnt) int mib[6], st, nprocs; struct pstats pstats; - if (kd->procbase2 != NULL) { - free(kd->procbase2); - /* - * Clear this pointer in case this call fails. Otherwise, - * kvm_close() will free it again. - */ - kd->procbase2 = NULL; - } - if (ISSYSCTL(kd)) { size = 0; mib[0] = CTL_KERN; @@ -487,9 +478,7 @@ kvm_getproc2(kd, op, arg, esize, cnt) } mib[5] = (int) (size / esize); - kd->procbase2 = (struct kinfo_proc2 *)_kvm_malloc(kd, size); - if (kd->procbase2 == NULL) - return (NULL); + KVM_ALLOC(kd, procbase2, size); st = sysctl(mib, 6, kd->procbase2, &size, NULL, (size_t)0); if (st == -1) { _kvm_syserr(kd, kd->program, "kvm_getproc2"); @@ -507,7 +496,8 @@ kvm_getproc2(kd, op, arg, esize, cnt) if (kp == NULL) return (NULL); - kd->procbase2 = _kvm_malloc(kd, nprocs * esize); + size = nprocs * esize; + KVM_ALLOC(kd, procbase2, size); kp2c = (char *)(void *)kd->procbase2; kp2p = &kp2; for (i = 0; i < nprocs; i++, kp++) { @@ -673,8 +663,6 @@ kvm_getproc2(kd, op, arg, esize, cnt) memcpy(kp2c, &kp2, esize); kp2c += esize; } - - _kvm_freeprocs(kd); } *cnt = nprocs; return (kd->procbase2); @@ -693,15 +681,6 @@ kvm_getlwps(kd, pid, paddr, esize, cnt) ssize_t st; struct kinfo_lwp *kl; - if (kd->lwpbase != NULL) { - free(kd->lwpbase); - /* - * Clear this pointer in case this call fails. Otherwise, - * kvm_close() will free it again. - */ - kd->lwpbase = NULL; - } - if (ISSYSCTL(kd)) { size = 0; mib[0] = CTL_KERN; @@ -716,9 +695,7 @@ kvm_getlwps(kd, pid, paddr, esize, cnt) } mib[4] = (int) (size / esize); - kd->lwpbase = (struct kinfo_lwp *)_kvm_malloc(kd, size); - if (kd->lwpbase == NULL) - return (NULL); + KVM_ALLOC(kd, lwpbase, size); st = sysctl(mib, 5, kd->lwpbase, &size, NULL, (size_t)0); if (st == -1) { _kvm_syserr(kd, kd->program, "kvm_getlwps"); @@ -739,10 +716,8 @@ kvm_getlwps(kd, pid, paddr, esize, cnt) } nlwps = p.p_nlwps; - kd->lwpbase = (struct kinfo_lwp *)_kvm_malloc(kd, - nlwps * sizeof(struct kinfo_lwp)); - if (kd->lwpbase == NULL) - return (NULL); + size = nlwps * sizeof(*kd->lwpbase); + KVM_ALLOC(kd, lwpbase, size); laddr = (u_long)PTRTOUINT64(p.p_lwps.lh_first); for (i = 0; (i < nlwps) && (laddr != 0); i++) { st = kvm_read(kd, laddr, &l, sizeof(l)); @@ -786,14 +761,6 @@ kvm_getprocs(kd, op, arg, cnt) size_t size; int mib[4], st, nprocs; - if (kd->procbase != NULL) { - free(kd->procbase); - /* - * Clear this pointer in case this call fails. Otherwise, - * kvm_close() will free it again. - */ - kd->procbase = NULL; - } if (ISKMEM(kd)) { size = 0; mib[0] = CTL_KERN; @@ -805,9 +772,7 @@ kvm_getprocs(kd, op, arg, cnt) _kvm_syserr(kd, kd->program, "kvm_getprocs"); return (NULL); } - kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size); - if (kd->procbase == NULL) - return (NULL); + KVM_ALLOC(kd, procbase, size); st = sysctl(mib, 4, kd->procbase, &size, NULL, (size_t)0); if (st == -1) { _kvm_syserr(kd, kd->program, "kvm_getprocs"); @@ -844,11 +809,8 @@ kvm_getprocs(kd, op, arg, cnt) _kvm_err(kd, kd->program, "can't read nprocs"); return (NULL); } - size = nprocs * sizeof(struct kinfo_proc); - kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size); - if (kd->procbase == NULL) - return (NULL); - + size = nprocs * sizeof(*kd->procbase); + KVM_ALLOC(kd, procbase, size); nprocs = kvm_deadprocs(kd, op, arg, nl[1].n_value, nl[2].n_value, nprocs); if (nprocs < 0) @@ -862,17 +824,6 @@ kvm_getprocs(kd, op, arg, cnt) return (kd->procbase); } -void -_kvm_freeprocs(kd) - kvm_t *kd; -{ - - if (kd->procbase) { - free(kd->procbase); - kd->procbase = NULL; - } -} - void * _kvm_realloc(kd, p, n) kvm_t *kd; @@ -918,25 +869,24 @@ kvm_argv(kd, p, addr, narg, maxcnt) * Try to avoid reallocs. */ kd->argc = MAX(narg + 1, 32); - kd->argv = (char **)_kvm_malloc(kd, kd->argc * - sizeof(*kd->argv)); + kd->argv = _kvm_malloc(kd, kd->argc * sizeof(*kd->argv)); if (kd->argv == NULL) return (NULL); } else if (narg + 1 > kd->argc) { kd->argc = MAX(2 * kd->argc, narg + 1); - kd->argv = (char **)_kvm_realloc(kd, kd->argv, kd->argc * + kd->argv = _kvm_realloc(kd, kd->argv, kd->argc * sizeof(*kd->argv)); if (kd->argv == NULL) return (NULL); } if (kd->argspc == NULL) { - kd->argspc = (char *)_kvm_malloc(kd, (size_t)kd->nbpg); + kd->argspc = _kvm_malloc(kd, (size_t)kd->nbpg); if (kd->argspc == NULL) return (NULL); - kd->arglen = kd->nbpg; + kd->argspc_len = kd->nbpg; } if (kd->argbuf == NULL) { - kd->argbuf = (char *)_kvm_malloc(kd, (size_t)kd->nbpg); + kd->argbuf = _kvm_malloc(kd, (size_t)kd->nbpg); if (kd->argbuf == NULL) return (NULL); } @@ -965,14 +915,14 @@ kvm_argv(kd, p, addr, narg, maxcnt) ep = memchr(cp, '\0', cc); if (ep != NULL) cc = ep - cp + 1; - if (len + cc > kd->arglen) { + if (len + cc > kd->argspc_len) { ptrdiff_t off; char **pp; char *op = kd->argspc; - kd->arglen *= 2; - kd->argspc = (char *)_kvm_realloc(kd, kd->argspc, - (size_t)kd->arglen); + kd->argspc_len *= 2; + kd->argspc = _kvm_realloc(kd, kd->argspc, + kd->argspc_len); if (kd->argspc == NULL) return (NULL); /* @@ -1127,7 +1077,7 @@ kvm_doargv2(kd, pid, type, nchr) { size_t bufs; int narg, mib[4]; - size_t newarglen; + size_t newargspc_len; char **ap, *bp, *endp; /* @@ -1153,43 +1103,31 @@ kvm_doargv2(kd, pid, type, nchr) * Try to avoid reallocs. */ kd->argc = MAX(narg + 1, 32); - kd->argv = (char **)_kvm_malloc(kd, kd->argc * - sizeof(*kd->argv)); + kd->argv = _kvm_malloc(kd, kd->argc * sizeof(*kd->argv)); if (kd->argv == NULL) return (NULL); } else if (narg + 1 > kd->argc) { kd->argc = MAX(2 * kd->argc, narg + 1); - kd->argv = (char **)_kvm_realloc(kd, kd->argv, kd->argc * + kd->argv = _kvm_realloc(kd, kd->argv, kd->argc * sizeof(*kd->argv)); if (kd->argv == NULL) return (NULL); } - newarglen = MIN(nchr, ARG_MAX); - if (kd->arglen < newarglen) { - if (kd->arglen == 0) - kd->argspc = (char *)_kvm_malloc(kd, newarglen); - else - kd->argspc = (char *)_kvm_realloc(kd, kd->argspc, - newarglen); - if (kd->argspc == NULL) - return (NULL); - if (newarglen > INT_MAX) - return NULL; - kd->arglen = (int)newarglen; - } - memset(kd->argspc, 0, (size_t)kd->arglen); /* XXX necessary? */ + newargspc_len = MIN(nchr, ARG_MAX); + KVM_ALLOC(kd, argspc, newargspc_len); + memset(kd->argspc, 0, (size_t)kd->argspc_len); /* XXX necessary? */ mib[0] = CTL_KERN; mib[1] = KERN_PROC_ARGS; mib[2] = pid; mib[3] = type; - bufs = kd->arglen; + bufs = kd->argspc_len; if (sysctl(mib, 4, kd->argspc, &bufs, NULL, (size_t)0) == -1) return (NULL); bp = kd->argspc; - bp[kd->arglen-1] = '\0'; /* make sure the string ends with nul */ + bp[kd->argspc_len-1] = '\0'; /* make sure the string ends with nul */ ap = kd->argv; endp = bp + MIN(nchr, bufs);