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.
This commit is contained in:
christos 2006-02-16 20:48:42 +00:00
parent fbae48b901
commit 0213791d0c
4 changed files with 68 additions and 124 deletions

View File

@ -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) {

View File

@ -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)

View File

@ -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)

View File

@ -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);