|
|
a2ff6b |
diff -Nrup a/testsuite/ltrace.main/system_call_params.exp b/testsuite/ltrace.main/system_call_params.exp
|
|
|
a2ff6b |
--- a/testsuite/ltrace.main/system_call_params.exp 2013-10-24 06:02:24.000000000 -0600
|
|
|
a2ff6b |
+++ b/testsuite/ltrace.main/system_call_params.exp 2015-06-01 12:13:04.639847059 -0600
|
|
|
a2ff6b |
@@ -1,5 +1,5 @@
|
|
|
a2ff6b |
# This file is part of ltrace.
|
|
|
a2ff6b |
-# Copyright (C) 2013 Petr Machata, Red Hat Inc.
|
|
|
a2ff6b |
+# Copyright (C) 2013, 2014, 2015 Petr Machata, Red Hat Inc.
|
|
|
a2ff6b |
#
|
|
|
a2ff6b |
# This program is free software; you can redistribute it and/or
|
|
|
a2ff6b |
# modify it under the terms of the GNU General Public License as
|
|
|
a2ff6b |
@@ -17,13 +17,31 @@
|
|
|
a2ff6b |
# 02110-1301 USA
|
|
|
a2ff6b |
|
|
|
a2ff6b |
set bin [ltraceCompile {} [ltraceSource c {
|
|
|
a2ff6b |
+ #ifndef _GNU_SOURCE
|
|
|
a2ff6b |
+ #define _GNU_SOURCE
|
|
|
a2ff6b |
+ #endif
|
|
|
a2ff6b |
#include <sys/types.h>
|
|
|
a2ff6b |
#include <sys/stat.h>
|
|
|
a2ff6b |
#include <fcntl.h>
|
|
|
a2ff6b |
+ #include <unistd.h>
|
|
|
a2ff6b |
+ #include <sys/syscall.h> /* For SYS_xxx definitions */
|
|
|
a2ff6b |
+ #include <sys/mount.h>
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
+ #ifndef SYS_open
|
|
|
a2ff6b |
+ # if defined(__aarch64__)
|
|
|
a2ff6b |
+ # /* Linux doesn't actually implement SYS_open on AArch64, but for merely
|
|
|
a2ff6b |
+ # * recording the syscall, it's fine. */
|
|
|
a2ff6b |
+ # define SYS_open 1024
|
|
|
a2ff6b |
+ # else
|
|
|
a2ff6b |
+ # error SYS_open not available.
|
|
|
a2ff6b |
+ # endif
|
|
|
a2ff6b |
+ #endif
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
int main(void) {
|
|
|
a2ff6b |
- open("/some/path", O_RDONLY);
|
|
|
a2ff6b |
+ syscall(SYS_open, "/some/path", O_RDONLY);
|
|
|
a2ff6b |
write(1, "something", 10);
|
|
|
a2ff6b |
mount("source", "target", "filesystemtype", 0, 0);
|
|
|
a2ff6b |
+ return 0;
|
|
|
a2ff6b |
}
|
|
|
a2ff6b |
}]]
|
|
|
a2ff6b |
|
|
|
a2ff6b |
@@ -42,8 +60,33 @@ set conf [ltraceNamedSource "$dir/syscal
|
|
|
a2ff6b |
# somelib.conf is passed, and syscalls.conf is not available, or
|
|
|
a2ff6b |
# doesn't list readdir, that would be taken from somelib.conf with a
|
|
|
a2ff6b |
# wrong prototype.
|
|
|
a2ff6b |
+#
|
|
|
a2ff6b |
+# This test relies on the fact that there is no global config file
|
|
|
a2ff6b |
+# that would provide legitimate system call prototype. But that
|
|
|
a2ff6b |
+# doesn't have to be true, maybe ltrace is already installed on the
|
|
|
a2ff6b |
+# system with the right prefix. So first compile a wrapper that we
|
|
|
a2ff6b |
+# use to redirect fopen calls.
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
+set libfopen_so [ltraceCompile libfopen.so -ldl [ltraceSource c {
|
|
|
a2ff6b |
+ #define _GNU_SOURCE
|
|
|
a2ff6b |
+ #include <dlfcn.h>
|
|
|
a2ff6b |
+ #include <stdio.h>
|
|
|
a2ff6b |
+ #include <string.h>
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
+ FILE *
|
|
|
a2ff6b |
+ fopen(const char *path, const char *mode)
|
|
|
a2ff6b |
+ {
|
|
|
a2ff6b |
+ if (strncmp(path, "/usr/share", 10) == 0)
|
|
|
a2ff6b |
+ path = "/dev/null";
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
+ return ((FILE *(*)(const char *, const char *))
|
|
|
a2ff6b |
+ dlsym(RTLD_NEXT, "fopen")) (path, mode);
|
|
|
a2ff6b |
+ }
|
|
|
a2ff6b |
+}]]
|
|
|
a2ff6b |
|
|
|
a2ff6b |
+setenv LD_PRELOAD $libfopen_so
|
|
|
a2ff6b |
ltraceMatch1 [ltraceRun -L -S -F $conf -- $bin] {^open@SYS\("/some/path"} == 0
|
|
|
a2ff6b |
+unsetenv LD_PRELOAD
|
|
|
a2ff6b |
|
|
|
a2ff6b |
# On the other hand, if -F somedir/ is given, we want to accept
|
|
|
a2ff6b |
# syscalls.conf found there.
|
|
|
a2ff6b |
diff -Nrup a/testsuite/ltrace.main/system_calls.exp b/testsuite/ltrace.main/system_calls.exp
|
|
|
a2ff6b |
--- a/testsuite/ltrace.main/system_calls.exp 2013-10-24 06:02:24.000000000 -0600
|
|
|
a2ff6b |
+++ b/testsuite/ltrace.main/system_calls.exp 2015-06-01 12:09:11.132944455 -0600
|
|
|
a2ff6b |
@@ -1,67 +1,146 @@
|
|
|
a2ff6b |
-# This file was written by Yao Qi <qiyao@cn.ibm.com>.
|
|
|
a2ff6b |
+# This file is part of ltrace.
|
|
|
a2ff6b |
+# Copyright (C) 2014 Petr Machata, Red Hat Inc.
|
|
|
a2ff6b |
+# Copyright (C) 2006 Yao Qi <qiyao@cn.ibm.com>, IBM Corporation
|
|
|
a2ff6b |
+#
|
|
|
a2ff6b |
+# This program is free software; you can redistribute it and/or
|
|
|
a2ff6b |
+# modify it under the terms of the GNU General Public License as
|
|
|
a2ff6b |
+# published by the Free Software Foundation; either version 2 of the
|
|
|
a2ff6b |
+# License, or (at your option) any later version.
|
|
|
a2ff6b |
+#
|
|
|
a2ff6b |
+# This program is distributed in the hope that it will be useful, but
|
|
|
a2ff6b |
+# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
a2ff6b |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
a2ff6b |
+# General Public License for more details.
|
|
|
a2ff6b |
+#
|
|
|
a2ff6b |
+# You should have received a copy of the GNU General Public License
|
|
|
a2ff6b |
+# along with this program; if not, write to the Free Software
|
|
|
a2ff6b |
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
|
|
a2ff6b |
+# 02110-1301 USA
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
+# Objectives: Verify that Ltrace can trace all the system calls in
|
|
|
a2ff6b |
+# execution. Note that this test is necessarily noisy. Dynamic
|
|
|
a2ff6b |
+# linker adds a bunch of system calls of its own.
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
+set empty [ltraceCompile {} [ltraceSource c {
|
|
|
a2ff6b |
+ int main (void) { return 0; }
|
|
|
a2ff6b |
+}]]
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
+set bin [ltraceCompile {} [ltraceSource c {
|
|
|
a2ff6b |
+ #include <stdio.h>
|
|
|
a2ff6b |
+ #include <unistd.h>
|
|
|
a2ff6b |
+ #include <sys/syscall.h>
|
|
|
a2ff6b |
+ #include <sys/stat.h>
|
|
|
a2ff6b |
+ #include <errno.h>
|
|
|
a2ff6b |
+ #include <stdlib.h>
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
+ int
|
|
|
a2ff6b |
+ main ()
|
|
|
a2ff6b |
+ {
|
|
|
a2ff6b |
+ FILE* fp;
|
|
|
a2ff6b |
+ char s[]="system_calls";
|
|
|
a2ff6b |
+ char buffer[1024];
|
|
|
a2ff6b |
+ struct stat state;
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
+ fp = fopen ("system_calls.tmp", "w");
|
|
|
a2ff6b |
+ if (fp == NULL)
|
|
|
a2ff6b |
+ {
|
|
|
a2ff6b |
+ printf("Can not create system_calls.tmp\n");
|
|
|
a2ff6b |
+ exit (0);
|
|
|
a2ff6b |
+ }
|
|
|
a2ff6b |
+ fwrite(s, sizeof(s), 1, fp);
|
|
|
a2ff6b |
+ fseek (fp, 0, SEEK_CUR);
|
|
|
a2ff6b |
+ fread(buffer, sizeof(s), 1, fp);
|
|
|
a2ff6b |
+ fclose(fp);
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
+ getcwd (buffer, sizeof buffer);
|
|
|
a2ff6b |
+ chdir (".");
|
|
|
a2ff6b |
+ symlink ("system_calls.tmp", "system_calls.link");
|
|
|
a2ff6b |
+ remove("system_calls.link");
|
|
|
a2ff6b |
+ rename ("system_calls.tmp", "system_calls.tmp1");
|
|
|
a2ff6b |
+ stat ("system_calls.tmp", &state);
|
|
|
a2ff6b |
+ access ("system_calls.tmp", R_OK);
|
|
|
a2ff6b |
+ remove("system_calls.tmp1");
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
+ mkdir ("system_call_mkdir", 0777);
|
|
|
a2ff6b |
+ rmdir ("system_call_mkdir");
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
+ return 0;
|
|
|
a2ff6b |
+ }
|
|
|
a2ff6b |
+}]]
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
+proc Calls {logfile} {
|
|
|
a2ff6b |
+ set fp [open $logfile]
|
|
|
a2ff6b |
+ set ret {}
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
+ while {[gets $fp line] >= 0} {
|
|
|
a2ff6b |
+ if [regexp -- {^[a-zA-Z0-9]*@SYS} $line] {
|
|
|
a2ff6b |
+ set call [lindex [split $line @] 0]
|
|
|
a2ff6b |
+ dict incr ret $call
|
|
|
a2ff6b |
+ }
|
|
|
a2ff6b |
+ }
|
|
|
a2ff6b |
|
|
|
a2ff6b |
-set testfile "system_calls"
|
|
|
a2ff6b |
-set srcfile ${testfile}.c
|
|
|
a2ff6b |
-set binfile ${testfile}
|
|
|
a2ff6b |
-
|
|
|
a2ff6b |
-
|
|
|
a2ff6b |
-verbose "compiling source file now....."
|
|
|
a2ff6b |
-# Build the shared libraries this test case needs.
|
|
|
a2ff6b |
-if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${objdir}/${subdir}/${binfile}" executable {debug} ] != "" } {
|
|
|
a2ff6b |
- send_user "Testcase compile failed, so all tests in this file will automatically fail.\n"
|
|
|
a2ff6b |
+ close $fp
|
|
|
a2ff6b |
+ return $ret
|
|
|
a2ff6b |
}
|
|
|
a2ff6b |
|
|
|
a2ff6b |
-# set options for ltrace.
|
|
|
a2ff6b |
-ltrace_options "-S"
|
|
|
a2ff6b |
-
|
|
|
a2ff6b |
-#Run PUT for ltarce.
|
|
|
a2ff6b |
-set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile]
|
|
|
a2ff6b |
+proc GetDefault {d key def} {
|
|
|
a2ff6b |
+ if {[dict exists $d $key]} {
|
|
|
a2ff6b |
+ return [dict get $d $key]
|
|
|
a2ff6b |
+ } else {
|
|
|
a2ff6b |
+ return $def
|
|
|
a2ff6b |
+ }
|
|
|
a2ff6b |
+}
|
|
|
a2ff6b |
|
|
|
a2ff6b |
-#check the output of this program.
|
|
|
a2ff6b |
-verbose "ltrace runtest output: $exec_output\n"
|
|
|
a2ff6b |
+proc Diff {d1 d2} {
|
|
|
a2ff6b |
+ set keys [lsort -unique [concat [dict keys $d1] [dict keys $d2]]]
|
|
|
a2ff6b |
+ set ret {}
|
|
|
a2ff6b |
+ foreach key $keys {
|
|
|
a2ff6b |
+ set n1 [GetDefault $d1 $key 0]
|
|
|
a2ff6b |
+ set n2 [GetDefault $d2 $key 0]
|
|
|
a2ff6b |
+ set sum [expr $n1 - $n2]
|
|
|
a2ff6b |
+ if {[expr $sum != 0]} {
|
|
|
a2ff6b |
+ dict set ret $key $sum
|
|
|
a2ff6b |
+ }
|
|
|
a2ff6b |
+ }
|
|
|
a2ff6b |
+ return $ret
|
|
|
a2ff6b |
+}
|
|
|
a2ff6b |
|
|
|
a2ff6b |
-if [regexp {ELF from incompatible architecture} $exec_output] {
|
|
|
a2ff6b |
- fail "32-bit ltrace can not perform on 64-bit PUTs and rebuild ltrace in 64 bit mode!"
|
|
|
a2ff6b |
- return
|
|
|
a2ff6b |
-} elseif [ regexp {Couldn't get .hash data} $exec_output ] {
|
|
|
a2ff6b |
- fail "Couldn't get .hash data!"
|
|
|
a2ff6b |
- return
|
|
|
a2ff6b |
+proc Match {d patterns} {
|
|
|
a2ff6b |
+ foreach line $patterns {
|
|
|
a2ff6b |
+ set pattern [lindex $line 0]
|
|
|
a2ff6b |
+ set op [lindex $line 1]
|
|
|
a2ff6b |
+ set expect [lindex $line 2]
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
+ set count 0
|
|
|
a2ff6b |
+ foreach key [dict keys $d] {
|
|
|
a2ff6b |
+ if [regexp -- $pattern $key] {
|
|
|
a2ff6b |
+ incr count [dict get $d $key]
|
|
|
a2ff6b |
+ }
|
|
|
a2ff6b |
+ }
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
+ set msgMain "$pattern was recorded $count times"
|
|
|
a2ff6b |
+
|
|
|
a2ff6b |
+ if {[eval expr $count $op $expect]} {
|
|
|
a2ff6b |
+ pass $msgMain
|
|
|
a2ff6b |
+ } else {
|
|
|
a2ff6b |
+ fail "$msgMain, expected $op $expect"
|
|
|
a2ff6b |
+ }
|
|
|
a2ff6b |
+ }
|
|
|
a2ff6b |
}
|
|
|
a2ff6b |
|
|
|
a2ff6b |
+Match [Diff [Calls [ltraceRun -L -S -- $bin]] \
|
|
|
a2ff6b |
+ [Calls [ltraceRun -L -S -- $empty]]] {
|
|
|
a2ff6b |
+ { {^write$} == 1 }
|
|
|
a2ff6b |
+ { {^unlink(at)?$} >= 2 }
|
|
|
a2ff6b |
+ { {^open(at)?$} == 1 }
|
|
|
a2ff6b |
+ { {^(new|f)?stat(64)?$} >= 1 }
|
|
|
a2ff6b |
+ { {^close$} == 1 }
|
|
|
a2ff6b |
+ { {^getcwd$} == 1 }
|
|
|
a2ff6b |
+ { {^chdir$} == 1 }
|
|
|
a2ff6b |
+ { {^symlink(at)?$} == 1 }
|
|
|
a2ff6b |
+ { {^f?access(at)?$} == 1 }
|
|
|
a2ff6b |
+ { {^rename(at)?$} == 1 }
|
|
|
a2ff6b |
+ { {^mkdir(at)?$} == 1 }
|
|
|
a2ff6b |
+}
|
|
|
a2ff6b |
|
|
|
a2ff6b |
-set pattern "^munmap@SYS"
|
|
|
a2ff6b |
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 2
|
|
|
a2ff6b |
-set pattern "^write@SYS"
|
|
|
a2ff6b |
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
|
|
|
a2ff6b |
-set pattern "^unlink@SYS"
|
|
|
a2ff6b |
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
|
|
|
a2ff6b |
-
|
|
|
a2ff6b |
-set pattern "^brk@SYS"
|
|
|
a2ff6b |
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
|
|
|
a2ff6b |
-set pattern "^open@SYS"
|
|
|
a2ff6b |
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
|
|
|
a2ff6b |
-set pattern "^(new)?fstat(64)?@SYS"
|
|
|
a2ff6b |
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 egrep
|
|
|
a2ff6b |
-set pattern "^(old_)?mmap2?@SYS"
|
|
|
a2ff6b |
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 egrep
|
|
|
a2ff6b |
-set pattern "^close@SYS"
|
|
|
a2ff6b |
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
|
|
|
a2ff6b |
-
|
|
|
a2ff6b |
-set pattern "^getcwd@SYS"
|
|
|
a2ff6b |
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
|
|
|
a2ff6b |
-set pattern "^chdir@SYS"
|
|
|
a2ff6b |
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
|
|
|
a2ff6b |
-set pattern "^symlink@SYS"
|
|
|
a2ff6b |
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
|
|
|
a2ff6b |
-set pattern "^unlink@SYS"
|
|
|
a2ff6b |
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
|
|
|
a2ff6b |
-set pattern "^(new)?stat(64)?@SYS"
|
|
|
a2ff6b |
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 egrep
|
|
|
a2ff6b |
-set pattern "^access@SYS"
|
|
|
a2ff6b |
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
|
|
|
a2ff6b |
-set pattern "^rename@SYS"
|
|
|
a2ff6b |
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
|
|
|
a2ff6b |
-set pattern "^mkdir@SYS"
|
|
|
a2ff6b |
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
|
|
|
a2ff6b |
-set pattern "^rmdir@SYS"
|
|
|
a2ff6b |
-ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
|
|
|
a2ff6b |
+ltraceDone
|