From 768acb96008d4169a554d78240a86873af77510b Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Fri, 4 May 2007 17:51:03 +0000 Subject: [PATCH] - added fork/exec patches, mostly IBM's work - added trace-exec tests into suite - added ia64 sigill patch --- ltrace-0.5-exec-tests.patch | 74 +++++++++++++++++ ltrace-0.5-exec.patch | 56 +++++++++++++ ltrace-0.5-fork.patch | 75 +++++++++++++++++ ltrace-0.5-ia64-sigill.patch | 157 +++++++++++++++++++++++++++++++++++ ltrace.spec | 17 +++- 5 files changed, 377 insertions(+), 2 deletions(-) create mode 100644 ltrace-0.5-exec-tests.patch create mode 100644 ltrace-0.5-exec.patch create mode 100644 ltrace-0.5-fork.patch create mode 100644 ltrace-0.5-ia64-sigill.patch diff --git a/ltrace-0.5-exec-tests.patch b/ltrace-0.5-exec-tests.patch new file mode 100644 index 0000000..e992d8c --- /dev/null +++ b/ltrace-0.5-exec-tests.patch @@ -0,0 +1,74 @@ +diff -BurpN ltrace-0.5-orig/testsuite/ltrace.minor/trace-exec1.c ltrace-0.5/testsuite/ltrace.minor/trace-exec1.c +--- ltrace-0.5-orig/testsuite/ltrace.minor/trace-exec1.c 1969-12-31 19:00:00.000000000 -0500 ++++ ltrace-0.5/testsuite/ltrace.minor/trace-exec1.c 2006-12-06 16:39:06.000000000 -0500 +@@ -0,0 +1,6 @@ ++#include ++int main (void) ++{ ++ printf("Hello, World.\n"); ++ return 0; ++} +diff -BurpN ltrace-0.5-orig/testsuite/ltrace.minor/trace-exec.c ltrace-0.5/testsuite/ltrace.minor/trace-exec.c +--- ltrace-0.5-orig/testsuite/ltrace.minor/trace-exec.c 1969-12-31 19:00:00.000000000 -0500 ++++ ltrace-0.5/testsuite/ltrace.minor/trace-exec.c 2006-12-06 16:51:45.000000000 -0500 +@@ -0,0 +1,8 @@ ++#include ++#include ++ ++int main (int argc, char ** argv) ++{ ++ execl (argv[1], argv[1], NULL); ++ abort (); ++} +diff -BurpN ltrace-0.5-orig/testsuite/ltrace.minor/trace-exec.exp ltrace-0.5/testsuite/ltrace.minor/trace-exec.exp +--- ltrace-0.5-orig/testsuite/ltrace.minor/trace-exec.exp 1969-12-31 19:00:00.000000000 -0500 ++++ ltrace-0.5/testsuite/ltrace.minor/trace-exec.exp 2006-12-06 16:57:30.000000000 -0500 +@@ -0,0 +1,48 @@ ++set testfile "trace-exec" ++set srcfile ${testfile}.c ++set binfile ${testfile} ++ ++verbose "compiling first source file now....." ++# Build the shared libraries this test case needs. ++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....." ++# Build the shared libraries this test case needs. ++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 ++ ++ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace {'^execl'} 1 ++ ++# assume glibc and see we really trace both binaries ++ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace {'^__libc_start_main'} 2 ++ ++# and that we trace printf from the second binary ++ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace {'^(puts|printf)'} 1 diff --git a/ltrace-0.5-exec.patch b/ltrace-0.5-exec.patch new file mode 100644 index 0000000..73f11b8 --- /dev/null +++ b/ltrace-0.5-exec.patch @@ -0,0 +1,56 @@ +diff -Naurp ltrace-0.5/process_event.c ltrace-0.5-mod/process_event.c +--- ltrace-0.5/process_event.c 2006-09-26 08:41:49.000000000 -0500 ++++ ltrace-0.5-mod/process_event.c 2006-09-26 08:41:20.000000000 -0500 +@@ -238,19 +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)) { +- 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; +- } + continue_process(event->proc->pid); + } + +diff -Naurp ltrace-0.5/wait_for_something.c ltrace-0.5-mod/wait_for_something.c +--- ltrace-0.5/wait_for_something.c 2006-02-20 15:48:07.000000000 -0600 ++++ ltrace-0.5-mod/wait_for_something.c 2006-09-26 08:41:20.000000000 -0500 +@@ -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); ++ 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 = diff --git a/ltrace-0.5-fork.patch b/ltrace-0.5-fork.patch new file mode 100644 index 0000000..757e4d9 --- /dev/null +++ b/ltrace-0.5-fork.patch @@ -0,0 +1,75 @@ +diff -BurpN ltrace-x86/ltrace.h ltrace-0.5/ltrace.h +--- ltrace-x86/ltrace.h 2006-12-06 11:34:44.000000000 -0500 ++++ ltrace-0.5/ltrace.h 2006-12-06 14:42:52.000000000 -0500 +@@ -175,6 +173,7 @@ extern void reinitialize_breakpoints(str + + extern struct process *open_program(char *filename, pid_t pid); + extern void open_pid(pid_t pid, int verbose); ++extern void open_forked_pid(pid_t pid); + extern void show_summary(void); + + /* Arch-dependent stuff: */ +diff -BurpN ltrace-x86/proc.c ltrace-0.5/proc.c +--- ltrace-x86/proc.c 2006-12-06 11:34:45.000000000 -0500 ++++ ltrace-0.5/proc.c 2006-12-06 14:42:13.000000000 -0500 +@@ -61,3 +59,11 @@ void open_pid(pid_t pid, int options) + proc->pid = pid; + proc->breakpoints_enabled = -1; + } ++ ++void open_forked_pid(pid_t pid) ++{ ++ char *filename = pid2name(pid); ++ struct process *proc = open_program(filename, 0); ++ proc->pid = pid; ++ proc->breakpoints_enabled = -1; ++} +diff -BurpN ltrace-x86/testsuite/lib/ltrace.exp ltrace-0.5/testsuite/lib/ltrace.exp +--- ltrace-x86/testsuite/lib/ltrace.exp 2006-12-06 11:34:43.000000000 -0500 ++++ ltrace-0.5/testsuite/lib/ltrace.exp 2006-12-06 15:31:42.000000000 -0500 +@@ -260,7 +260,7 @@ proc ltrace_saveoutput { args } { + proc ltrace_verify_output { file_to_search pattern {instance_no 0}} { + + # compute the number of PATTERN in FILE_TO_SEARCH by grep and wc. +- catch "exec sh -c {grep $pattern $file_to_search | wc -l ;exit}" output ++ catch "exec sh -c {egrep $pattern $file_to_search | wc -l ;exit}" output + verbose "output = $output" + + if { $instance_no == 0 } then { +diff -BurpN ltrace-x86/testsuite/ltrace.minor/trace-fork.exp ltrace-0.5/testsuite/ltrace.minor/trace-fork.exp +--- ltrace-x86/testsuite/ltrace.minor/trace-fork.exp 2006-12-06 11:34:43.000000000 -0500 ++++ ltrace-0.5/testsuite/ltrace.minor/trace-fork.exp 2006-12-06 15:29:40.000000000 -0500 +@@ -35,6 +35,19 @@ if [regexp {ELF from incompatible archit + + ltrace_saveoutput "${exec_output}" ${srcdir}/${subdir}/${testfile}.ltrace + +-set pattern "fork" ++if [ regexp {Cannot attach} $exec_output ] { ++ fail "Couldn't attach to forked process!" ++ return ++} ++ ++set pattern "^fork" + ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 + ++set pattern {'^\[pid [0-9]*\][ \t]*(printf|puts)'} ++ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 2 ++ ++set pattern {'^\[pid [0-9]*\][ \t]*wait'} ++ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 ++ ++set pattern {'^\[pid [0-9]*\][ \t]*sleep'} ++ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +diff -BurpN ltrace-x86/wait_for_something.c ltrace-0.5/wait_for_something.c +--- ltrace-x86/wait_for_something.c 2006-12-06 21:43:33.000000000 +0100 ++++ ltrace-0.5/wait_for_something.c 2006-12-06 21:45:06.000000000 +0100 +@@ -103,7 +103,8 @@ + event.e_un.signum = WSTOPSIG(status); + child_pid = (pid_t) get_child_pid(event.proc->pid); + if (child_pid){ +- open_pid(child_pid,0); ++ debug (3, "fork: get_child_pid gave us %d", child_pid); ++ open_forked_pid(child_pid); + } + enable_all_breakpoints(event.proc); + continue_after_signal(event.proc->pid, event.e_un.signum); diff --git a/ltrace-0.5-ia64-sigill.patch b/ltrace-0.5-ia64-sigill.patch new file mode 100644 index 0000000..566594f --- /dev/null +++ b/ltrace-0.5-ia64-sigill.patch @@ -0,0 +1,157 @@ +diff -Nurp ltrace-0.5-orig/testsuite/ltrace.torture/ia64-sigill.exp ltrace-0.5/testsuite/ltrace.torture/ia64-sigill.exp +--- ltrace-0.5-orig/testsuite/ltrace.torture/ia64-sigill.exp 1969-12-31 19:00:00.000000000 -0500 ++++ ltrace-0.5/testsuite/ltrace.torture/ia64-sigill.exp 2007-05-04 13:29:43.000000000 -0400 +@@ -0,0 +1,33 @@ ++# This file was written by Yao Qi . ++ ++set testfile "ia64-sigill" ++set srcfile ${testfile}.s ++set binfile ${testfile} ++ ++if { [istarget ia64-*] } then { ++ verbose "compiling source file now....." ++ # Build the shared libraries this test case needs. ++ if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.s" "${srcdir}/${subdir}/${binfile}" executable {debug} ] != "" } { ++ send_user "Testcase compile failed, so all tests in this file will automatically fail\n." ++ } ++ ++ # Run PUT for ltarce. ++ set exec_output [ltrace_runtest $srcdir/$subdir $srcdir/$subdir/$binfile] ++ ++ # 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 ++ } ++ ++ catch "exec sh -c {grep SIGILL ${srcdir}/${subdir}/${testfile}.ltrace | wc -l ;exit}" output ++ if { $output == 0 } then { ++ pass "ltrace did interpret SIGILL as breakpoint." ++ } else { ++ fail "ltrace failed to interpret SIGILL as breakpoint." ++ } ++} +diff -Nurp ltrace-0.5-orig/testsuite/ltrace.torture/ia64-sigill.s ltrace-0.5/testsuite/ltrace.torture/ia64-sigill.s +--- ltrace-0.5-orig/testsuite/ltrace.torture/ia64-sigill.s 1969-12-31 19:00:00.000000000 -0500 ++++ ltrace-0.5/testsuite/ltrace.torture/ia64-sigill.s 2007-05-04 12:51:14.000000000 -0400 +@@ -0,0 +1,43 @@ ++ .file "pokus.c" ++ .pred.safe_across_calls p1-p5,p16-p63 ++ .section .rodata ++ .align 8 ++.LC0: ++ stringz "" ++ .text ++ .align 16 ++ .global main# ++ .proc main# ++main: ++ .prologue 14, 32 ++ .save ar.pfs, r33 ++ alloc r33 = ar.pfs, 0, 4, 1, 0 ++ .vframe r34 ++ mov r34 = r12 ++ mov r35 = r1 ++ .save rp, r32 ++ mov r32 = b0 ++ .body ++ addl r36 = @ltoffx(.LC0), r1 ++ ;; ++ ld8.mov r36 = [r36], .LC0 ++ br.call.sptk.many b0 = printf# ++ nop.b 0x0 ++ nop.b 0x1 ++ nop.b 0x2 ++ nop.b 0x0 ++ nop.b 0x1 ++ nop.b 0x2 ++ mov r1 = r35 ++ addl r14 = 234, r0 ++ ;; ++ mov r8 = r14 ++ mov ar.pfs = r33 ++ mov b0 = r32 ++ .restore sp ++ mov r12 = r34 ++ br.ret.sptk.many b0 ++ ;; ++ .endp main# ++ .section .note.GNU-stack,"",@progbits ++ .ident "GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-3)" +diff -Nurp ltrace-0.5-orig/wait_for_something.c ltrace-0.5/wait_for_something.c +--- ltrace-0.5-orig/wait_for_something.c 2007-05-04 12:39:00.000000000 -0400 ++++ ltrace-0.5/wait_for_something.c 2007-05-04 13:53:30.000000000 -0400 +@@ -27,6 +27,7 @@ struct event *wait_for_something(void) + pid_t pid, child_pid; + int status; + int tmp; ++ int stop_signal; + + if (!list_of_processes) { + debug(1, "No more children"); +@@ -92,15 +93,38 @@ struct event *wait_for_something(void) + event.thing = LT_EV_UNKNOWN; + return &event; + } +- if ((WSTOPSIG(status) != (SIGTRAP | event.proc->tracesysgood)) && +- (WSTOPSIG(status) != SIGTRAP)) { ++ ++ stop_signal = WSTOPSIG(status); ++ event.thing = LT_EV_NONE; ++ ++ /* On some targets, breakpoints are signalled not using ++ SIGTRAP, but also with SIGILL, SIGSEGV or SIGEMT. Check ++ for these. */ ++ if (stop_signal == SIGSEGV ++ || stop_signal == SIGILL ++#ifdef SIGEMT ++ || stop_signal == SIGEMT ++#endif ++ ) { ++ // If we didn't need to know IP so far, get it now. ++ void * addr = opt_i ++ ? event.proc->instruction_pointer ++ : (event.proc->instruction_pointer = get_instruction_pointer (event.proc)); ++ ++ if (address2bpstruct(event.proc, addr)) ++ stop_signal = SIGTRAP; ++ } ++ ++ if (event.thing == LT_EV_NONE ++ && (stop_signal != (SIGTRAP | event.proc->tracesysgood)) ++ && (stop_signal != SIGTRAP)) { + event.thing = LT_EV_SIGNAL; +- event.e_un.signum = WSTOPSIG(status); ++ event.e_un.signum = stop_signal; + return &event; + } +- if((WSTOPSIG(status) == SIGTRAP) && (status & FORK_MASK)) { ++ if(stop_signal == SIGTRAP && (status & FORK_MASK)) { + event.thing = LT_EV_NONE; +- event.e_un.signum = WSTOPSIG(status); ++ event.e_un.signum = stop_signal; + child_pid = (pid_t) get_child_pid(event.proc->pid); + if (child_pid){ + debug (3, "fork: get_child_pid gave us %d", child_pid); +@@ -110,7 +134,7 @@ struct event *wait_for_something(void) + continue_after_signal(event.proc->pid, event.e_un.signum); + return &event; + } +- if (WSTOPSIG(status) == SIGTRAP){ ++ if (stop_signal == 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]; +@@ -118,7 +142,7 @@ struct event *wait_for_something(void) + pid_t saved_pid; + + event.thing = LT_EV_NONE; +- event.e_un.signum = WSTOPSIG(status); ++ event.e_un.signum = stop_signal; + debug(1,"Placing breakpoints for the new program"); + event.proc->mask_32bit = 0; + event.proc->personality = 0; diff --git a/ltrace.spec b/ltrace.spec index 67dc00f..832b9e1 100644 --- a/ltrace.spec +++ b/ltrace.spec @@ -1,7 +1,7 @@ Summary: Tracks runtime library calls from dynamically linked executables Name: ltrace Version: 0.5 -Release: 6.45svn%{?dist} +Release: 7.45svn%{?dist} URL: http://alioth.debian.org/projects/ltrace/ Source: ltrace-0.5.tar.gz Patch0: ltrace-0.4-exec.patch @@ -13,7 +13,11 @@ Patch5: ltrace-0.5-testsuite.patch Patch6: ltrace-0.5-ppc-symval.patch Patch7: ltrace-0.5-a2bp.patch Patch8: ltrace-0.5-attach.patch -Patch9: ltrace-0.5-man.patch +Patch9: ltrace-0.5-fork.patch +Patch10: ltrace-0.5-exec.patch +Patch11: ltrace-0.5-exec-tests.patch +Patch12: ltrace-0.5-man.patch +Patch13: ltrace-0.5-ia64-sigill.patch License: GPL Group: Development/Debuggers ExclusiveArch: %{ix86} x86_64 ia64 ppc ppc64 s390 s390x alpha sparc @@ -42,6 +46,10 @@ execution of processes. %patch7 -p1 %patch8 -p1 %patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 sed -i -e 's/-o root -g root//' Makefile.in %build @@ -69,6 +77,11 @@ rm -rf $RPM_BUILD_ROOT %config(noreplace) /etc/ltrace.conf %changelog +* Fri May 4 2007 Petr Machata - 0.5-7.45svn +- added fork/exec patches, mostly IBM's work +- added trace-exec tests into suite +- added ia64 sigill patch + * Thu Jan 25 2007 Petr Machata - 0.5-6.45svn - tidy up the specfile per rpmlint comments - fix man page