Browse Source

Plan 9 from Bell Labs 2011-07-15

David du Colombier 12 years ago
parent
commit
6f96eacdc2
1 changed files with 65 additions and 22 deletions
  1. 65 22
      sys/src/cmd/ratrace.c

+ 65 - 22
sys/src/cmd/ratrace.c

@@ -29,19 +29,35 @@ die(char *s)
 void
 cwrite(int fd, char *path, char *cmd, int len)
 {
+	werrstr("");
 	if (write(fd, cmd, len) < len) {
-		fprint(2, "cwrite: %s: failed %d bytes: %r\n", path, len);
+		fprint(2, "cwrite: %s: failed writing %d bytes: %r\n",
+			path, len);
 		sendp(quit, nil);
 		threadexits(nil);
 	}
 }
 
+Str *
+newstr(void)
+{
+	Str *s;
+
+	s = mallocz(sizeof(Str) + Bufsize, 1);
+	if (s == nil)
+		sysfatal("malloc");
+	s->buf = (char *)&s[1];
+	return s;
+}
+
 void
 reader(void *v)
 {
-	int cfd, tfd, forking = 0, pid, newpid;
+	int cfd, tfd, forking = 0, exiting, pid, newpid;
 	char *ctl, *truss;
 	Str *s;
+	static char start[] = "start";
+	static char waitstop[] = "waitstop";
 
 	pid = (int)(uintptr)v;
 	ctl = smprint("/proc/%d/ctl", pid);
@@ -51,12 +67,13 @@ reader(void *v)
 	if ((tfd = open(truss, OREAD)) < 0)
 		die(smprint("%s: %r", truss));
 
-	cwrite(cfd, ctl, "stop", 4);
-	cwrite(cfd, truss, "startsyscall", 12);
+	/* child was stopped by hang msg earlier */
+	cwrite(cfd, ctl, waitstop, sizeof waitstop - 1);
 
-	s = mallocz(sizeof(Str) + Bufsize, 1);
-	s->buf = (char *)&s[1];
-	while((s->len = pread(tfd, s->buf, Bufsize - 1, 0)) > 0){
+	cwrite(cfd, ctl, "startsyscall", 12);
+	s = newstr();
+	exiting = 0;
+	while((s->len = pread(tfd, s->buf, Bufsize - 1, 0)) >= 0){
 		if (forking && s->buf[1] == '=' && s->buf[3] != '-') {
 			forking = 0;
 			newpid = strtol(&s->buf[3], 0, 0);
@@ -73,20 +90,26 @@ reader(void *v)
 			char *rf;
 
 			rf = strdup(s->buf);
-         		if (tokenize(rf, a, 8) == 5) {
-				ulong flags;
-
-				flags = strtoul(a[4], 0, 16);
-				if (flags & RFPROC)
-					forking = 1;
-			}
+         		if (tokenize(rf, a, 8) == 5 &&
+			    strtoul(a[4], 0, 16) & RFPROC)
+				forking = 1;
 			free(rf);
+		} else if (strstr(s->buf, " Exits") != nil)
+			exiting = 1;
+
+		sendp(out, s);	/* print line from /proc/$child/syscall */
+		if (exiting) {
+			s = newstr();
+			strcpy(s->buf, "\n");
+			sendp(out, s);
+			break;
 		}
-		sendp(out, s);
-		cwrite(cfd, truss, "startsyscall", 12);
-		s = mallocz(sizeof(Str) + Bufsize, 1);
-		s->buf = (char *)&s[1];
+
+		/* flush syscall trace buffer */
+		cwrite(cfd, ctl, "startsyscall", 12);
+		s = newstr();
 	}
+
 	sendp(quit, nil);
 	threadexitsall(nil);
 }
@@ -111,17 +134,17 @@ writer(void *)
 
 	for(;;)
 		switch(alt(a)){
-		case 0:
+		case 0:			/* quit */
 			nread--;
 			if(nread <= 0)
 				goto done;
 			break;
-		case 1:
+		case 1:			/* out */
 			/* it's a nice null terminated thing */
 			fprint(2, "%s", s->buf);
 			free(s);
 			break;
-		case 2:
+		case 2:			/* forkc */
 			// procrfork(reader, (void*)newpid, Stacksize, 0);
 			nread++;
 			break;
@@ -137,6 +160,22 @@ usage(void)
 	exits("usage");
 }
 
+void
+hang(void)
+{
+	int me;
+	char *myctl;
+	static char hang[] = "hang";
+
+	myctl = smprint("/proc/%d/ctl", getpid());
+	me = open(myctl, OWRITE);
+	if (me < 0)
+		sysfatal("can't open %s: %r", myctl);
+	cwrite(me, myctl, hang, sizeof hang - 1);
+	close(me);
+	free(myctl);
+}
+
 void
 threadmain(int argc, char **argv)
 {
@@ -151,7 +190,7 @@ threadmain(int argc, char **argv)
 	 */
 	if (argc < 2)
 		usage();
-	if (argv[1][0] == '-')
+	while (argv[1][0] == '-') {
 		switch(argv[1][1]) {
 		case 'c':
 			if (argc < 3)
@@ -162,6 +201,9 @@ threadmain(int argc, char **argv)
 		default:
 			usage();
 		}
+		++argv;
+		--argc;
+	}
 
 	/* run a command? */
 	if(cmd) {
@@ -169,6 +211,7 @@ threadmain(int argc, char **argv)
 		if (pid < 0)
 			sysfatal("fork failed: %r");
 		if(pid == 0) {
+			hang();
 			exec(cmd, args);
 			if(cmd[0] != '/')
 				exec(smprint("/bin/%s", cmd), args);