1*684b182fSmrg /* $NetBSD: gcore.c,v 1.12 2019/02/01 08:29:04 mrg Exp $ */
28dd56584Schristos
38dd56584Schristos /*-
48dd56584Schristos * Copyright (c) 2003 The NetBSD Foundation, Inc.
58dd56584Schristos * All rights reserved.
68dd56584Schristos *
78dd56584Schristos * This code is derived from software contributed to The NetBSD Foundation
88dd56584Schristos * by Christos Zoulas.
98dd56584Schristos *
108dd56584Schristos * Redistribution and use in source and binary forms, with or without
118dd56584Schristos * modification, are permitted provided that the following conditions
128dd56584Schristos * are met:
138dd56584Schristos * 1. Redistributions of source code must retain the above copyright
148dd56584Schristos * notice, this list of conditions and the following disclaimer.
158dd56584Schristos * 2. Redistributions in binary form must reproduce the above copyright
168dd56584Schristos * notice, this list of conditions and the following disclaimer in the
178dd56584Schristos * documentation and/or other materials provided with the distribution.
188dd56584Schristos *
198dd56584Schristos * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
208dd56584Schristos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
218dd56584Schristos * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
228dd56584Schristos * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
238dd56584Schristos * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
248dd56584Schristos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
258dd56584Schristos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
268dd56584Schristos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
278dd56584Schristos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
288dd56584Schristos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
298dd56584Schristos * POSSIBILITY OF SUCH DAMAGE.
308dd56584Schristos */
318dd56584Schristos
328dd56584Schristos #include <sys/cdefs.h>
33*684b182fSmrg __RCSID("$NetBSD: gcore.c,v 1.12 2019/02/01 08:29:04 mrg Exp $");
348dd56584Schristos
358dd56584Schristos #include <sys/types.h>
368dd56584Schristos #include <sys/param.h>
378dd56584Schristos #include <sys/time.h>
388dd56584Schristos #include <sys/ptrace.h>
398dd56584Schristos #include <sys/proc.h>
4046c0b8e9Schristos #include <sys/wait.h>
418dd56584Schristos
428dd56584Schristos #include <stdio.h>
43089038b4Schristos #include <string.h>
448dd56584Schristos #include <err.h>
458dd56584Schristos #include <limits.h>
468dd56584Schristos #include <stdlib.h>
478dd56584Schristos #include <unistd.h>
488dd56584Schristos #include <errno.h>
498dd56584Schristos
508b0f9554Sperry static void usage(void) __dead;
518dd56584Schristos
528dd56584Schristos static void
usage(void)538dd56584Schristos usage(void)
548dd56584Schristos {
55089038b4Schristos (void)fprintf(stderr, "Usage: %s [-c <corename>] <pid> [<pid> ...]\n",
56089038b4Schristos getprogname());
578dd56584Schristos exit(1);
588dd56584Schristos }
598dd56584Schristos
608dd56584Schristos
618dd56584Schristos int
main(int argc,char ** argv)628dd56584Schristos main(int argc, char **argv)
638dd56584Schristos {
648dd56584Schristos int c;
65089038b4Schristos char *corename = NULL;
66089038b4Schristos int corelen = 0;
678dd56584Schristos
68089038b4Schristos while ((c = getopt(argc, argv, "c:")) != -1)
698dd56584Schristos switch (c) {
70089038b4Schristos case 'c':
71089038b4Schristos corename = optarg;
72089038b4Schristos corelen = strlen(corename);
73089038b4Schristos break;
748dd56584Schristos case '?':
758dd56584Schristos default:
768dd56584Schristos usage();
778dd56584Schristos /*NOTREACHED*/
788dd56584Schristos }
798dd56584Schristos
808dd56584Schristos if (optind == argc)
818dd56584Schristos usage();
828dd56584Schristos
838dd56584Schristos for (c = optind; c < argc; c++) {
848dd56584Schristos char *ep;
8546c0b8e9Schristos u_long lval;
8646c0b8e9Schristos int status, serrno;
8746c0b8e9Schristos pid_t pid, cpid;
888dd56584Schristos
89ef83aa34Slukem errno = 0;
9046c0b8e9Schristos lval = strtoul(argv[c], &ep, 0);
91*684b182fSmrg if (argv[c] == NULL || *ep)
928dd56584Schristos errx(1, "`%s' is not a number.", argv[c]);
9346c0b8e9Schristos
9446c0b8e9Schristos if (errno == ERANGE && lval == ULONG_MAX)
958dd56584Schristos err(1, "Pid `%s'", argv[c]);
9646c0b8e9Schristos
9746c0b8e9Schristos pid = (pid_t)lval;
9846c0b8e9Schristos
9946c0b8e9Schristos if (ptrace(PT_ATTACH, pid, 0, 0) == -1)
10046c0b8e9Schristos err(1, "ptrace(PT_ATTACH) to %lu failed", lval);
10146c0b8e9Schristos
10246c0b8e9Schristos if ((cpid = waitpid(pid, &status, 0)) != pid) {
10346c0b8e9Schristos serrno = errno;
10446c0b8e9Schristos (void)ptrace(PT_DETACH, pid, (void *)1, 0);
10546c0b8e9Schristos errno = serrno;
10646c0b8e9Schristos if (cpid == -1)
10746c0b8e9Schristos err(1, "Cannot wait for %lu", lval);
10846c0b8e9Schristos else
10946c0b8e9Schristos errx(1, "Unexpected process %lu waited",
11046c0b8e9Schristos (unsigned long)cpid);
11146c0b8e9Schristos }
11246c0b8e9Schristos
11346c0b8e9Schristos if (ptrace(PT_DUMPCORE, pid, corename, corelen) == -1) {
11446c0b8e9Schristos serrno = errno;
11546c0b8e9Schristos (void)ptrace(PT_DETACH, pid, (void *)1, 0);
11646c0b8e9Schristos errno = serrno;
11746c0b8e9Schristos err(1, "ptrace(PT_DUMPCORE) to %lu failed", lval);
11846c0b8e9Schristos }
11946c0b8e9Schristos if (ptrace(PT_DETACH, pid, (void *)1, 0) == -1)
12046c0b8e9Schristos err(1, "ptrace(PT_DETACH) to %lu failed", lval);
1218dd56584Schristos }
1228dd56584Schristos return 0;
1238dd56584Schristos }
124