[Ltrace-devel] Re: [Fwd: Patch for tracing fork]

supriya kannery supriyak at in.ibm.com
Tue Dec 12 11:13:42 CET 2006


Olaf Hering wrote:

>Just run 'make && make check', you need expect, dejagnu etc installed.       
>  
>
Honouring -x option:
The make check errors were because of not honouring "-x" option. Please 
find the modified patch for fork that honours -x option.
Here, the parent process (the process traced by ltrace) will be 
honouring -x option. Its forked children are not going to
honour this option.

Honouring -X option:
In ppc64, -X option is not working fine with trunk-69 and found that the 
name of the procedure read in readelf() is appended with "@@GLIBC_2.0"
to the actual procedure names. When I give "-X wait" the output is 
incorrect. But when I give "-X wait@@GLIBC_2.0" the output is
displayed correctly.

Please let me know your comments for the patch for fork.
Thanks, Supriya


-------------- next part --------------
diff -Naurp trunk/execute_program.c trunk-fork/execute_program.c
--- trunk/execute_program.c	2006-12-05 16:50:52.000000000 +0530
+++ trunk-fork/execute_program.c	2006-12-11 16:59:55.000000000 +0530
@@ -17,6 +17,8 @@
 #include "debug.h"
 #include "sysdep.h"
 
+pid_t parent_process_pid = 0;
+
 static void change_uid(struct process *proc)
 {
 	uid_t run_uid, run_euid;
@@ -91,6 +93,7 @@ void execute_program(struct process *sp,
 	debug(1, "PID=%d", pid);
 
 	sp->pid = pid;
+        parent_process_pid = pid;
 
 	return;
 }
diff -Naurp trunk/ltrace.c trunk-fork/ltrace.c
--- trunk/ltrace.c	2006-12-05 16:50:52.000000000 +0530
+++ trunk-fork/ltrace.c	2006-12-11 16:58:25.000000000 +0530
@@ -97,6 +97,8 @@ int main(int argc, char **argv)
 	struct opt_p_t *opt_p_tmp;
 
 	atexit(normal_exit);
+	int options = 0;
+
 	signal(SIGINT, signal_exit);	/* Detach processes when interrupted */
 	signal(SIGTERM, signal_exit);	/*  ... or killed */
 
@@ -133,7 +135,8 @@ int main(int argc, char **argv)
 	}
 	opt_p_tmp = opt_p;
 	while (opt_p_tmp) {
-		open_pid(opt_p_tmp->pid, 1);
+		options = P_OPTION_SET | VERBOSE;
+		open_pid(opt_p_tmp->pid, options);
 		opt_p_tmp = opt_p_tmp->next;
 	}
 	while (1) {
diff -Naurp trunk/ltrace.h trunk-fork/ltrace.h
--- trunk/ltrace.h	2006-12-05 16:50:52.000000000 +0530
+++ trunk-fork/ltrace.h	2006-12-11 16:59:55.000000000 +0530
@@ -12,13 +12,17 @@
 #include "sysdep.h"
 
 #define MAX_LIBRARY	30
+#define TRACE_FORK	1
+#define VERBOSE	0x00000001
+#define P_OPTION_SET	0x00000002
+
 
 #if defined HAVE_LIBIBERTY || defined HAVE_LIBSUPC__
 # define USE_DEMANGLE
 #endif
 
 extern char *command;
-
+extern pid_t parent_process_pid;
 extern int exiting;		/* =1 if we have to exit ASAP */
 
 struct breakpoint {
@@ -229,7 +233,7 @@ extern arg_type_info *lookup_prototype(e
 
 /* Arch-dependent stuff: */
 extern char *pid2name(pid_t pid);
-extern void trace_set_options(struct process *proc, pid_t pid);
+extern void trace_set_options(struct process *proc, pid_t pid, int option);
 extern void trace_me(void);
 extern int trace_pid(pid_t pid);
 extern void untrace_pid(pid_t pid);
@@ -258,5 +262,5 @@ extern void *sym2addr(struct process *, 
 #if 0				/* not yet */
 extern int umoven(struct process *proc, void *addr, int len, void *laddr);
 #endif
-
+extern ulong get_child_pid(pid_t pid);
 #endif
diff -Naurp trunk/proc.c trunk-fork/proc.c
--- trunk/proc.c	2006-12-05 16:50:52.000000000 +0530
+++ trunk-fork/proc.c	2006-12-11 16:58:25.000000000 +0530
@@ -22,25 +22,28 @@ struct process *open_program(char *filen
 	}
 	proc->filename = filename;
 	proc->breakpoints_enabled = -1;
+	proc->pid = 0;
+	breakpoints_init(proc);
 	if (pid) {
 		proc->pid = pid;
 	}
-	breakpoints_init(proc);
-
 	proc->next = list_of_processes;
 	list_of_processes = proc;
 	return proc;
 }
 
-void open_pid(pid_t pid, int verbose)
+void open_pid(pid_t pid, int options)
+
 {
 	struct process *proc;
 	char *filename;
 
-	if (trace_pid(pid) < 0) {
-		fprintf(stderr, "Cannot attach to pid %u: %s\n", pid,
+	if(options & P_OPTION_SET){
+		if ((trace_pid(pid) < 0) && (options & VERBOSE)){
+			fprintf(stderr, "Cannot attach to pid %u: %s\n", pid,
 			strerror(errno));
-		return;
+			return;
+		}
 	}
 
 	filename = pid2name(pid);
@@ -56,5 +59,5 @@ void open_pid(pid_t pid, int verbose)
 #endif
 
 	proc = open_program(filename, pid);
-	proc->breakpoints_enabled = 1;
+	proc->breakpoints_enabled = -1;
 }
diff -Naurp trunk/process_event.c trunk-fork/process_event.c
--- trunk/process_event.c	2006-12-05 16:50:52.000000000 +0530
+++ trunk-fork/process_event.c	2006-12-11 16:59:55.000000000 +0530
@@ -223,19 +223,6 @@ static void process_sysret(struct event 
 	if (opt_T || opt_c) {
 		calc_time_spent(event->proc);
 	}
-	if (fork_p(event->proc, event->e_un.sysnum)) {
-		if (opt_f) {
-			arg_type_info info;
-			info.arg_num = -1; /* Return value */
-			info.type = ARGTYPE_LONG;
-			pid_t child =
-			    gimme_arg(LT_TOF_SYSCALLR, event->proc, &info);
-			if (child > 0) {
-				open_pid(child, 0);
-			}
-		}
-		enable_all_breakpoints(event->proc);
-	}
 	callstack_pop(event->proc);
 	if (opt_S) {
 		output_right(LT_TOF_SYSCALLR, event->proc,
@@ -354,7 +341,8 @@ static void process_breakpoint(struct ev
 		output_left(LT_TOF_FUNCTION, event->proc, sbp->libsym->name);
 		callstack_push_symfunc(event->proc, sbp->libsym);
 #ifdef PLT_REINITALISATION_BP
-		if (event->proc->need_to_reinitialize_breakpoints
+		if (event->proc->pid == parent_process_pid 
+                    && event->proc->need_to_reinitialize_breakpoints
 		    && (strcmp(sbp->libsym->name, PLTs_initialized_by_here) ==
 			0))
 			reinitialize_breakpoints(event->proc);
diff -Naurp trunk/sysdeps/linux-gnu/trace.c trunk-fork/sysdeps/linux-gnu/trace.c
--- trunk/sysdeps/linux-gnu/trace.c	2006-12-05 16:50:02.000000000 +0530
+++ trunk-fork/sysdeps/linux-gnu/trace.c	2006-12-11 16:58:25.000000000 +0530
@@ -90,7 +90,7 @@ int trace_pid(pid_t pid)
 	return 0;
 }
 
-void trace_set_options(struct process *proc, pid_t pid)
+void trace_set_options(struct process *proc, pid_t pid, int option)
 {
 #ifndef PTRACE_SETOPTIONS
 #define PTRACE_SETOPTIONS 0x4200
@@ -101,9 +101,20 @@ void trace_set_options(struct process *p
 #ifndef PTRACE_O_TRACESYSGOOD
 #define PTRACE_O_TRACESYSGOOD 0x00000001
 #endif
+#ifndef PTRACE_O_TRACEFORK
+#define PTRACE_O_TRACEFORK 0x00000002
+#endif
+
+	ulong setoptions = 0;
+
 	if (proc->tracesysgood & 0x80)
 		return;
-	if (ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACESYSGOOD) < 0 &&
+
+	setoptions |= PTRACE_O_TRACESYSGOOD;
+	if (TRACE_FORK == option){
+		setoptions |= PTRACE_O_TRACEFORK;
+	}
+	if (ptrace(PTRACE_SETOPTIONS, pid, 0, setoptions) < 0 &&
 	    ptrace(PTRACE_OLDSETOPTIONS, pid, 0, PTRACE_O_TRACESYSGOOD) < 0) {
 		perror("PTRACE_SETOPTIONS");
 		return;
@@ -193,3 +204,19 @@ int umovestr(struct process *proc, void 
 	*(char *)(laddr + offset) = '\0';
 	return 0;
 }
+
+ulong get_child_pid(pid_t pid)
+{
+#ifndef PTRACE_GETEVENTMSG
+#define PTRACE_GETEVENTMSG 0x4201
+#endif
+	ulong child_pid = 9999;
+
+	if( ptrace(PTRACE_GETEVENTMSG, pid, 0, &child_pid) < 0) {
+		perror("PTRACE_GETEVENTMSG");
+		return 0;
+	}
+	return child_pid;
+}
+
+
diff -Naurp trunk/wait_for_something.c trunk-fork/wait_for_something.c
--- trunk/wait_for_something.c	2006-12-05 16:50:52.000000000 +0530
+++ trunk-fork/wait_for_something.c	2006-12-11 16:59:55.000000000 +0530
@@ -14,6 +14,7 @@
 #include "options.h"
 #include "debug.h"
 
+#define FORK_MASK 0x00010000
 static struct event event;
 
 /* This should also update `current_process' */
@@ -22,7 +23,7 @@ static struct process *pid2proc(int pid)
 
 struct event *wait_for_something(void)
 {
-	pid_t pid;
+	pid_t pid, child_pid;
 	int status;
 	int tmp;
 
@@ -51,10 +52,24 @@ struct event *wait_for_something(void)
 	get_arch_dep(event.proc);
 	event.proc->instruction_pointer = NULL;
 	debug(3, "signal from pid %u", pid);
+       
 	if (event.proc->breakpoints_enabled == -1) {
-		enable_all_breakpoints(event.proc);
+
+                event.proc->breakpoints_enabled = 0;
+                if(parent_process_pid != event.proc->pid){
+#ifdef PLT_REINITALISATION_BP
+        		reinitialize_breakpoints(event.proc);
+	        	event.proc->breakpoints_enabled = 1;
+#else
+		        enable_all_breakpoints(event.proc);
+#endif
+		}
 		event.thing = LT_EV_NONE;
-		trace_set_options(event.proc, event.proc->pid);
+		if(opt_f){
+			trace_set_options(event.proc, event.proc->pid, TRACE_FORK);
+		}else{
+			trace_set_options(event.proc, event.proc->pid, 0);
+		}
 		continue_process(event.proc->pid);
 		return &event;
 	}
@@ -92,6 +107,18 @@ struct event *wait_for_something(void)
 		event.e_un.signum = WSTOPSIG(status);
 		return &event;
 	}
+	if((WSTOPSIG(status) == SIGTRAP) && (status & FORK_MASK)) {
+		event.thing = LT_EV_NONE;
+		event.e_un.signum = WSTOPSIG(status);
+		child_pid = (pid_t) get_child_pid(event.proc->pid);
+		if (child_pid){
+			open_pid(child_pid,0);
+		}
+		enable_all_breakpoints(event.proc);
+		continue_after_signal(event.proc->pid, event.e_un.signum);
+		return &event;
+	}
+
 	event.thing = LT_EV_BREAKPOINT;
 	if (!event.proc->instruction_pointer) {
 		event.proc->instruction_pointer =


More information about the Ltrace-devel mailing list