[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