Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1:kernel-2.6.32
ltrace
ltrace.trunk-r77.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File ltrace.trunk-r77.patch of Package ltrace
------------------------------------------------------------------------ r77 | pmachata-guest | 2007-05-17 14:24:15 +0000 (Thu, 17 May 2007) | 5 lines Changed paths: M /ltrace/trunk/ChangeLog M /ltrace/trunk/breakpoints.c M /ltrace/trunk/ltrace.h M /ltrace/trunk/process_event.c M /ltrace/trunk/sysdeps/linux-gnu/trace.c A /ltrace/trunk/testsuite/ltrace.minor/trace-exec.c A /ltrace/trunk/testsuite/ltrace.minor/trace-exec.exp A /ltrace/trunk/testsuite/ltrace.minor/trace-exec1.c M /ltrace/trunk/wait_for_something.c * Based on work of Supriya Kannery <supriyak@in.ibm.com> * wait_for_something.c, process_event.c: Tracing across exec. * sysdeps/linux-gnu/trace.c, ltrace.h: New interface was_exec. * testsuite/ltrace.minor/trace-exec.c, testsuite/ltrace.minor/trace-exec.exp, testsuite/ltrace.minor/trace-exec1.c: Testcase for same. ------------------------------------------------------------------------ Index: ChangeLog =================================================================== --- ChangeLog (revision 76) +++ ChangeLog (revision 77) @@ -1,3 +1,12 @@ +2007-05-10 Petr Machata <pmachata@redhat.com> + + * Based on work of Supriya Kannery <supriyak@in.ibm.com> + * wait_for_something.c, process_event.c: Tracing across exec. + * sysdeps/linux-gnu/trace.c, ltrace.h: New interface was_exec. + * testsuite/ltrace.minor/trace-exec.c, + testsuite/ltrace.minor/trace-exec.exp, + testsuite/ltrace.minor/trace-exec1.c: Testcase for same. + 2007-05-09 Petr Machata <pmachata@redhat.com> * wait_for_something.c (wait_for_something): Interpret SIGILL, Index: testsuite/ltrace.minor/trace-exec1.c =================================================================== --- testsuite/ltrace.minor/trace-exec1.c (revision 0) +++ testsuite/ltrace.minor/trace-exec1.c (revision 77) @@ -0,0 +1,6 @@ +#include <stdio.h> +int main (void) +{ + puts("Hello, World."); + return 0; +} Index: testsuite/ltrace.minor/trace-exec.c =================================================================== --- testsuite/ltrace.minor/trace-exec.c (revision 0) +++ testsuite/ltrace.minor/trace-exec.c (revision 77) @@ -0,0 +1,8 @@ +#include <unistd.h> +#include <stdlib.h> + +int main (int argc, char ** argv) +{ + execl (argv[1], argv[1], NULL); + abort (); +} Index: testsuite/ltrace.minor/trace-exec.exp =================================================================== --- testsuite/ltrace.minor/trace-exec.exp (revision 0) +++ testsuite/ltrace.minor/trace-exec.exp (revision 77) @@ -0,0 +1,45 @@ +set testfile "trace-exec" +set srcfile ${testfile}.c +set binfile ${testfile} + +verbose "compiling first source file now....." +if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/${binfile}" executable {debug} ] != "" } { + send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" +} + +verbose "compiling second source file now....." +if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}1.c" "${srcdir}/${subdir}/${binfile}1" executable {debug} ] != "" } { + send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" +} + +global LTRACE +set exec_output "" + +#Run PUT for ltarce. +spawn $LTRACE -f $srcdir/$subdir/$testfile $srcdir/$subdir/${testfile}1 +set timeout 4 +expect timeout { + fail "Time out! Maybe caused by ltrace segment fault or improper timeout value here!" + return +} + +catch "exec $LTRACE -f $srcdir/$subdir/$testfile $srcdir/$subdir/${testfile}1" exec_output + +#check the output of this program. +verbose "ltrace runtest output: $exec_output\n" +if [regexp {ELF from incompatible architecture} $exec_output] { + fail "32-bit ltrace can not perform on 64-bit PUTs and rebuild ltrace in 64 bit mode!" + return +} elseif [ regexp {Couldn't get .hash data} $exec_output ] { + fail "Couldn't get .hash data!" + return +} + +ltrace_saveoutput "${exec_output}" ${srcdir}/${subdir}/${testfile}.ltrace + +# execl from first binary +ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace {"^execl"} 1 +# puts from second binary +ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace {"^puts"} 1 +# assume glibc and see we really trace both binaries +ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace {"^__libc_start_main"} 2 Index: sysdeps/linux-gnu/trace.c =================================================================== --- sysdeps/linux-gnu/trace.c (revision 76) +++ sysdeps/linux-gnu/trace.c (revision 77) @@ -11,6 +11,34 @@ #include "ltrace.h" #include "options.h" #include "sysdep.h" +#include "debug.h" + +/* If the system headers did not provide the constants, hard-code the normal + values. */ +#ifndef PTRACE_EVENT_FORK + +#define PTRACE_OLDSETOPTIONS 21 +#define PTRACE_SETOPTIONS 0x4200 +#define PTRACE_GETEVENTMSG 0x4201 + +/* options set using PTRACE_SETOPTIONS */ +#define PTRACE_O_TRACESYSGOOD 0x00000001 +#define PTRACE_O_TRACEFORK 0x00000002 +#define PTRACE_O_TRACEVFORK 0x00000004 +#define PTRACE_O_TRACECLONE 0x00000008 +#define PTRACE_O_TRACEEXEC 0x00000010 +#define PTRACE_O_TRACEVFORKDONE 0x00000020 +#define PTRACE_O_TRACEEXIT 0x00000040 + +/* Wait extended result codes for the above trace options. */ +#define PTRACE_EVENT_FORK 1 +#define PTRACE_EVENT_VFORK 2 +#define PTRACE_EVENT_CLONE 3 +#define PTRACE_EVENT_EXEC 4 +#define PTRACE_EVENT_VFORK_DONE 5 +#define PTRACE_EVENT_EXIT 6 + +#endif /* PTRACE_EVENT_FORK */ static int fork_exec_syscalls[][5] = { { @@ -75,6 +103,39 @@ int exec_p(struct process *proc, int sys return 0; } +/* Check that we just hit an exec. + */ +int was_exec(struct process *proc, int status) +{ + if (!WIFSTOPPED (status)) + return 0; + + if (WSTOPSIG (status) == SIGTRAP + && (status >> 16) == PTRACE_EVENT_EXEC) { + debug (1, "detected exec (PTRACE_EVENT_EXEC)"); + return 1; + } + + if (WSTOPSIG (status) == SIGTRAP + && proc->callstack_depth > 0) { + /* Check whether this SIGTRAP is received just after + execve is called for this process. Ideally we'd + like to check that the exec succeeded, but e.g. on + s390 we have no way of knowing, because return + value is not set to -1 (as it should). Never mind, + reseting breakpoints for current process doesn't + hurt. */ + struct callstack_element *elem; + elem = &proc->callstack[proc->callstack_depth - 1]; + if (elem && elem->is_syscall && exec_p(proc, elem->c_un.syscall)) { + debug (1, "detected exec (callstack)"); + return 1; + } + } + + return 0; +} + void trace_me(void) { if (ptrace(PTRACE_TRACEME, 0, 1, 0) < 0) { @@ -103,19 +164,12 @@ int trace_pid(pid_t pid) void trace_set_options(struct process *proc, pid_t pid) { -#ifndef PTRACE_SETOPTIONS -#define PTRACE_SETOPTIONS 0x4200 -#endif -#ifndef PTRACE_OLDSETOPTIONS -#define PTRACE_OLDSETOPTIONS 21 -#endif -#ifndef PTRACE_O_TRACESYSGOOD -#define PTRACE_O_TRACESYSGOOD 0x00000001 -#endif if (proc->tracesysgood & 0x80) return; - if (ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACESYSGOOD) < 0 && - ptrace(PTRACE_OLDSETOPTIONS, pid, 0, PTRACE_O_TRACESYSGOOD) < 0) { + + long options = PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEEXEC; + if (ptrace(PTRACE_SETOPTIONS, pid, 0, options) < 0 && + ptrace(PTRACE_OLDSETOPTIONS, pid, 0, options) < 0) { perror("PTRACE_SETOPTIONS"); return; } Index: ltrace.h =================================================================== --- ltrace.h (revision 76) +++ ltrace.h (revision 77) @@ -242,6 +242,7 @@ extern void enable_breakpoint(pid_t pid, extern void disable_breakpoint(pid_t pid, const struct breakpoint *sbp); extern int fork_p(struct process *proc, int sysnum); extern int exec_p(struct process *proc, int sysnum); +extern int was_exec(struct process *proc, int status); extern int syscall_p(struct process *proc, int status, int *sysnum); extern void continue_process(pid_t pid); extern void continue_after_signal(pid_t pid, int signum); Index: process_event.c =================================================================== --- process_event.c (revision 76) +++ process_event.c (revision 77) @@ -185,10 +185,7 @@ static void process_syscall(struct event output_left(LT_TOF_SYSCALL, event->proc, sysname(event->proc, event->e_un.sysnum)); } - if (fork_p(event->proc, event->e_un.sysnum) - || exec_p(event->proc, event->e_un.sysnum)) { - disable_all_breakpoints(event->proc); - } else if (event->proc->breakpoints_enabled == 0) { + if (event->proc->breakpoints_enabled == 0) { enable_all_breakpoints(event->proc); } callstack_push_syscall(event->proc, event->e_un.sysnum); @@ -241,25 +238,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); } Index: breakpoints.c =================================================================== --- breakpoints.c (revision 76) +++ breakpoints.c (revision 77) @@ -158,7 +158,6 @@ void breakpoints_init(struct process *pr struct library_symbol *sym; if (proc->breakpoints) { /* let's remove that struct */ - /* TODO FIXME XXX: free() all "struct breakpoint"s */ dict_apply_to_all(proc->breakpoints, free_bp_cb, NULL); dict_clear(proc->breakpoints); proc->breakpoints = NULL; Index: wait_for_something.c =================================================================== --- wait_for_something.c (revision 76) +++ wait_for_something.c (revision 77) @@ -114,6 +114,25 @@ struct event *wait_for_something(void) event.e_un.signum = stop_signal; return &event; } + + if (was_exec(event.proc, status)) { + pid_t saved_pid; + + event.thing = LT_EV_NONE; + event.e_un.signum = WSTOPSIG(status); + debug(1, "Placing breakpoints for the new program"); + 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_process(event.proc->pid); + return &event; + } + event.thing = LT_EV_BREAKPOINT; if (!event.proc->instruction_pointer) { event.proc->instruction_pointer =
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor