diff options
| author | Mattias Andrée <maandree@kth.se> | 2020-05-30 23:18:42 +0200 | 
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2020-05-30 23:18:42 +0200 | 
| commit | b3b9cf7dc1912c4df8c9d8dd740144dab8050bff (patch) | |
| tree | 0d945745dc9644910c184dd93bf4ad1c29b5ee4c | |
| parent | Do not print PID numbers if only configured to trace one thread (diff) | |
| download | sctrace-b3b9cf7dc1912c4df8c9d8dd740144dab8050bff.tar.gz sctrace-b3b9cf7dc1912c4df8c9d8dd740144dab8050bff.tar.bz2 sctrace-b3b9cf7dc1912c4df8c9d8dd740144dab8050bff.tar.xz  | |
Add support for tracing threads
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
| -rw-r--r-- | common.h | 3 | ||||
| -rw-r--r-- | sctrace.c | 16 | ||||
| -rw-r--r-- | util.c | 15 | 
3 files changed, 26 insertions, 8 deletions
@@ -67,8 +67,10 @@ enum type {  enum state {  	Normal,  	Syscall, +	CloneChild,  	ForkChild,  	VforkChild, +	CloneParent,  	ForkParent,  	VforkParent,  	Exec @@ -76,6 +78,7 @@ enum state {  struct process {  	pid_t pid; +	pid_t thread_group_leader;  	struct process *next;  	struct process *prev;  	enum state state; @@ -8,7 +8,7 @@ char *argv0;  static void  usage(void)  { -	fprintf(stderr, "usage: %s [-o trace-output-file] [-f] (command | -0 command argv0) [argument] ...\n", argv0); +	fprintf(stderr, "usage: %s [-o trace-output-file] [-ft] (command | -0 command argv0) [argument] ...\n", argv0);  	exit(1);  } @@ -42,6 +42,7 @@ handle_syscall(struct process *proc)  		break;  	case Syscall: +	case CloneParent:  	case ForkParent:  		/* Get system call result */  		if (ptrace(PTRACE_GETREGS, proc->pid, NULL, ®s)) @@ -82,6 +83,7 @@ handle_syscall(struct process *proc)  		proc->state = Syscall;  		break; +	case CloneChild:  	case ForkChild:  	case VforkChild:  		tprintf(proc, "= 0\n"); @@ -104,7 +106,6 @@ main(int argc, char **argv)  	struct process *proc, *proc2;  	unsigned long int event; -	/* TODO add option to trace threads (-t) */  	/* TODO add option to trace signals (-s) */  	ARGBEGIN {  	case '0': @@ -118,6 +119,9 @@ main(int argc, char **argv)  	case 'f':  		trace_options |= PTRACE_O_TRACEFORK;  		trace_options |= PTRACE_O_TRACEVFORK; +		/* fall through */ +	case 't': +		trace_options |= PTRACE_O_TRACECLONE;  		multiprocess = 1;  		break;  	default: @@ -226,20 +230,24 @@ have_outfp:  					tprintf(proc, "\nProcess stopped by vfork until child exits or exec(2)s\n");  					/* fall thought */  				case PTRACE_EVENT_FORK: +				case PTRACE_EVENT_CLONE:  					if (ptrace(PTRACE_GETEVENTMSG, proc->pid, NULL, &event))  						eprintf("ptrace PTRACE_GETEVENTMSG %ju NULL <buffer>:", (uintmax_t)proc->pid);  					proc2 = add_process((pid_t)event, trace_options); +					if (trace_event == PTRACE_EVENT_CLONE) +						proc2->thread_group_leader = proc->pid;  					proc->ret = event;  					if (trace_event == PTRACE_EVENT_VFORK) {  						proc2->continue_on_exit = proc;  						proc->vfork_waiting_on = proc2;  						proc->state = VforkParent;  					} else { -						proc->state = ForkParent; +						proc->state = trace_event == PTRACE_EVENT_CLONE ? CloneParent : ForkParent;  						handle_syscall(proc);  					}  					tprintf(proc2, "\nTracing new process\n"); -					proc2->state = trace_event == PTRACE_EVENT_FORK ? ForkChild : VforkChild; +					proc2->state = trace_event == PTRACE_EVENT_FORK ? ForkChild : +					               trace_event == PTRACE_EVENT_VFORK ? VforkChild : CloneChild;  					handle_syscall(proc2);  					break; @@ -25,10 +25,17 @@ tprintf(struct process *proc, const char *fmt, ...)  		fmt = &fmt[1];  	}  	if (multiproctrace) { -		if (last_char == '\n') -			fprintf(trace_fp, "[%ju] ", (uintmax_t)proc->pid); -		else if (proc->pid != last_pid) -			fprintf(trace_fp, "\n[%ju] ", (uintmax_t)proc->pid); +		if (proc->thread_group_leader) { +			if (last_char == '\n') +				fprintf(trace_fp, "[%ju, %ju] ", (uintmax_t)proc->thread_group_leader, (uintmax_t)proc->pid); +			else if (proc->pid != last_pid) +				fprintf(trace_fp, "\n[%ju, %ju] ", (uintmax_t)proc->thread_group_leader, (uintmax_t)proc->pid); +		} else { +			if (last_char == '\n') +				fprintf(trace_fp, "[%ju] ", (uintmax_t)proc->pid); +			else if (proc->pid != last_pid) +				fprintf(trace_fp, "\n[%ju] ", (uintmax_t)proc->pid); +		}  	}  	va_start(ap, fmt);  	vfprintf(trace_fp, fmt, ap);  | 
