[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