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.