diff options
Diffstat (limited to 'usr.bin/gcore')
| -rw-r--r-- | usr.bin/gcore/Makefile | 3 | ||||
| -rw-r--r-- | usr.bin/gcore/elfcore.c | 514 | ||||
| -rw-r--r-- | usr.bin/gcore/extern.h | 4 | ||||
| -rw-r--r-- | usr.bin/gcore/gcore.c | 142 |
4 files changed, 60 insertions, 603 deletions
diff --git a/usr.bin/gcore/Makefile b/usr.bin/gcore/Makefile index 7f6a3eed905ac..664813febb927 100644 --- a/usr.bin/gcore/Makefile +++ b/usr.bin/gcore/Makefile @@ -1,8 +1,7 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 PROG= gcore -SRCS= elfcore.c gcore.c -CFLAGS+=-Wall +SRCS= gcore.c DPADD= ${LIBKVM} LDADD= -lkvm diff --git a/usr.bin/gcore/elfcore.c b/usr.bin/gcore/elfcore.c deleted file mode 100644 index af199ca8f705c..0000000000000 --- a/usr.bin/gcore/elfcore.c +++ /dev/null @@ -1,514 +0,0 @@ -/*- - * Copyright (c) 1998 John D. Polstra - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: elfcore.c,v 1.1 1998/10/19 19:42:18 jdp Exp $ - */ - -#include <sys/param.h> -#include <sys/lock.h> -#include <sys/procfs.h> -#include <vm/vm_param.h> -#include <vm/vm.h> -#include <vm/pmap.h> -#include <vm/vm_map.h> -#include <vm/vm_prot.h> -#include <elf.h> -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "extern.h" - -/* - * Code for generating ELF core dumps. - */ - -typedef void (*segment_callback)(vm_map_entry_t, void *); - -/* Closure for cb_put_phdr(). */ -struct phdr_closure { - Elf_Phdr *phdr; /* Program header to fill in */ - Elf_Off offset; /* Offset of segment in core file */ -}; - -/* Closure for cb_size_segment(). */ -struct sseg_closure { - int count; /* Count of writable segments. */ - size_t size; /* Total size of all writable segments. */ -}; - -static void cb_put_phdr(vm_map_entry_t, void *); -static void cb_size_segment(vm_map_entry_t, void *); -static void each_writable_segment(vm_map_entry_t, segment_callback, - void *closure); -static void elf_corehdr(int fd, pid_t, vm_map_entry_t, int numsegs, - void *hdr, size_t hdrsize); -static void elf_puthdr(vm_map_entry_t, void *, size_t *, - const prstatus_t *, const prfpregset_t *, const prpsinfo_t *, int numsegs); -static void elf_putnote(void *dst, size_t *off, const char *name, int type, - const void *desc, size_t descsz); -static void freemap(vm_map_entry_t); -static void readhdrinfo(pid_t, prstatus_t *, prfpregset_t *, prpsinfo_t *); -static vm_map_entry_t readmap(pid_t); - -/* - * Write an ELF coredump for the given pid to the given fd. - */ -void -elf_coredump(int fd, pid_t pid) -{ - vm_map_entry_t map; - struct sseg_closure seginfo; - void *hdr; - size_t hdrsize; - char memname[64]; - int memfd; - Elf_Phdr *php; - int i; - - /* Get the program's memory map. */ - map = readmap(pid); - - /* Size the program segments. */ - seginfo.count = 0; - seginfo.size = 0; - each_writable_segment(map, cb_size_segment, &seginfo); - - /* - * Calculate the size of the core file header area by making - * a dry run of generating it. Nothing is written, but the - * size is calculated. - */ - hdrsize = 0; - elf_puthdr(map, (void *)NULL, &hdrsize, - (const prstatus_t *)NULL, (const prfpregset_t *)NULL, - (const prpsinfo_t *)NULL, seginfo.count); - - /* - * Allocate memory for building the header, fill it up, - * and write it out. - */ - hdr = malloc(hdrsize); - if ((hdr = malloc(hdrsize)) == NULL) - errx(1, "out of memory"); - elf_corehdr(fd, pid, map, seginfo.count, hdr, hdrsize); - - /* Write the contents of all of the writable segments. */ - snprintf(memname, sizeof memname, "/proc/%d/mem", pid); - if ((memfd = open(memname, O_RDONLY)) == -1) - err(1, "cannot open %s", memname); - - php = (Elf_Phdr *)((char *)hdr + sizeof(Elf_Ehdr)) + 1; - for (i = 0; i < seginfo.count; i++) { - int nleft = php->p_filesz; - - lseek(memfd, (off_t)php->p_vaddr, SEEK_SET); - while (nleft > 0) { - char buf[8*1024]; - int nwant; - int ngot; - - nwant = nleft; - if (nwant > sizeof buf) - nwant = sizeof buf; - ngot = read(memfd, buf, nwant); - if (ngot == -1) - err(1, "read from %s", memname); - if (ngot < nwant) - errx(1, "short read from %s:" - " wanted %d, got %d\n", memname, - nwant, ngot); - ngot = write(fd, buf, nwant); - if (ngot == -1) - err(1, "write of segment %d failed", i); - if (ngot != nwant) - errx(1, "short write"); - nleft -= nwant; - } - php++; - } - close(memfd); - free(hdr); - freemap(map); -} - -/* - * A callback for each_writable_segment() to write out the segment's - * program header entry. - */ -static void -cb_put_phdr(vm_map_entry_t entry, void *closure) -{ - struct phdr_closure *phc = (struct phdr_closure *)closure; - Elf_Phdr *phdr = phc->phdr; - - phc->offset = round_page(phc->offset); - - phdr->p_type = PT_LOAD; - phdr->p_offset = phc->offset; - phdr->p_vaddr = entry->start; - phdr->p_paddr = 0; - phdr->p_filesz = phdr->p_memsz = entry->end - entry->start; - phdr->p_align = PAGE_SIZE; - phdr->p_flags = 0; - if (entry->protection & VM_PROT_READ) - phdr->p_flags |= PF_R; - if (entry->protection & VM_PROT_WRITE) - phdr->p_flags |= PF_W; - if (entry->protection & VM_PROT_EXECUTE) - phdr->p_flags |= PF_X; - - phc->offset += phdr->p_filesz; - phc->phdr++; -} - -/* - * A callback for each_writable_segment() to gather information about - * the number of segments and their total size. - */ -static void -cb_size_segment(vm_map_entry_t entry, void *closure) -{ - struct sseg_closure *ssc = (struct sseg_closure *)closure; - - ssc->count++; - ssc->size += entry->end - entry->start; -} - -/* - * For each segment in the given memory map, call the given function - * with a pointer to the map entry and some arbitrary caller-supplied - * data. - */ -static void -each_writable_segment(vm_map_entry_t map, segment_callback func, void *closure) -{ - vm_map_entry_t entry; - - for (entry = map; entry != NULL; entry = entry->next) - (*func)(entry, closure); -} - -/* - * Write the core file header to the file, including padding up to - * the page boundary. - */ -static void -elf_corehdr(int fd, pid_t pid, vm_map_entry_t map, int numsegs, void *hdr, - size_t hdrsize) -{ - size_t off; - prstatus_t status; - prfpregset_t fpregset; - prpsinfo_t psinfo; - - /* Gather the information for the header. */ - readhdrinfo(pid, &status, &fpregset, &psinfo); - - /* Fill in the header. */ - memset(hdr, 0, hdrsize); - off = 0; - elf_puthdr(map, hdr, &off, &status, &fpregset, &psinfo, numsegs); - - /* Write it to the core file. */ - if (write(fd, hdr, hdrsize) == -1) - err(1, "write"); -} - -/* - * Generate the ELF coredump header into the buffer at "dst". "dst" may - * be NULL, in which case the header is sized but not actually generated. - */ -static void -elf_puthdr(vm_map_entry_t map, void *dst, size_t *off, const prstatus_t *status, - const prfpregset_t *fpregset, const prpsinfo_t *psinfo, int numsegs) -{ - size_t ehoff; - size_t phoff; - size_t noteoff; - size_t notesz; - - ehoff = *off; - *off += sizeof(Elf_Ehdr); - - phoff = *off; - *off += (numsegs + 1) * sizeof(Elf_Phdr); - - noteoff = *off; - elf_putnote(dst, off, "FreeBSD", NT_PRSTATUS, status, - sizeof *status); - elf_putnote(dst, off, "FreeBSD", NT_FPREGSET, fpregset, - sizeof *fpregset); - elf_putnote(dst, off, "FreeBSD", NT_PRPSINFO, psinfo, - sizeof *psinfo); - notesz = *off - noteoff; - - /* Align up to a page boundary for the program segments. */ - *off = round_page(*off); - - if (dst != NULL) { - Elf_Ehdr *ehdr; - Elf_Phdr *phdr; - struct phdr_closure phc; - - /* - * Fill in the ELF header. - */ - ehdr = (Elf_Ehdr *)((char *)dst + ehoff); - ehdr->e_ident[EI_MAG0] = ELFMAG0; - ehdr->e_ident[EI_MAG1] = ELFMAG1; - ehdr->e_ident[EI_MAG2] = ELFMAG2; - ehdr->e_ident[EI_MAG3] = ELFMAG3; - ehdr->e_ident[EI_CLASS] = ELF_CLASS; - ehdr->e_ident[EI_DATA] = ELF_DATA; - ehdr->e_ident[EI_VERSION] = EV_CURRENT; - ehdr->e_ident[EI_PAD] = 0; - strncpy(ehdr->e_ident + EI_BRAND, "FreeBSD", - EI_NIDENT - EI_BRAND); - ehdr->e_type = ET_CORE; - ehdr->e_machine = ELF_ARCH; - ehdr->e_version = EV_CURRENT; - ehdr->e_entry = 0; - ehdr->e_phoff = phoff; - ehdr->e_flags = 0; - ehdr->e_ehsize = sizeof(Elf_Ehdr); - ehdr->e_phentsize = sizeof(Elf_Phdr); - ehdr->e_phnum = numsegs + 1; - ehdr->e_shentsize = sizeof(Elf_Shdr); - ehdr->e_shnum = 0; - ehdr->e_shstrndx = SHN_UNDEF; - - /* - * Fill in the program header entries. - */ - phdr = (Elf_Phdr *)((char *)dst + phoff); - - /* The note segement. */ - phdr->p_type = PT_NOTE; - phdr->p_offset = noteoff; - phdr->p_vaddr = 0; - phdr->p_paddr = 0; - phdr->p_filesz = notesz; - phdr->p_memsz = 0; - phdr->p_flags = 0; - phdr->p_align = 0; - phdr++; - - /* All the writable segments from the program. */ - phc.phdr = phdr; - phc.offset = *off; - each_writable_segment(map, cb_put_phdr, &phc); - } -} - -/* - * Emit one note section to "dst", or just size it if "dst" is NULL. - */ -static void -elf_putnote(void *dst, size_t *off, const char *name, int type, - const void *desc, size_t descsz) -{ - Elf_Note note; - - note.n_namesz = strlen(name) + 1; - note.n_descsz = descsz; - note.n_type = type; - if (dst != NULL) - bcopy(¬e, (char *)dst + *off, sizeof note); - *off += sizeof note; - if (dst != NULL) - bcopy(name, (char *)dst + *off, note.n_namesz); - *off += roundup2(note.n_namesz, sizeof(Elf_Size)); - if (dst != NULL) - bcopy(desc, (char *)dst + *off, note.n_descsz); - *off += roundup2(note.n_descsz, sizeof(Elf_Size)); -} - -/* - * Free the memory map. - */ -static void -freemap(vm_map_entry_t map) -{ - while (map != NULL) { - vm_map_entry_t next = map->next; - free(map); - map = next; - } -} - -/* - * Read the process information necessary to fill in the core file's header. - */ -static void -readhdrinfo(pid_t pid, prstatus_t *status, prfpregset_t *fpregset, - prpsinfo_t *psinfo) -{ - char name[64]; - char line[256]; - int fd; - int i; - int n; - - memset(status, 0, sizeof *status); - status->pr_version = PRSTATUS_VERSION; - status->pr_statussz = sizeof(prstatus_t); - status->pr_gregsetsz = sizeof(gregset_t); - status->pr_fpregsetsz = sizeof(fpregset_t); - status->pr_osreldate = __FreeBSD_version; - status->pr_pid = pid; - - memset(fpregset, 0, sizeof *fpregset); - - memset(psinfo, 0, sizeof *psinfo); - psinfo->pr_version = PRPSINFO_VERSION; - psinfo->pr_psinfosz = sizeof(prpsinfo_t); - - /* Read the general registers. */ - snprintf(name, sizeof name, "/proc/%d/regs", pid); - if ((fd = open(name, O_RDONLY)) == -1) - err(1, "cannot open %s", name); - if ((n = read(fd, &status->pr_reg, sizeof status->pr_reg)) == -1) - err(1, "read error from %s", name); - if (n < sizeof status->pr_reg) - errx(1, "short read from %s: wanted %u, got %d", name, - sizeof status->pr_reg, n); - close(fd); - - /* Read the floating point registers. */ - snprintf(name, sizeof name, "/proc/%d/fpregs", pid); - if ((fd = open(name, O_RDONLY)) == -1) - err(1, "cannot open %s", name); - if ((n = read(fd, fpregset, sizeof *fpregset)) == -1) - err(1, "read error from %s", name); - if (n < sizeof *fpregset) - errx(1, "short read from %s: wanted %u, got %d", name, - sizeof *fpregset, n); - close(fd); - - /* Read and parse the process status. */ - snprintf(name, sizeof name, "/proc/%d/status", pid); - if ((fd = open(name, O_RDONLY)) == -1) - err(1, "cannot open %s", name); - if ((n = read(fd, line, sizeof line - 1)) == -1) - err(1, "read error from %s", name); - if (n > MAXCOMLEN) - n = MAXCOMLEN; - for (i = 0; i < n && line[i] != ' '; i++) - psinfo->pr_fname[i] = line[i]; - strncpy(psinfo->pr_psargs, psinfo->pr_fname, PRARGSZ); - close(fd); -} - -/* - * Read the process's memory map using procfs, and return a list of - * VM map entries. Only the non-device read/writable segments are - * returned. The map entries in the list aren't fully filled in; only - * the items we need are present. - */ -static vm_map_entry_t -readmap(pid_t pid) -{ - char mapname[64]; - int mapfd; - ssize_t mapsize; - size_t bufsize; - char *mapbuf; - int pos; - vm_map_entry_t map; - vm_map_entry_t *linkp; - - snprintf(mapname, sizeof mapname, "/proc/%d/map", pid); - if ((mapfd = open(mapname, O_RDONLY)) == -1) - err(1, "cannot open %s", mapname); - - /* - * Procfs requires (for consistency) that the entire memory map - * be read with a single read() call. Start with a reasonbly sized - * buffer, and double it until it is big enough. - */ - bufsize = 8 * 1024; - mapbuf = NULL; - for ( ; ; ) { - if ((mapbuf = realloc(mapbuf, bufsize)) == NULL) - errx(1, "out of memory"); - mapsize = read(mapfd, mapbuf, bufsize); - if (mapsize != -1 || errno != EFBIG) - break; - bufsize *= 2; - /* This lseek shouldn't be necessary, but it is. */ - lseek(mapfd, (off_t)0, SEEK_SET); - } - if (mapsize == -1) - err(1, "read error from %s", mapname); - if (mapsize == 0) - errx(1, "empty map file %s", mapname); - close(mapfd); - - pos = 0; - map = NULL; - linkp = ↦ - while (pos < mapsize) { - vm_map_entry_t ent; - vm_offset_t start; - vm_offset_t end; - char prot[4]; - char type[16]; - int n; - int len; - - len = 0; - n = sscanf(mapbuf + pos, "%x %x %*d %*d %*d %3[-rwx]" - " %*d %*d %*x %*s %*s %16s%*[\n]%n", - &start, &end, prot, type, &len); - if (n != 4) - errx(1, "ill-formed line in %s", mapname); - pos += len; - - /* Ignore segments of the wrong kind, and unwritable ones */ - if (strncmp(prot, "rw", 2) != 0 || - (strcmp(type, "default") != 0 && - strcmp(type, "vnode") != 0 && - strcmp(type, "swap") != 0)) - continue; - - if ((ent = (vm_map_entry_t)calloc(1, sizeof *ent)) == NULL) - errx(1, "out of memory"); - ent->start = start; - ent->end = end; - ent->protection = VM_PROT_READ | VM_PROT_WRITE; - if (prot[2] == 'x') - ent->protection |= VM_PROT_EXECUTE; - - *linkp = ent; - linkp = &ent->next; - } - free(mapbuf); - return map; -} diff --git a/usr.bin/gcore/extern.h b/usr.bin/gcore/extern.h index f157e531a5f3a..3dccafe70845c 100644 --- a/usr.bin/gcore/extern.h +++ b/usr.bin/gcore/extern.h @@ -33,9 +33,5 @@ * @(#)extern.h 8.1 (Berkeley) 6/6/93 */ -#include <sys/types.h> -#include <kvm.h> - void err __P((int, const char *, ...)); -void elf_coredump __P((int, pid_t)); void md_core __P((kvm_t *, int, struct kinfo_proc *)); diff --git a/usr.bin/gcore/gcore.c b/usr.bin/gcore/gcore.c index 4702003b8afc1..8ab7b0bdbe613 100644 --- a/usr.bin/gcore/gcore.c +++ b/usr.bin/gcore/gcore.c @@ -42,7 +42,7 @@ static const char copyright[] = static char sccsid[] = "@(#)gcore.c 8.2 (Berkeley) 9/23/93"; #endif static const char rcsid[] = - "$Id: gcore.c,v 1.12 1998/10/22 04:02:37 jdp Exp $"; + "$Id: gcore.c,v 1.9 1998/09/14 10:09:30 des Exp $"; #endif /* not lint */ /* @@ -79,19 +79,17 @@ static const char rcsid[] = #include "extern.h" -static void core __P((int, int, struct kinfo_proc *)); -static void datadump __P((int, int, struct proc *, u_long, int)); -static void killed __P((int)); -static void restart_target __P((void)); -static void usage __P((void)) __dead2; -static void userdump __P((int, struct proc *, u_long, int)); +void core __P((int, int, struct kinfo_proc *)); +void datadump __P((int, int, struct proc *, u_long, int)); +void usage __P((void)); +void userdump __P((int, struct proc *, u_long, int)); kvm_t *kd; /* XXX undocumented routine, should be in kvm.h? */ ssize_t kvm_uread __P((kvm_t *, const struct proc *, u_long, char *, size_t)); + static int data_offset; -static pid_t pid; int main(argc, argv) @@ -99,12 +97,11 @@ main(argc, argv) char *argv[]; { register struct proc *p; - struct kinfo_proc *ki = NULL; + struct kinfo_proc *ki; struct exec exec; - int ch, cnt, efd, fd, sflag, uid; + int ch, cnt, efd, fd, pid, sflag, uid; char *binfile, *corefile; char errbuf[_POSIX2_LINE_MAX], fname[MAXPATHLEN + 1]; - int is_aout; sflag = 0; corefile = NULL; @@ -140,53 +137,27 @@ main(argc, argv) usage(); } - efd = open(binfile, O_RDONLY, 0); - if (efd < 0) - err(1, "%s", binfile); + kd = kvm_openfiles(0, 0, 0, O_RDONLY, errbuf); + if (kd == NULL) + errx(1, "%s", errbuf); - 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); - - p = &ki->kp_proc; - if (ki->kp_eproc.e_pcred.p_ruid != uid && uid != 0) - errx(1, "%d: not owner", pid); - - if (p->p_stat == SZOMB) - errx(1, "%d: zombie", pid); - - if (p->p_flag & P_WEXIT) - errx(1, "%d: process exiting", pid); - if (p->p_flag & P_SYSTEM) /* Swapper or pagedaemon. */ - errx(1, "%d: system process", pid); - if (exec.a_text != ptoa(ki->kp_eproc.e_vm.vm_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->kp_eproc.e_vm.vm_tsize)); - data_offset = N_DATOFF(exec); - } else if (IS_ELF(*(Elf_Ehdr *)&exec)) { - is_aout = 0; - close(efd); - } else - errx(1, "Invalid executable file"); + uid = getuid(); + + ki = kvm_getprocs(kd, KERN_PROC_PID, pid, &cnt); + if (ki == NULL || cnt != 1) + errx(1, "%d: not found", pid); + + p = &ki->kp_proc; + if (ki->kp_eproc.e_pcred.p_ruid != uid && uid != 0) + errx(1, "%d: not owner", pid); + + if (p->p_stat == SZOMB) + errx(1, "%d: zombie", pid); + + if (p->p_flag & P_WEXIT) + errx(1, "%d: process exiting", pid); + if (p->p_flag & P_SYSTEM) /* Swapper or pagedaemon. */ + errx(1, "%d: system process", pid); if (corefile == NULL) { (void)snprintf(fname, sizeof(fname), "core.%d", pid); @@ -196,21 +167,41 @@ main(argc, argv) if (fd < 0) err(1, "%s", corefile); - if (sflag) { - signal(SIGHUP, killed); - signal(SIGINT, killed); - signal(SIGTERM, killed); - if (kill(pid, SIGSTOP) == -1) - err(1, "%d: stop signal", pid); - atexit(restart_target); + 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)) { + const Elf_Ehdr *ehdr = (const Elf_Ehdr *)&exec; + + if (IS_ELF(*ehdr)) + errx(1, "ELF executables are not supported yet"); + errx(1, "Invalid executable file"); } - if (is_aout) - core(efd, fd, ki); - else - elf_coredump(fd, pid); + /* check the text segment size of the executable and the process */ + if (exec.a_text != ptoa(ki->kp_eproc.e_vm.vm_tsize)) + errx(1, + "The executable %s does not belong to process %d!\n" + "Text segment size (in bytes): executable %d, process %d", + binfile, pid, exec.a_text, + ptoa(ki->kp_eproc.e_vm.vm_tsize)); + + data_offset = N_DATOFF(exec); + + if (sflag && kill(pid, SIGSTOP) < 0) + err(1, "%d: stop signal", pid); + core(efd, fd, ki); + + if (sflag && kill(pid, SIGCONT) < 0) + err(1, "%d: continue signal", pid); (void)close(fd); + exit(0); } @@ -295,21 +286,6 @@ datadump(efd, fd, p, addr, npage) } } -static void -killed(sig) - int sig; -{ - restart_target(); - signal(sig, SIG_DFL); - kill(getpid(), sig); -} - -static void -restart_target() -{ - kill(pid, SIGCONT); -} - void userdump(fd, p, addr, npage) register int fd; |
