xref: /netbsd-src/usr.bin/gcore/gcore.c (revision 684b182f813418fbf004008a32d738baa45c875a)
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