1 1.12 mrg /* $NetBSD: gcore.c,v 1.12 2019/02/01 08:29:04 mrg Exp $ */ 2 1.2 tls 3 1.1 tls /*- 4 1.4 christos * Copyright (c) 2003 The NetBSD Foundation, Inc. 5 1.4 christos * All rights reserved. 6 1.4 christos * 7 1.4 christos * This code is derived from software contributed to The NetBSD Foundation 8 1.4 christos * by Christos Zoulas. 9 1.1 tls * 10 1.1 tls * Redistribution and use in source and binary forms, with or without 11 1.1 tls * modification, are permitted provided that the following conditions 12 1.1 tls * are met: 13 1.1 tls * 1. Redistributions of source code must retain the above copyright 14 1.1 tls * notice, this list of conditions and the following disclaimer. 15 1.1 tls * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 tls * notice, this list of conditions and the following disclaimer in the 17 1.1 tls * documentation and/or other materials provided with the distribution. 18 1.1 tls * 19 1.4 christos * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.4 christos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.4 christos * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.4 christos * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.4 christos * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.4 christos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.4 christos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.4 christos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.4 christos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.4 christos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.4 christos * POSSIBILITY OF SUCH DAMAGE. 30 1.1 tls */ 31 1.1 tls 32 1.4 christos #include <sys/cdefs.h> 33 1.12 mrg __RCSID("$NetBSD: gcore.c,v 1.12 2019/02/01 08:29:04 mrg Exp $"); 34 1.4 christos 35 1.4 christos #include <sys/types.h> 36 1.1 tls #include <sys/param.h> 37 1.1 tls #include <sys/time.h> 38 1.4 christos #include <sys/ptrace.h> 39 1.1 tls #include <sys/proc.h> 40 1.9 christos #include <sys/wait.h> 41 1.1 tls 42 1.4 christos #include <stdio.h> 43 1.8 christos #include <string.h> 44 1.4 christos #include <err.h> 45 1.1 tls #include <limits.h> 46 1.1 tls #include <stdlib.h> 47 1.1 tls #include <unistd.h> 48 1.4 christos #include <errno.h> 49 1.1 tls 50 1.10 perry static void usage(void) __dead; 51 1.1 tls 52 1.4 christos static void 53 1.4 christos usage(void) 54 1.4 christos { 55 1.8 christos (void)fprintf(stderr, "Usage: %s [-c <corename>] <pid> [<pid> ...]\n", 56 1.8 christos getprogname()); 57 1.4 christos exit(1); 58 1.4 christos } 59 1.1 tls 60 1.1 tls 61 1.1 tls int 62 1.4 christos main(int argc, char **argv) 63 1.1 tls { 64 1.4 christos int c; 65 1.8 christos char *corename = NULL; 66 1.8 christos int corelen = 0; 67 1.4 christos 68 1.8 christos while ((c = getopt(argc, argv, "c:")) != -1) 69 1.4 christos switch (c) { 70 1.8 christos case 'c': 71 1.8 christos corename = optarg; 72 1.8 christos corelen = strlen(corename); 73 1.8 christos break; 74 1.4 christos case '?': 75 1.1 tls default: 76 1.1 tls usage(); 77 1.4 christos /*NOTREACHED*/ 78 1.1 tls } 79 1.1 tls 80 1.4 christos if (optind == argc) 81 1.1 tls usage(); 82 1.1 tls 83 1.4 christos for (c = optind; c < argc; c++) { 84 1.4 christos char *ep; 85 1.9 christos u_long lval; 86 1.9 christos int status, serrno; 87 1.9 christos pid_t pid, cpid; 88 1.4 christos 89 1.6 lukem errno = 0; 90 1.9 christos lval = strtoul(argv[c], &ep, 0); 91 1.12 mrg if (argv[c] == NULL || *ep) 92 1.4 christos errx(1, "`%s' is not a number.", argv[c]); 93 1.9 christos 94 1.9 christos if (errno == ERANGE && lval == ULONG_MAX) 95 1.4 christos err(1, "Pid `%s'", argv[c]); 96 1.9 christos 97 1.9 christos pid = (pid_t)lval; 98 1.9 christos 99 1.9 christos if (ptrace(PT_ATTACH, pid, 0, 0) == -1) 100 1.9 christos err(1, "ptrace(PT_ATTACH) to %lu failed", lval); 101 1.9 christos 102 1.9 christos if ((cpid = waitpid(pid, &status, 0)) != pid) { 103 1.9 christos serrno = errno; 104 1.9 christos (void)ptrace(PT_DETACH, pid, (void *)1, 0); 105 1.9 christos errno = serrno; 106 1.9 christos if (cpid == -1) 107 1.9 christos err(1, "Cannot wait for %lu", lval); 108 1.9 christos else 109 1.9 christos errx(1, "Unexpected process %lu waited", 110 1.9 christos (unsigned long)cpid); 111 1.9 christos } 112 1.9 christos 113 1.9 christos if (ptrace(PT_DUMPCORE, pid, corename, corelen) == -1) { 114 1.9 christos serrno = errno; 115 1.9 christos (void)ptrace(PT_DETACH, pid, (void *)1, 0); 116 1.9 christos errno = serrno; 117 1.9 christos err(1, "ptrace(PT_DUMPCORE) to %lu failed", lval); 118 1.9 christos } 119 1.9 christos if (ptrace(PT_DETACH, pid, (void *)1, 0) == -1) 120 1.9 christos err(1, "ptrace(PT_DETACH) to %lu failed", lval); 121 1.1 tls } 122 1.4 christos return 0; 123 1.1 tls } 124