Commit fb88a01c authored by Russ Cox's avatar Russ Cox

marginally better thread debugging on Linux.

if you clone inside a traced pid, the child
is automatically attached and stopped,
apparently.

R=r
DELTA=63  (41 added, 12 deleted, 10 changed)
OCL=24096
CL=24106
parent b67603df
......@@ -28,6 +28,8 @@
// THE SOFTWARE.
#include <u.h>
#include <sys/syscall.h> /* for tkill */
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/signal.h>
#include <sys/wait.h>
......@@ -53,8 +55,10 @@ struct user_regs_struct {
unsigned long ds,es,fs,gs;
};
// return pid's state letter or -1 on error.
// set *tpid to tracer pid
static int
isstopped(int pid)
procstate(int pid, int *tpid)
{
char buf[1024];
int fd, n;
......@@ -62,21 +66,31 @@ isstopped(int pid)
snprint(buf, sizeof buf, "/proc/%d/stat", pid);
if((fd = open(buf, OREAD)) < 0)
return 0;
return -1;
n = read(fd, buf, sizeof buf-1);
close(fd);
if(n <= 0)
return 0;
return -1;
buf[n] = 0;
/* command name is in parens, no parens afterward */
p = strrchr(buf, ')');
if(p == nil || *++p != ' ')
return 0;
return -1;
++p;
/* next is state - T is stopped for tracing */
return *p == 'T';
/* p is now state letter. p+1 is tracer pid */
if(tpid)
*tpid = atoi(p+1);
return *p;
}
static int
attached(int pid)
{
int tpid;
return procstate(pid, &tpid) == 'T' && tpid == pid;
}
static int
......@@ -84,13 +98,17 @@ waitstop(int pid)
{
int p, status;
if(isstopped(pid))
p = procstate(pid, nil);
if(p < 0)
return -1;
if(p == 'T')
return 0;
for(;;){
p = waitpid(pid, &status, WUNTRACED|__WALL);
if(p <= 0){
if(errno == ECHILD){
if(isstopped(pid))
if(procstate(pid, nil) == 'T')
return 0;
}
return -1;
......@@ -116,7 +134,7 @@ ptraceattach(int pid)
return -1;
}
if(ptrace(PTRACE_ATTACH, pid, 0, 0) < 0){
if(!attached(pid) && ptrace(PTRACE_ATTACH, pid, 0, 0) < 0){
werrstr("ptrace attach %d: %r", pid);
return -1;
}
......@@ -296,7 +314,7 @@ ctlproc(int pid, char *msg)
return waitstop(pid);
}
if(strcmp(msg, "stop") == 0){
if(kill(pid, SIGSTOP) < 0)
if(syscall(__NR_tkill, pid, SIGSTOP) < 0)
return -1;
return waitstop(pid);
}
......@@ -526,8 +544,19 @@ ptraceerr:
char*
procstatus(int pid)
{
if(isstopped(pid))
return "Stopped";
int c;
c = procstate(pid, nil);
if(c < 0)
return "Dead";
switch(c) {
case 'T':
return "Stopped";
case 'Z':
return "Zombie";
case 'R':
return "Running";
// TODO: translate more characters here
}
return "Running";
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment