Print this page
3946 ::gcore
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
*** 20,29 ****
--- 20,30 ----
*/
/*
* 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,49 ****
#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"
--- 40,49 ----
*** 432,441 ****
--- 432,447 ----
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,454 ****
* 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;
--- 448,457 ----
*** 458,483 ****
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 */
return;
- }
- (void) close(mapfd);
if ((newmap = calloc(1, nmap * sizeof (map_info_t))) == NULL)
return;
/*
--- 461,472 ----
if (P->info_valid || P->state == PS_UNDEAD)
return;
Preadauxvec(P);
! if (Preadmaps(P, &Pmap, &nmap) != 0)
return;
if ((newmap = calloc(1, nmap * sizeof (map_info_t))) == NULL)
return;
/*
*** 846,900 ****
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);
}
/*
* Return a requested element from the process's aux vector.
* Return -1 on failure (this is adequate for our purposes).
--- 835,854 ----
Pname_to_ctf(struct ps_prochandle *P, const char *name)
{
return (Plmid_to_ctf(P, PR_LMID_EVERY, name));
}
void
Preadauxvec(struct ps_prochandle *P)
{
if (P->auxv != NULL) {
free(P->auxv);
P->auxv = NULL;
P->nauxv = 0;
}
! 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,1691 ****
* 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) {
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)
--- 1635,1645 ----
* 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 || (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,3022 ****
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.
*/
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);
}
/*
! * 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.
*/
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));
}
/*
* Called from Pcreate(), Pgrab(), and Pfgrab_core() to initialize
* the symbol table heads in the new ps_prochandle.
--- 2921,2945 ----
return (Psymbol_iter_com(P, PR_LMID_EVERY, object_name, which, mask,
PRO_BYNAME, (proc_xsym_f *)func, cd));
}
/*
! * Get the platform string.
*/
char *
Pplatform(struct ps_prochandle *P, char *s, size_t n)
{
! return (P->ops.pop_platform(P, s, n, P->data));
}
/*
! * Get the uname(2) information.
*/
int
Puname(struct ps_prochandle *P, struct utsname *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.