svn commit: r203532 - head/usr.bin/gcore

Matt Jacob mjacob at FreeBSD.org
Fri Feb 5 18:28:44 UTC 2010


Author: mjacob
Date: Fri Feb  5 18:28:43 2010
New Revision: 203532
URL: http://svn.freebsd.org/changeset/base/203532

Log:
  Fix gcore so that it can have the '-s' flag without hanging.

Modified:
  head/usr.bin/gcore/extern.h
  head/usr.bin/gcore/gcore.c

Modified: head/usr.bin/gcore/extern.h
==============================================================================
--- head/usr.bin/gcore/extern.h	Fri Feb  5 18:17:17 2010	(r203531)
+++ head/usr.bin/gcore/extern.h	Fri Feb  5 18:28:43 2010	(r203532)
@@ -38,3 +38,4 @@ struct dumpers {
 	int (*ident)(int efd, pid_t pid, char *binfile);
 	void (*dump)(int efd, int fd, pid_t pid);
 };
+extern int sflag;

Modified: head/usr.bin/gcore/gcore.c
==============================================================================
--- head/usr.bin/gcore/gcore.c	Fri Feb  5 18:17:17 2010	(r203531)
+++ head/usr.bin/gcore/gcore.c	Fri Feb  5 18:28:43 2010	(r203532)
@@ -65,16 +65,15 @@ __FBSDID("$FreeBSD$");
 
 #include <err.h>
 #include <fcntl.h>
-#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
 #include "extern.h"
+int sflag;
 
 static void	killed(int);
-static void	restart_target(void);
 static void	usage(void) __dead2;
 
 static pid_t pid;
@@ -84,7 +83,7 @@ SET_DECLARE(dumpset, struct dumpers);
 int
 main(int argc, char *argv[])
 {
-	int ch, efd, fd, name[4], sflag;
+	int ch, efd, fd, name[4];
 	char *binfile, *corefile;
 	char passpath[MAXPATHLEN], fname[MAXPATHLEN];
 	struct dumpers **d, *dumper;
@@ -148,36 +147,28 @@ main(int argc, char *argv[])
 	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);
-		signal(SIGTERM, killed);
-		if (kill(pid, SIGSTOP) == -1)
-			err(1, "%d: stop signal", pid);
-		atexit(restart_target);
-	}
+	/*
+	 * The semantics of the 's' flag is to stop the target process.
+	 * Previous versions of gcore would manage this by trapping SIGHUP,
+	 * SIGINT and SIGTERM (to be passed to the target pid), and then
+	 * signal the child to stop.
+	 *
+	 * However, this messes up if the selected dumper uses ptrace calls
+	 * that leave the child already stopped. The waitpid call in elfcore
+	 * never returns.
+	 *
+	 * The best thing to do here is to externalize the 's' flag and let
+	 * each dumper dispose of what that means, if anything. For the elfcore
+	 * dumper, the 's' flag is a no-op since the ptrace attach stops the
+	 * process in question already.
+	 */
+
 	dumper->dump(efd, fd, pid);
 	(void)close(fd);
 	(void)close(efd);
 	exit(0);
 }
 
-static void
-killed(int sig)
-{
-
-	restart_target();
-	signal(sig, SIG_DFL);
-	kill(getpid(), sig);
-}
-
-static void
-restart_target(void)
-{
-
-	kill(pid, SIGCONT);
-}
-
 void
 usage(void)
 {


More information about the svn-src-all mailing list