Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 1 Aug 2006 16:15:33 GMT
From:      Howard Su <howardsu@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 102946 for review
Message-ID:  <200608011615.k71GFXZA005978@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=102946

Change 102946 by howardsu@su_vm on 2006/08/01 16:15:10

	handle the event returned from waitpid correctly.
	this close the race condition when catching the events.

Affected files ...

.. //depot/projects/dtrace/src/usr.bin/truss/setup.c#5 edit

Differences ...

==== //depot/projects/dtrace/src/usr.bin/truss/setup.c#5 (text+ko) ====

@@ -59,24 +59,6 @@
 #include "extern.h"
 
 
-static siginfo_t myinfo;
-
-static void handler(int si __unused, siginfo_t *info, void *uap __unused)
-{
-	memcpy(&myinfo, info, sizeof(myinfo));
-}
-
-static void
-installhandler(void)
-{
-	int error;
-	struct sigaction act;
-	act.sa_sigaction = handler;
-	act.sa_flags = SA_SIGINFO;
-	error = sigaction(SIGCHLD, &act, NULL);
-	if (error)
-		errx(1, "install signal failed");
-}
 /*
  * setup_and_wait() is called to start a process.  All it really does
  * is fork(), set itself up to stop on exec or exit, and then exec
@@ -89,18 +71,18 @@
 {
 	int pid;
 
-	installhandler();
-
-	pid = fork();
+	pid = vfork();
 	if (pid == -1) {
-		err(1, "fork failed");
+		err(1, "vfork failed");
 	}
 	if (pid == 0) {	/* Child */
 		ptrace(PT_TRACE_ME, 0, 0, 0);
+		setpgid (0, 0);	
 		execvp(command[0], command);
 		err(1, "execvp failed");
 	}
 
+	waitpid(pid, NULL, WNOHANG);
 	/* Only in the parent here */
 	return (pid);
 }
@@ -114,7 +96,6 @@
 int
 start_tracing(int pid)
 {
-	installhandler();
 	if (ptrace(PT_ATTACH, pid, NULL, 0))
 		err(1, "can not attach to target process");
 	return (0);
@@ -138,31 +119,38 @@
 	struct ptrace_lwpinfo lwpinfo;
 	
 	ptrace(PT_SYSCALL, info->pid, (caddr_t)1, 0);
-	if (waitpid(info->pid, &waitval, 0) == -1)
-		err(1, "unexpect stop");
-	switch(myinfo.si_code) {
-	case CLD_TRAPPED:
+	if (waitpid(info->pid, &waitval, WNOHANG) == -1) {
+		switch (errno)
+		{
+		case EINTR:
+			break;
+		default:
+			err(1, "failed");
+		}
+	}
+	if (WIFCONTINUED(waitval)) printf("WIFCONTINUED");
+	if (WIFEXITED(waitval)) {
+		info->pr_why = S_EXIT;
+		return;
+	}
+	if (WIFSIGNALED(waitval)) printf("WIFSIGNALED");
+	if (WIFSTOPPED(waitval)) {
 		ptrace(PT_LWPINFO, info->pid, (caddr_t)&lwpinfo, sizeof(lwpinfo));
 		info->tid = lwpinfo.pl_lwpid;
 		switch(lwpinfo.pl_event) {
 		case PL_EVENT_SYSENTER:
 			info->pr_why = S_SCE;
-			break;
-		case PL_EVENT_SYSEXIT:
-			info->pr_why = S_SCX;
-			break;
-		case PL_EVENT_SIGNAL:
-			info->pr_why = S_SIG;
-			info->pr_data = lwpinfo.pl_signal;
-			break;
-		default:
-			info->pr_why = S_NONE;
-		}
-		break;
-	case CLD_EXITED:
-		info->pr_why = S_EXIT;
-		break;
-	default:
-		info->pr_why = S_NONE;
+	        break;
+	    case PL_EVENT_SYSEXIT:
+	        info->pr_why = S_SCX;
+	        break;
+	    case PL_EVENT_SIGNAL:
+	    	info->pr_why = S_SIG;
+		    info->pr_data = lwpinfo.pl_signal;
+		    break;
+	    default:
+	        info->pr_why = S_NONE;
+	    }
+		return;
 	}
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200608011615.k71GFXZA005978>