summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2010-03-20 19:58:29 +0100
committerMark Wielaard <mjw@redhat.com>2010-03-21 17:34:41 +0100
commit816395d6f1c433cddc1eaecba2248168c1dd4a5a (patch)
tree96fe777697334f937c46f1db0835a063c9aec001
parent92ef533e0241eb1a39ef7ceef8dce52e4ae9d820 (diff)
downloadsystemtap-steved-816395d6f1c433cddc1eaecba2248168c1dd4a5a.tar.gz
systemtap-steved-816395d6f1c433cddc1eaecba2248168c1dd4a5a.tar.xz
systemtap-steved-816395d6f1c433cddc1eaecba2248168c1dd4a5a.zip
Add support for dup3 to syscall.stp tapset.
* tapset/aux_syscalls.stp (_dup3_flag_str): New helper function. * tapset/syscalls.stp (syscall.dup2): Add alternatives to handle dup3 also. * testsuite/systemtap.syscall/dup.c: New testcase.
-rw-r--r--tapset/aux_syscalls.stp10
-rw-r--r--tapset/syscalls.stp43
-rw-r--r--testsuite/systemtap.syscall/dup.c43
3 files changed, 96 insertions, 0 deletions
diff --git a/tapset/aux_syscalls.stp b/tapset/aux_syscalls.stp
index 87db5abb..15a70484 100644
--- a/tapset/aux_syscalls.stp
+++ b/tapset/aux_syscalls.stp
@@ -1645,6 +1645,16 @@ function _epoll_create1_flag_str:string(f:long)
#endif
%}
+function _dup3_flag_str:string(f:long)
+%{ /* pure */
+#ifdef O_CLOEXEC
+ if (THIS->f == O_CLOEXEC)
+ strlcpy (THIS->__retvalue, "O_CLOEXEC", MAXSTRINGLEN);
+ else
+#endif
+ strlcpy (THIS->__retvalue, "UNKNOWN", MAXSTRINGLEN);
+%}
+
%{
#include <linux/shm.h>
static const _stp_val_array const _stp_shmat_list[] = {
diff --git a/tapset/syscalls.stp b/tapset/syscalls.stp
index 743318b2..90cdbd0e 100644
--- a/tapset/syscalls.stp
+++ b/tapset/syscalls.stp
@@ -565,9 +565,12 @@ probe syscall.dup.return = kernel.function("SyS_dup").return !,
# dup2 _______________________________________________________
# long sys_dup2(unsigned int oldfd, unsigned int newfd)
+# Only handles corner case, others handled by dup3.
probe syscall.dup2 = kernel.function("SyS_dup2").call !,
kernel.function("sys_dup2").call
{
+ if ($oldfd != $newfd) next;
+
name = "dup2"
oldfd = $oldfd
newfd = $newfd
@@ -576,10 +579,50 @@ probe syscall.dup2 = kernel.function("SyS_dup2").call !,
probe syscall.dup2.return = kernel.function("SyS_dup2").return !,
kernel.function("sys_dup2").return
{
+ if ($oldfd != $newfd) next;
+
name = "dup2"
retstr = returnstr(1)
}
+# dup3 (handles both dup2 and dup3 except for corner case)___________
+# long sys_dup2(unsigned int oldfd, unsigned int newfd)
+# SYSCALL_DEFINE3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags)
+probe syscall.dup2 = kernel.function("SyS_dup3").call !,
+ kernel.function("sys_dup3").call !,
+ kernel.function("SyS_dup2").call !,
+ kernel.function("sys_dup2").call
+{
+ oldfd = $oldfd
+ newfd = $newfd
+ flags = @defined($flags) ? $flags : 0;
+
+ # Corner case handled by dup2
+ if ($oldfd == $newfd && flags == 0) next
+
+ if (flags == 0) {
+ name = "dup2";
+ argstr = sprintf("%d, %d", $oldfd, $newfd);
+ } else {
+ name = "dup3";
+ argstr = sprintf("%d, %d, %s", $oldfd, $newfd,
+ _dup3_flag_str(flags));
+ }
+}
+probe syscall.dup2.return = kernel.function("SyS_dup3").return !,
+ kernel.function("sys_dup3").return !,
+ kernel.function("SyS_dup2").return !,
+ kernel.function("sys_dup2").return
+{
+ flags = @defined($flags) ? $flags : 0;
+
+ # Corner case handled by dup2
+ if ($oldfd == $newfd && flags == 0) next
+
+ name = flags == 0 ? "dup2" : "dup3";
+ retstr = returnstr(1)
+}
+
# epoll_create _______________________________________________
# long sys_epoll_create(int size)
# SYSCALL_DEFINE1(epoll_create1, int, flags)
diff --git a/testsuite/systemtap.syscall/dup.c b/testsuite/systemtap.syscall/dup.c
new file mode 100644
index 00000000..862f7e91
--- /dev/null
+++ b/testsuite/systemtap.syscall/dup.c
@@ -0,0 +1,43 @@
+/* COVERAGE: dup dup2 dup3 */
+
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+int main()
+{
+ dup(2);
+ //staptest// dup (2) = NNNN
+
+ dup(256);
+ //staptest// dup (256) = -9 (EBADF)
+
+ dup2(3, 4);
+ //staptest// dup2 (3, 4) = 4
+
+ dup2(255, 256);
+ //staptest// dup2 (255, 256) = -9 (EBADF)
+
+ /* weird corner case oldfd == newfd */
+ dup2(1, 1);
+ //staptest// dup2 (1, 1) = 1
+
+#ifdef O_CLOEXEC
+ dup3 (4, 5, O_CLOEXEC);
+ //staptest// dup3 (4, 5, O_CLOEXEC) = 5
+
+ dup3 (256, 255, O_CLOEXEC);
+ //staptest// dup3 (256, 255, O_CLOEXEC) = -9 (EBADF)
+
+ dup3 (5, 6, 666);
+ //staptest// dup3 (5, 6, UNKNOWN) = -22 (EINVAL)
+
+ /* corner case not valid for dup3 */
+ dup3 (1, 1, O_CLOEXEC);
+ //staptest// dup3 (1, 1, O_CLOEXEC) = -22 (EINVAL)
+#endif
+
+ return 0;
+}