[Ltrace-devel] Patch for tracing exec

supriya kannery supriyak at in.ibm.com
Mon Oct 16 13:26:07 UTC 2006


Hello Ian,
     While trying out different programs with trunk-68 level, observed 
that ltrace is not able to trace properly a new process created by 
"exec" call. Output is showing "unexpected breakpoints" and library 
calls of the new process is not getting displayed in ppc64.

I have prepared a patch for this using PTRACE_O_TRACEEXEC option. Tested 
this in ppc64 architecture with no make check errors.

Man page of execve says "There shall be no return from  a successful 
exec, because the calling process image is overlaid by the new process 
image".  In S390 arch, the return value of execve is not predictable. In 
ppc64, the program is not even hitting Sys_ret of execve. So instead of 
having the processing of exec in process_sysret(), moved that block to 
wait_for_something.c file. I was intending to use the following 
explained in man page, to capture the event of execl getting executed.

PTRACE_O_TRACEEXEC (since Linux 2.5.46)
                     Stop the child at the next exec()  call  with  
SIGTRAP  | PTRACE_EVENT_EXEC << 8.

But unfortunately ltrace is not getting this signal. SIGTRAP is not 
getting modified as mentioned here during an execl call.  Hence for now, 
for confirming whether the SIGTRAP received by ltrace is the one after 
execution of  an execl call, the last entry in the system call stack in 
used.
Please let me know your comments on this patch.

Thanks & Rgds, Supriya
-------------- next part --------------
diff -Naurp trunk/proc.c trunk-mod/proc.c
--- trunk/proc.c	2006-09-25 13:13:11.000000000 +0530
+++ trunk-mod/proc.c	2006-10-16 17:50:46.000000000 +0530
@@ -22,10 +22,11 @@ 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;
@@ -56,5 +57,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-mod/process_event.c
--- trunk/process_event.c	2006-09-25 13:13:11.000000000 +0530
+++ trunk-mod/process_event.c	2006-10-16 17:41:17.000000000 +0530
@@ -241,25 +241,6 @@ static void process_sysret(struct event 
 		output_right(LT_TOF_SYSCALLR, event->proc,
 			     sysname(event->proc, event->e_un.sysnum));
 	}
-	if (exec_p(event->proc, event->e_un.sysnum)) {
-		arg_type_info info;
-		info.arg_num = -1; /* Return value */
-		info.type = ARGTYPE_LONG;
-		if (gimme_arg(LT_TOF_SYSCALLR, event->proc, &info) == 0) {
-			pid_t saved_pid;
-			event->proc->mask_32bit = 0;
-			event->proc->personality = 0;
-			/* FIXME: Leak, should have arch_dep_free.
-			   But we are leaking here much more than that.  */
-			event->proc->arch_ptr = NULL;
-			event->proc->filename = pid2name(event->proc->pid);
-			saved_pid = event->proc->pid;
-			event->proc->pid = 0;
-			breakpoints_init(event->proc);
-			event->proc->pid = saved_pid;
-		} else
-			enable_all_breakpoints(event->proc);
-	}
 	continue_process(event->proc->pid);
 }
 
diff -Naurp trunk/sysdeps/linux-gnu/trace.c trunk-mod/sysdeps/linux-gnu/trace.c
--- trunk/sysdeps/linux-gnu/trace.c	2006-09-25 13:12:53.000000000 +0530
+++ trunk-mod/sysdeps/linux-gnu/trace.c	2006-10-16 17:42:50.000000000 +0530
@@ -101,9 +101,12 @@ void trace_set_options(struct process *p
 #ifndef PTRACE_O_TRACESYSGOOD
 #define PTRACE_O_TRACESYSGOOD 0x00000001
 #endif
+#ifndef PTRACE_O_TRACEEXEC
+#define PTRACE_O_TRACEEXEC 0x00000010
+#endif
 	if (proc->tracesysgood & 0x80)
 		return;
-	if (ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACESYSGOOD) < 0 &&
+	if (ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEEXEC) < 0 &&
 	    ptrace(PTRACE_OLDSETOPTIONS, pid, 0, PTRACE_O_TRACESYSGOOD) < 0) {
 		perror("PTRACE_SETOPTIONS");
 		return;
diff -Naurp trunk/wait_for_something.c trunk-mod/wait_for_something.c
--- trunk/wait_for_something.c	2006-09-25 13:13:11.000000000 +0530
+++ trunk-mod/wait_for_something.c	2006-10-16 17:50:02.000000000 +0530
@@ -92,6 +92,29 @@ struct event *wait_for_something(void)
 		event.e_un.signum = WSTOPSIG(status);
 		return &event;
 	}
+	if (WSTOPSIG(status) == SIGTRAP){
+	/* Check whether this SIGTRAP is received just after execve is called for this process */
+		struct callstack_element *elem;
+
+		elem = &event.proc->callstack[event.proc->callstack_depth - 1];
+		if( elem && elem->is_syscall &&  exec_p(event.proc, elem->c_un.syscall)){
+			pid_t saved_pid;
+
+			event.thing = LT_EV_NONE;
+			event.e_un.signum = WSTOPSIG(status);
+			event.proc->mask_32bit = 0;
+			event.proc->personality = 0;
+			event.proc->arch_ptr = NULL;
+			event.proc->filename = pid2name(event.proc->pid);
+			saved_pid = event.proc->pid;
+			event.proc->pid = 0;
+			breakpoints_init(event.proc);
+			event.proc->pid = saved_pid;
+			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