Print this page
3946 ::gcore
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
@@ -20,10 +20,11 @@
*/
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@ -39,11 +40,10 @@
#include <signal.h>
#include <limits.h>
#include <libgen.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/systeminfo.h>
#include <sys/sysmacros.h>
#include "libproc.h"
#include "Pcontrol.h"
#include "Putil.h"
@@ -432,10 +432,16 @@
if (Pgetauxval(P, AT_BASE) != -1L &&
(mptr = object_name_to_map(P, PR_LMID_EVERY, PR_OBJ_LDSO)) != NULL)
map_set(P, mptr, "ld.so.1");
}
+int
+Preadmaps(struct ps_prochandle *P, prmap_t **Pmapp, ssize_t *nmapp)
+{
+ return (P->ops.pop_read_maps(P, Pmapp, nmapp, P->data));
+}
+
/*
* Go through all the address space mappings, validating or updating
* the information already gathered, or gathering new information.
*
* This function is only called when we suspect that the mappings have changed
@@ -442,13 +448,10 @@
* because this is the first time we're calling it or because of rtld activity.
*/
void
Pupdate_maps(struct ps_prochandle *P)
{
- char mapfile[PATH_MAX];
- int mapfd;
- struct stat statb;
prmap_t *Pmap = NULL;
prmap_t *pmap;
ssize_t nmap;
int i;
uint_t oldmapcount;
@@ -458,26 +461,12 @@
if (P->info_valid || P->state == PS_UNDEAD)
return;
Preadauxvec(P);
- (void) snprintf(mapfile, sizeof (mapfile), "%s/%d/map",
- procfs_path, (int)P->pid);
- if ((mapfd = open(mapfile, O_RDONLY)) < 0 ||
- fstat(mapfd, &statb) != 0 ||
- statb.st_size < sizeof (prmap_t) ||
- (Pmap = malloc(statb.st_size)) == NULL ||
- (nmap = pread(mapfd, Pmap, statb.st_size, 0L)) <= 0 ||
- (nmap /= sizeof (prmap_t)) == 0) {
- if (Pmap != NULL)
- free(Pmap);
- if (mapfd >= 0)
- (void) close(mapfd);
- Preset_maps(P); /* utter failure; destroy tables */
+ if (Preadmaps(P, &Pmap, &nmap) != 0)
return;
- }
- (void) close(mapfd);
if ((newmap = calloc(1, nmap * sizeof (map_info_t))) == NULL)
return;
/*
@@ -846,55 +835,20 @@
Pname_to_ctf(struct ps_prochandle *P, const char *name)
{
return (Plmid_to_ctf(P, PR_LMID_EVERY, name));
}
-/*
- * If we're not a core file, re-read the /proc/<pid>/auxv file and store
- * its contents in P->auxv. In the case of a core file, we either
- * initialized P->auxv in Pcore() from the NT_AUXV, or we don't have an
- * auxv because the note was missing.
- */
void
Preadauxvec(struct ps_prochandle *P)
{
- char auxfile[64];
- struct stat statb;
- ssize_t naux;
- int fd;
-
- if (P->state == PS_DEAD)
- return; /* Already read during Pgrab_core() */
- if (P->state == PS_IDLE)
- return; /* No aux vec for Pgrab_file() */
-
if (P->auxv != NULL) {
free(P->auxv);
P->auxv = NULL;
P->nauxv = 0;
}
- (void) snprintf(auxfile, sizeof (auxfile), "%s/%d/auxv",
- procfs_path, (int)P->pid);
- if ((fd = open(auxfile, O_RDONLY)) < 0)
- return;
-
- if (fstat(fd, &statb) == 0 &&
- statb.st_size >= sizeof (auxv_t) &&
- (P->auxv = malloc(statb.st_size + sizeof (auxv_t))) != NULL) {
- if ((naux = read(fd, P->auxv, statb.st_size)) < 0 ||
- (naux /= sizeof (auxv_t)) < 1) {
- free(P->auxv);
- P->auxv = NULL;
- } else {
- P->auxv[naux].a_type = AT_NULL;
- P->auxv[naux].a_un.a_val = 0L;
- P->nauxv = (int)naux;
- }
- }
-
- (void) close(fd);
+ P->ops.pop_read_aux(P, &P->auxv, &P->nauxv, P->data);
}
/*
* Return a requested element from the process's aux vector.
* Return -1 on failure (this is adequate for our purposes).
@@ -1681,11 +1635,11 @@
* header and .shstrtab data buffer so we can process sections by
* name. If anything goes wrong try to fake up an elf file from
* the in-core elf image.
*/
- if (_libproc_incore_elf) {
+ if (_libproc_incore_elf || (P->flags & INCORE)) {
dprintf("Pbuild_file_symtab: using in-core data for: %s\n",
fptr->file_pname);
if ((elf = build_fake_elf(P, fptr, &ehdr, &nshdrs, &shdata)) ==
NULL)
@@ -2967,56 +2921,25 @@
return (Psymbol_iter_com(P, PR_LMID_EVERY, object_name, which, mask,
PRO_BYNAME, (proc_xsym_f *)func, cd));
}
/*
- * Get the platform string from the core file if we have it;
- * just perform the system call for the caller if this is a live process.
+ * Get the platform string.
*/
char *
Pplatform(struct ps_prochandle *P, char *s, size_t n)
{
- if (P->state == PS_IDLE) {
- errno = ENODATA;
- return (NULL);
- }
-
- if (P->state == PS_DEAD) {
- if (P->core->core_platform == NULL) {
- errno = ENODATA;
- return (NULL);
- }
- (void) strncpy(s, P->core->core_platform, n - 1);
- s[n - 1] = '\0';
-
- } else if (sysinfo(SI_PLATFORM, s, n) == -1)
- return (NULL);
-
- return (s);
+ return (P->ops.pop_platform(P, s, n, P->data));
}
/*
- * Get the uname(2) information from the core file if we have it;
- * just perform the system call for the caller if this is a live process.
+ * Get the uname(2) information.
*/
int
Puname(struct ps_prochandle *P, struct utsname *u)
{
- if (P->state == PS_IDLE) {
- errno = ENODATA;
- return (-1);
- }
-
- if (P->state == PS_DEAD) {
- if (P->core->core_uts == NULL) {
- errno = ENODATA;
- return (-1);
- }
- (void) memcpy(u, P->core->core_uts, sizeof (struct utsname));
- return (0);
- }
- return (uname(u));
+ return (P->ops.pop_uname(P, u, P->data));
}
/*
* Called from Pcreate(), Pgrab(), and Pfgrab_core() to initialize
* the symbol table heads in the new ps_prochandle.