Add procstat_getvmmap function to get VM layout of a process.
MFC after: 1 month
This commit is contained in:
parent
16ea6280bf
commit
08b1137c14
@ -16,6 +16,8 @@ FBSD_1.2 {
|
||||
};
|
||||
|
||||
FBSD_1.3 {
|
||||
procstat_freevmmap;
|
||||
procstat_get_shm_info;
|
||||
procstat_getvmmap;
|
||||
procstat_open_core;
|
||||
};
|
||||
|
@ -34,8 +34,10 @@
|
||||
.Nm procstat_close ,
|
||||
.Nm procstat_getfiles ,
|
||||
.Nm procstat_getprocs ,
|
||||
.Nm procstat_getvmmap ,
|
||||
.Nm procstat_freefiles ,
|
||||
.Nm procstat_freeprocs ,
|
||||
.Nm procstat_freevmmap ,
|
||||
.Nm procstat_get_pipe_info ,
|
||||
.Nm procstat_get_pts_info ,
|
||||
.Nm procstat_get_shm_info ,
|
||||
@ -57,6 +59,11 @@
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fn procstat_freeprocs "struct procstat *procstat" "struct kinfo_proc *p"
|
||||
.Ft void
|
||||
.Fo procstat_freevmmap
|
||||
.Fa "struct procstat *procstat"
|
||||
.Fa "struct kinfo_vmentry *vmmap"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo procstat_get_pipe_info
|
||||
.Fa "struct procstat *procstat"
|
||||
@ -105,6 +112,12 @@
|
||||
.Fa "int arg"
|
||||
.Fa "unsigned int *count"
|
||||
.Fc
|
||||
.Ft "struct kinfo_vmentry *"
|
||||
.Fo procstat_getvmmap
|
||||
.Fa "struct procstat *procstat"
|
||||
.Fa "struct kinfo_proc *kp"
|
||||
.Fa "unsigned int *count"
|
||||
.Fc
|
||||
.Ft "struct procstat *"
|
||||
.Fn procstat_open_core "const char *filename"
|
||||
.Ft "struct procstat *"
|
||||
@ -214,6 +227,22 @@ The caller is responsible to free the allocated memory with a subsequent
|
||||
function call.
|
||||
.Pp
|
||||
The
|
||||
.Fn procstat_getvmmap
|
||||
function gets a pointer to the
|
||||
.Vt procstat
|
||||
structure initialized with one of the
|
||||
.Fn procstat_open_*
|
||||
functions, a pointer to
|
||||
.Vt kinfo_proc
|
||||
structure, and returns VM layout of the process as a dynamically allocated
|
||||
array of
|
||||
.Vt kinfo_vmentry
|
||||
structures.
|
||||
The caller is responsible to free the allocated memory with a subsequent
|
||||
.Fn procstat_freevmmap
|
||||
function call.
|
||||
.Pp
|
||||
The
|
||||
.Fn procstat_get_pipe_info ,
|
||||
.Fn procstat_get_pts_info ,
|
||||
.Fn procstat_get_shm_info ,
|
||||
|
@ -105,6 +105,8 @@ int statfs(const char *, struct statfs *); /* XXX */
|
||||
#define PROCSTAT_CORE 3
|
||||
|
||||
static char *getmnton(kvm_t *kd, struct mount *m);
|
||||
static struct kinfo_vmentry * kinfo_getvmmap_core(struct procstat_core *core,
|
||||
int *cntp);
|
||||
static struct filestat_list *procstat_getfiles_kvm(
|
||||
struct procstat *procstat, struct kinfo_proc *kp, int mmapped);
|
||||
static struct filestat_list *procstat_getfiles_sysctl(
|
||||
@ -802,7 +804,7 @@ procstat_getfiles_sysctl(struct procstat *procstat, struct kinfo_proc *kp,
|
||||
STAILQ_INSERT_TAIL(head, entry, next);
|
||||
}
|
||||
if (mmapped != 0) {
|
||||
vmentries = kinfo_getvmmap(kp->ki_pid, &cnt);
|
||||
vmentries = procstat_getvmmap(procstat, kp, &cnt);
|
||||
procstat->vmentries = vmentries;
|
||||
if (vmentries == NULL || cnt == 0)
|
||||
goto fail;
|
||||
@ -1507,3 +1509,82 @@ getmnton(kvm_t *kd, struct mount *m)
|
||||
return (mt->mntonname);
|
||||
}
|
||||
|
||||
static struct kinfo_vmentry *
|
||||
kinfo_getvmmap_core(struct procstat_core *core, int *cntp)
|
||||
{
|
||||
int cnt;
|
||||
size_t len;
|
||||
char *buf, *bp, *eb;
|
||||
struct kinfo_vmentry *kiv, *kp, *kv;
|
||||
|
||||
buf = procstat_core_get(core, PSC_TYPE_VMMAP, NULL, &len);
|
||||
if (buf == NULL)
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* XXXMG: The code below is just copy&past from libutil.
|
||||
* The code duplication can be avoided if libutil
|
||||
* is extended to provide something like:
|
||||
* struct kinfo_vmentry *kinfo_getvmmap_from_buf(const char *buf,
|
||||
* size_t len, int *cntp);
|
||||
*/
|
||||
|
||||
/* Pass 1: count items */
|
||||
cnt = 0;
|
||||
bp = buf;
|
||||
eb = buf + len;
|
||||
while (bp < eb) {
|
||||
kv = (struct kinfo_vmentry *)(uintptr_t)bp;
|
||||
bp += kv->kve_structsize;
|
||||
cnt++;
|
||||
}
|
||||
|
||||
kiv = calloc(cnt, sizeof(*kiv));
|
||||
if (kiv == NULL) {
|
||||
free(buf);
|
||||
return (NULL);
|
||||
}
|
||||
bp = buf;
|
||||
eb = buf + len;
|
||||
kp = kiv;
|
||||
/* Pass 2: unpack */
|
||||
while (bp < eb) {
|
||||
kv = (struct kinfo_vmentry *)(uintptr_t)bp;
|
||||
/* Copy/expand into pre-zeroed buffer */
|
||||
memcpy(kp, kv, kv->kve_structsize);
|
||||
/* Advance to next packed record */
|
||||
bp += kv->kve_structsize;
|
||||
/* Set field size to fixed length, advance */
|
||||
kp->kve_structsize = sizeof(*kp);
|
||||
kp++;
|
||||
}
|
||||
free(buf);
|
||||
*cntp = cnt;
|
||||
return (kiv); /* Caller must free() return value */
|
||||
}
|
||||
|
||||
struct kinfo_vmentry *
|
||||
procstat_getvmmap(struct procstat *procstat, struct kinfo_proc *kp,
|
||||
unsigned int *cntp)
|
||||
{
|
||||
switch(procstat->type) {
|
||||
case PROCSTAT_KVM:
|
||||
warnx("kvm method is not supported");
|
||||
return (NULL);
|
||||
case PROCSTAT_SYSCTL:
|
||||
return (kinfo_getvmmap(kp->ki_pid, cntp));
|
||||
case PROCSTAT_CORE:
|
||||
return (kinfo_getvmmap_core(procstat->core, cntp));
|
||||
default:
|
||||
warnx("unknown access method: %d", procstat->type);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
procstat_freevmmap(struct procstat *procstat __unused,
|
||||
struct kinfo_vmentry *vmmap)
|
||||
{
|
||||
|
||||
free(vmmap);
|
||||
}
|
||||
|
@ -89,6 +89,7 @@
|
||||
#define PS_FST_FFLAG_EXEC 0x2000
|
||||
#define PS_FST_FFLAG_HASLOCK 0x4000
|
||||
|
||||
struct kinfo_vmentry;
|
||||
struct procstat;
|
||||
struct filestat {
|
||||
int fs_type; /* Descriptor type. */
|
||||
@ -148,6 +149,8 @@ void procstat_close(struct procstat *procstat);
|
||||
void procstat_freeprocs(struct procstat *procstat, struct kinfo_proc *p);
|
||||
void procstat_freefiles(struct procstat *procstat,
|
||||
struct filestat_list *head);
|
||||
void procstat_freevmmap(struct procstat *procstat,
|
||||
struct kinfo_vmentry *vmmap);
|
||||
struct filestat_list *procstat_getfiles(struct procstat *procstat,
|
||||
struct kinfo_proc *kp, int mmapped);
|
||||
struct kinfo_proc *procstat_getprocs(struct procstat *procstat,
|
||||
@ -162,6 +165,8 @@ int procstat_get_socket_info(struct procstat *procstat, struct filestat *fst,
|
||||
struct sockstat *sock, char *errbuf);
|
||||
int procstat_get_vnode_info(struct procstat *procstat, struct filestat *fst,
|
||||
struct vnstat *vn, char *errbuf);
|
||||
struct kinfo_vmentry *procstat_getvmmap(struct procstat *procstat,
|
||||
struct kinfo_proc *kp, unsigned int *count);
|
||||
struct procstat *procstat_open_core(const char *filename);
|
||||
struct procstat *procstat_open_sysctl(void);
|
||||
struct procstat *procstat_open_kvm(const char *nlistf, const char *memf);
|
||||
|
Loading…
x
Reference in New Issue
Block a user