Date: Fri, 13 Sep 2002 11:26:48 -0700 (PDT) From: Peter Wemm <peter@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 17453 for review Message-ID: <200209131826.g8DIQm1B006522@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://people.freebsd.org/~peter/p4db/chv.cgi?CH=17453 Change 17453 by peter@peter_daintree on 2002/09/13 11:26:32 IFC gcore bits for testing Affected files ... .. //depot/projects/ia64/usr.bin/gcore/Makefile#3 integrate .. //depot/projects/ia64/usr.bin/gcore/aoutcore.c#1 branch .. //depot/projects/ia64/usr.bin/gcore/elfcore.c#4 integrate .. //depot/projects/ia64/usr.bin/gcore/extern.h#3 integrate .. //depot/projects/ia64/usr.bin/gcore/gcore.c#6 integrate .. //depot/projects/ia64/usr.bin/gcore/md-nop.c#4 delete .. //depot/projects/ia64/usr.bin/gcore/md-sparc.c#3 delete Differences ... ==== //depot/projects/ia64/usr.bin/gcore/Makefile#3 (text+ko) ==== @@ -1,15 +1,13 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 -# $FreeBSD: src/usr.bin/gcore/Makefile,v 1.7 2002/03/30 17:19:40 dwmalone Exp $ +# $FreeBSD: src/usr.bin/gcore/Makefile,v 1.8 2002/09/13 16:33:35 peter Exp $ PROG= gcore SRCS= elfcore.c gcore.c + +.if ${MACHINE_ARCH} == i386 +SRCS+= aoutcore.c DPADD= ${LIBKVM} LDADD= -lkvm - -.if ${MACHINE_ARCH} != "sparc" -SRCS+= md-nop.c -.else -SRCS+= md-${MACHINE_ARCH}.c .endif .include <bsd.prog.mk> ==== //depot/projects/ia64/usr.bin/gcore/elfcore.c#4 (text+ko) ==== @@ -25,10 +25,11 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/usr.bin/gcore/elfcore.c,v 1.13 2002/09/05 09:11:19 dwmalone Exp $"); +__FBSDID("$FreeBSD: src/usr.bin/gcore/elfcore.c,v 1.14 2002/09/13 16:33:35 peter Exp $"); #include <sys/param.h> #include <sys/procfs.h> +#include <sys/linker_set.h> #include <machine/elf.h> #include <vm/vm_param.h> #include <vm/vm.h> @@ -77,11 +78,26 @@ static void readhdrinfo(pid_t, prstatus_t *, prfpregset_t *, prpsinfo_t *); static vm_map_entry_t readmap(pid_t); +static int +elf_ident(int efd, pid_t pid, char *binfile) +{ + Elf_Ehdr hdr; + int cnt; + uid_t uid; + + cnt = read(efd, &hdr, sizeof(hdr)); + if (cnt != sizeof(hdr)) + return (0); + if (IS_ELF(hdr)) + return (1); + return (0); +} + /* * Write an ELF coredump for the given pid to the given fd. */ void -elf_coredump(int fd, pid_t pid) +elf_coredump(int efd, int fd, pid_t pid) { vm_map_entry_t map; struct sseg_closure seginfo; @@ -357,6 +373,7 @@ static void freemap(vm_map_entry_t map) { + while (map != NULL) { vm_map_entry_t next = map->next; free(map); @@ -514,3 +531,6 @@ free(mapbuf); return map; } + +struct dumpers elfdump = { elf_ident, elf_coredump }; +TEXT_SET(dumpset, elfdump); ==== //depot/projects/ia64/usr.bin/gcore/extern.h#3 (text+ko) ==== @@ -31,12 +31,10 @@ * SUCH DAMAGE. * * @(#)extern.h 8.1 (Berkeley) 6/6/93 - * $FreeBSD: src/usr.bin/gcore/extern.h,v 1.3 2002/03/22 01:22:40 imp Exp $ + * $FreeBSD: src/usr.bin/gcore/extern.h,v 1.4 2002/09/13 16:33:35 peter Exp $ */ -#include <sys/types.h> -#include <kvm.h> - -void err(int, const char *, ...); -void elf_coredump(int, pid_t); -void md_core(kvm_t *, int, struct kinfo_proc *); +struct dumpers { + int (*ident)(int efd, pid_t pid, char *binfile); + void (*dump)(int efd, int fd, pid_t pid); +}; ==== //depot/projects/ia64/usr.bin/gcore/gcore.c#6 (text+ko) ==== @@ -43,7 +43,7 @@ #endif /* not lint */ #endif #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/usr.bin/gcore/gcore.c,v 1.29 2002/09/05 09:11:20 dwmalone Exp $"); +__FBSDID("$FreeBSD: src/usr.bin/gcore/gcore.c,v 1.30 2002/09/13 16:33:35 peter Exp $"); /* * Originally written by Eric Cooper in Fall 1981. @@ -60,19 +60,10 @@ #include <sys/param.h> #include <sys/time.h> #include <sys/stat.h> -#include <sys/proc.h> -#include <sys/user.h> -#include <sys/sysctl.h> - -#include <arpa/inet.h> -#include <machine/elf.h> -#include <machine/vmparam.h> +#include <sys/linker_set.h> -#include <a.out.h> #include <err.h> #include <fcntl.h> -#include <kvm.h> -#include <limits.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> @@ -81,30 +72,21 @@ #include "extern.h" -static void core(int, int, struct kinfo_proc *); -static void datadump(int, int, struct kinfo_proc *, u_long, int); static void killed(int); static void restart_target(void); static void usage(void) __dead2; -static void userdump(int, struct kinfo_proc *, u_long, int); -kvm_t *kd; +static pid_t pid; -static int data_offset; -static pid_t pid; +SET_DECLARE(dumpset, struct dumpers); int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { - struct kinfo_proc *ki = NULL; - struct exec exec; int ch, cnt, efd, fd, sflag; - uid_t uid; char *binfile, *corefile; - char errbuf[_POSIX2_LINE_MAX], fname[MAXPATHLEN]; - int is_aout; + char fname[MAXPATHLEN]; + struct dumpers **d, *dumper; sflag = 0; corefile = NULL; @@ -123,7 +105,6 @@ } argv += optind; argc -= optind; - /* XXX we should check that the pid argument is really a number */ switch (argc) { case 1: @@ -139,54 +120,20 @@ default: usage(); } - efd = open(binfile, O_RDONLY, 0); if (efd < 0) err(1, "%s", binfile); - - cnt = read(efd, &exec, sizeof(exec)); - if (cnt != sizeof(exec)) - errx(1, "%s exec header: %s", - binfile, cnt > 0 ? strerror(EIO) : strerror(errno)); - if (!N_BADMAG(exec)) { - is_aout = 1; - /* - * This legacy a.out support uses the kvm interface instead - * of procfs. - */ - kd = kvm_openfiles(0, 0, 0, O_RDONLY, errbuf); - if (kd == NULL) - errx(1, "%s", errbuf); - - uid = getuid(); - - ki = kvm_getprocs(kd, KERN_PROC_PID, pid, &cnt); - if (ki == NULL || cnt != 1) - errx(1, "%d: not found", pid); - - if (ki->ki_ruid != uid && uid != 0) - errx(1, "%d: not owner", pid); - - if (ki->ki_stat == SZOMB) - errx(1, "%d: zombie", pid); - - if (ki->ki_flag & P_WEXIT) - errx(1, "%d: process exiting", pid); - if (ki->ki_flag & P_SYSTEM) /* Swapper or pagedaemon. */ - errx(1, "%d: system process", pid); - if (exec.a_text != ptoa(ki->ki_tsize)) - errx(1, "The executable %s does not belong to" - " process %d!\n" - "Text segment size (in bytes): executable %ld," - " process %d", binfile, pid, exec.a_text, - ptoa(ki->ki_tsize)); - data_offset = N_DATOFF(exec); - } else if (IS_ELF(*(Elf_Ehdr *)&exec)) { - is_aout = 0; - close(efd); - } else + dumper = NULL; + SET_FOREACH(d, dumpset) { + lseek(efd, 0, SEEK_SET); + if (((*d)->ident)(efd, pid, binfile)) { + dumper = (*d); + lseek(efd, 0, SEEK_SET); + break; + } + } + if (dumper == NULL) errx(1, "Invalid executable file"); - if (corefile == NULL) { (void)snprintf(fname, sizeof(fname), "core.%d", pid); corefile = fname; @@ -194,7 +141,6 @@ fd = open(corefile, O_RDWR|O_CREAT|O_TRUNC, DEFFILEMODE); if (fd < 0) err(1, "%s", corefile); - if (sflag) { signal(SIGHUP, killed); signal(SIGINT, killed); @@ -203,148 +149,32 @@ err(1, "%d: stop signal", pid); atexit(restart_target); } - - if (is_aout) - core(efd, fd, ki); - else - elf_coredump(fd, pid); - + dumper->dump(efd, fd, pid); (void)close(fd); + (void)close(efd); exit(0); } -/* - * core -- - * Build the core file. - */ -void -core(efd, fd, ki) - int efd; - int fd; - struct kinfo_proc *ki; -{ - union { - struct user user; - struct { - char uabytes[ctob(UAREA_PAGES)]; - char ksbytes[ctob(KSTACK_PAGES)]; - } bytes; - } uarea; - int tsize = ki->ki_tsize; - int dsize = ki->ki_dsize; - int ssize = ki->ki_ssize; - int cnt; - - /* Read in user struct */ - cnt = kvm_read(kd, (u_long)ki->ki_addr, uarea.bytes.uabytes, - ctob(UAREA_PAGES)); - if (cnt != ctob(UAREA_PAGES)) - errx(1, "read upages structure: %s", - cnt > 0 ? strerror(EIO) : strerror(errno)); - - cnt = kvm_read(kd, (u_long)ki->ki_kstack, uarea.bytes.ksbytes, - ctob(KSTACK_PAGES)); - if (cnt != ctob(KSTACK_PAGES)) - errx(1, "read kstack structure: %s", - cnt > 0 ? strerror(EIO) : strerror(errno)); - - /* - * Fill in the eproc vm parameters, since these are garbage unless - * the kernel is dumping core or something. - */ - uarea.user.u_kproc = *ki; - - /* Dump user area */ - cnt = write(fd, &uarea, sizeof(uarea)); - if (cnt != sizeof(uarea)) - errx(1, "write user structure: %s", - cnt > 0 ? strerror(EIO) : strerror(errno)); - - /* Dump data segment */ - datadump(efd, fd, ki, USRTEXT + ctob(tsize), dsize); - - /* Dump stack segment */ - userdump(fd, ki, USRSTACK - ctob(ssize), ssize); - - /* Dump machine dependent portions of the core. */ - md_core(kd, fd, ki); -} - -void -datadump(efd, fd, kp, addr, npage) - register int efd; - register int fd; - struct kinfo_proc *kp; - register u_long addr; - register int npage; +static void +killed(int sig) { - register int cc, delta; - char buffer[PAGE_SIZE]; - delta = data_offset - addr; - while (--npage >= 0) { - cc = kvm_uread(kd, kp, addr, buffer, PAGE_SIZE); - if (cc != PAGE_SIZE) { - /* Try to read the page from the executable. */ - if (lseek(efd, (off_t)addr + delta, SEEK_SET) == -1) - err(1, "seek executable"); - cc = read(efd, buffer, sizeof(buffer)); - if (cc != sizeof(buffer)) { - if (cc < 0) - err(1, "read executable"); - else /* Assume untouched bss page. */ - bzero(buffer, sizeof(buffer)); - } - } - cc = write(fd, buffer, PAGE_SIZE); - if (cc != PAGE_SIZE) - errx(1, "write data segment: %s", - cc > 0 ? strerror(EIO) : strerror(errno)); - addr += PAGE_SIZE; - } -} - -static void -killed(sig) - int sig; -{ restart_target(); signal(sig, SIG_DFL); kill(getpid(), sig); } static void -restart_target() +restart_target(void) { + kill(pid, SIGCONT); } void -userdump(fd, kp, addr, npage) - register int fd; - struct kinfo_proc *kp; - register u_long addr; - register int npage; +usage(void) { - register int cc; - char buffer[PAGE_SIZE]; - while (--npage >= 0) { - cc = kvm_uread(kd, kp, addr, buffer, PAGE_SIZE); - if (cc != PAGE_SIZE) - /* Could be an untouched fill-with-zero page. */ - bzero(buffer, PAGE_SIZE); - cc = write(fd, buffer, PAGE_SIZE); - if (cc != PAGE_SIZE) - errx(1, "write stack segment: %s", - cc > 0 ? strerror(EIO) : strerror(errno)); - addr += PAGE_SIZE; - } -} - -void -usage() -{ (void)fprintf(stderr, "usage: gcore [-s] [-c core] [executable] pid\n"); exit(1); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200209131826.g8DIQm1B006522>