summaryrefslogtreecommitdiffstats
path: root/tapset
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 /tapset
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.
Diffstat (limited to 'tapset')
-rw-r--r--tapset/aux_syscalls.stp10
-rw-r--r--tapset/syscalls.stp43
2 files changed, 53 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)