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:
parent
fbae48b901
commit
0213791d0c
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue