diff -Naurp ltrace-0.4/ltrace.h ltrace-0.4-Getmsg/ltrace.h --- ltrace-0.4/ltrace.h 2006-02-20 16:48:07.000000000 -0500 +++ ltrace-0.4-Getmsg/ltrace.h 2006-07-18 02:23:36.000000000 -0400 @@ -12,6 +12,7 @@ #include "sysdep.h" #define MAX_LIBRARY 30 +#define TRACE_FORK 1 #if defined HAVE_LIBIBERTY || defined HAVE_LIBSUPC__ # define USE_DEMANGLE @@ -170,7 +171,7 @@ extern void show_summary(void); /* 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); @@ -198,5 +199,5 @@ extern void *plt2addr(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 ltrace-0.4/proc.c ltrace-0.4-Getmsg/proc.c --- ltrace-0.4/proc.c 2006-02-20 16:48:07.000000000 -0500 +++ ltrace-0.4-Getmsg/proc.c 2006-07-17 06:00:36.000000000 -0400 @@ -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; @@ -37,11 +38,13 @@ void open_pid(pid_t pid, int verbose) struct process *proc; char *filename; +#if 0 if (trace_pid(pid) < 0) { fprintf(stderr, "Cannot attach to pid %u: %s\n", pid, strerror(errno)); return; } +#endif filename = pid2name(pid); @@ -54,7 +57,6 @@ void open_pid(pid_t pid, int verbose) return; } #endif - proc = open_program(filename, pid); - proc->breakpoints_enabled = 1; + proc->breakpoints_enabled = -1; } diff -Naurp ltrace-0.4/process_event.c ltrace-0.4-Getmsg/process_event.c --- ltrace-0.4/process_event.c 2006-02-20 16:48:07.000000000 -0500 +++ ltrace-0.4-Getmsg/process_event.c 2006-07-18 03:05:16.000000000 -0400 @@ -223,16 +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) { - pid_t child = - gimme_arg(LT_TOF_SYSCALLR, event->proc, -1); - 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, diff -Naurp ltrace-0.4/sysdeps/linux-gnu/trace.c ltrace-0.4-Getmsg/sysdeps/linux-gnu/trace.c --- ltrace-0.4/sysdeps/linux-gnu/trace.c 2006-02-20 16:48:07.000000000 -0500 +++ ltrace-0.4-Getmsg/sysdeps/linux-gnu/trace.c 2006-07-18 02:49:35.000000000 -0400 @@ -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,10 +101,21 @@ 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 && - ptrace(PTRACE_OLDSETOPTIONS, 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; } @@ -175,3 +186,18 @@ 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 ltrace-0.4/wait_for_something.c ltrace-0.4-Getmsg/wait_for_something.c --- ltrace-0.4/wait_for_something.c 2006-02-20 16:48:07.000000000 -0500 +++ ltrace-0.4-Getmsg/wait_for_something.c 2006-07-18 02:32:26.000000000 -0400 @@ -14,15 +14,17 @@ #include "options.h" #include "debug.h" +#define FORK_MASK 0x00010000 static struct event event; /* This should also update `current_process' */ static struct process *pid2proc(int pid); +void verify(int sig_status); struct event *wait_for_something(void) { - pid_t pid; + pid_t pid, child_pid; int status; int tmp; @@ -54,7 +56,11 @@ struct event *wait_for_something(void) if (event.proc->breakpoints_enabled == -1) { enable_all_breakpoints(event.proc); 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 +98,17 @@ 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 = @@ -115,3 +132,4 @@ static struct process *pid2proc(pid_t pi } return NULL; } +