From 816395d6f1c433cddc1eaecba2248168c1dd4a5a Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sat, 20 Mar 2010 19:58:29 +0100 Subject: 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. --- tapset/aux_syscalls.stp | 10 +++++++++ tapset/syscalls.stp | 43 +++++++++++++++++++++++++++++++++++++++ testsuite/systemtap.syscall/dup.c | 43 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 testsuite/systemtap.syscall/dup.c 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 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 +#include +#include +#include + +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; +} -- cgit