strace lockup when tracing exec in go
[I am CCing strace mailing list because even if this turns out to be a kernel bug strace seems to be doing something unexpected - more on that below] Hi, Aleksa has reported the following lockup when stracing the following go program % cat exec.go package main import ( "os" "syscall" ) func main() { syscall.Exec("/bin/echo", []string{"/bin/echo", "Hello"}, os.Environ()) } $ go version go version go1.6.3 linux/amd64 $ go build -o exec exec.go $ strace -f ./exec [snip] [pid 10349] select(0, NULL, NULL, NULL, {0, 100} [pid 10346] <... select resumed> ) = 0 (Timeout) [pid 10346] select(0, NULL, NULL, NULL, {0, 20} [pid 10345] execve("/bin/echo", ["/bin/echo", "Hello"], [/* 95 vars */] [pid 10346] <... select resumed> ) = 0 (Timeout) [pid 10349] <... select resumed> ) = 0 (Timeout) execve will never finish unless the strace process get killed with SIGKILL. The following was debugged on 3.12 kernel and the current kernel seems to not trigger the issue as easily but I believe the same problem is there as well. The further investigation shown that the tracer (strace) is stuck waiting for cred_guard_mutex [<>] mm_access+0x22/0xa0 [<>] process_vm_rw_core.isra.1+0x112/0x6c0 [<>] process_vm_rw+0xab/0x110 [<>] SyS_process_vm_readv+0x15/0x20 [<>] system_call_fastpath+0x16/0x1b [<>] 0x7f186f031c3a [<>] 0x while the traced process (3 threads) are trying to perform the exec. That means that 2 threads are dead (in fact zombies) waiting in their final schedule. Call Trace: [] do_exit+0x6f7/0xa70 [] do_group_exit+0x39/0xa0 [] get_signal_to_deliver+0x1e8/0x5c0 [] do_signal+0x42/0x670 [] do_notify_resume+0x78/0xc0 [] int_signal+0x12/0x17 [<7f3a33f3ffb9>] 0x7f3a33f3ffb8 and one is Call Trace: [] flush_old_exec+0xdf/0x890 [] load_elf_binary+0x307/0xda0 [] search_binary_handler+0xae/0x1f0 [] do_execve_common.isra.26+0x64e/0x810 [] SyS_execve+0x31/0x50 [] stub_execve+0x69/0xa0 [<7f3a33f16527>] 0x7f3a33f16526 waiting for notify_count to drop down to 0 while (sig->notify_count) { __set_current_state(TASK_KILLABLE); spin_unlock_irq(lock); schedule(); < if (unlikely(__fatal_signal_pending(tsk))) goto killed; spin_lock_irq(lock); } this however doesn't happen because both threads which are dead are zombies waiting to be reaped by the parent and to call their release_task->__exit_signal. The tracer is blocked on the lock held by exec (in prepare_bprm_creds). This is the case in the current kernel as well AFAICS so the same should be possible as well. So is this a bug or something somewhere else makes sure that this will not happen in newer kernels? Now, I've tried to fix this by diff --git a/kernel/fork.c b/kernel/fork.c index 5a57b9bab85c..d5b7c3aea187 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -837,7 +837,7 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) struct mm_struct *mm; int err; - err = mutex_lock_killable(&task->signal->cred_guard_mutex); + err = mutex_lock_interruptible(&task->signal->cred_guard_mutex); if (err) return ERR_PTR(err); but it didn't help and I really couldn't see why until I sprinkled printks all over the exit path and to learn that the parent (strace) doesn't get notified about SIGCHLD when those threads are dying. Why is that? exit_notify do_notify_parent -> return false __group_send_sig_info send_signal __send_signal prepare_signal -> fails because the signal is ignored this is more than unexpected (at least to me) because I would expect that the strace wouldn't ignore SIGCHLD! Is this a bug in strace? Btw. in a successful (not hung) case the tracer is in do_wait when do_notify_parent->__wake_up_parent does the right thing. Thanks! -- Michal Hocko SUSE Labs -- ___ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel
[PATCH 02/11] tests: Avoid filling with the same values in ioctl_block test
* tests/ioctl.block (init_magic): Add iterator value to fill magic value in order to enable detection of possible 4-byte aligned shifts. --- tests/ioctl_block.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ioctl_block.c b/tests/ioctl_block.c index 3dc030d..bac9f68 100644 --- a/tests/ioctl_block.c +++ b/tests/ioctl_block.c @@ -50,7 +50,7 @@ init_magic(void *addr, const unsigned int size) const unsigned int *end = addr + size - sizeof(int); for (; p <= end; ++p) - *(unsigned int *) p = magic; + *(unsigned int *) p = magic + (p - (unsigned int *)addr); } static struct xlat block_argless[] = { -- 1.7.10.4 -- ___ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel
[PATCH 01/11] tests: Additional getcwd checks
* tests/getcwd.c: Additional checks for getcwd arguments decoding. --- tests/getcwd.c |8 1 file changed, 8 insertions(+) diff --git a/tests/getcwd.c b/tests/getcwd.c index 704a315..e4a791f 100644 --- a/tests/getcwd.c +++ b/tests/getcwd.c @@ -13,6 +13,14 @@ main(void) { long res; char cur_dir[PATH_MAX + 1]; + static const size_t bogus_size = (size_t) 0xbadc0deddeadfaceULL; + + syscall(__NR_getcwd, NULL, bogus_size); + printf("getcwd(NULL, %zu) = -1 EFAULT (%m)\n", bogus_size); + + syscall(__NR_getcwd, (char *)-1L, sizeof(cur_dir)); + printf("getcwd(%p, %zu) = -1 EFAULT (%m)\n", + (char *)-1L, sizeof(cur_dir)); res = syscall(__NR_getcwd, cur_dir, sizeof(cur_dir)); -- 1.7.10.4 -- ___ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel
[PATCH 00/11] Various minor tests
Hello. This patchset provides a set of some simple syscall decoders test along with fixes of minor issues discovered in the process. Eugene Syromyatnikov (11): tests: Additional getcwd checks tests: Avoid filling with the same values in ioctl_block test tests: check decoding of getcpu syscall xlat: Add values for falloc_flags constants fallocate: Change print format of offset and len arguments to signed fadvise: Change printing of len argument to unsigned in fadvise64 syscall util: Add getarg_ull/getarg_ll functions fadvise: Use getarg_ull for obtaining len argument of fadvise64 syscall Use sys_fadvise64 as a decoder for fadvise64 syscall on x32 tests: Add test for decoding fallocate syscall tests: Add test for decoding fadvise syscall configure.ac|1 + defs.h |2 ++ fadvise.c |2 +- fallocate.c |4 +-- linux/x32/syscallent.h |2 +- tests/.gitignore|4 +++ tests/Makefile.am |8 ++ tests/fadvise64.c | 71 +++ tests/fadvise64.test|6 tests/fadvise64_64.c| 59 +++ tests/fadvise64_64.test |6 tests/fallocate.c | 38 + tests/fallocate.test|6 tests/getcpu.c | 48 tests/getcpu.test |6 tests/getcwd.c |8 ++ tests/ioctl_block.c |2 +- util.c | 44 + xlat/falloc_flags.in| 12 19 files changed, 306 insertions(+), 23 deletions(-) create mode 100644 tests/fadvise64.c create mode 100755 tests/fadvise64.test create mode 100644 tests/fadvise64_64.c create mode 100755 tests/fadvise64_64.test create mode 100644 tests/fallocate.c create mode 100755 tests/fallocate.test create mode 100644 tests/getcpu.c create mode 100755 tests/getcpu.test -- 1.7.10.4 -- ___ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel
[PATCH 03/11] tests: check decoding of getcpu syscall
* tests/getcpu.c: New file. * tests/getcpu.test: New test. * tests/.gitignore: Add getcpu. * tests/Makefile.am (check_PROGRAMS): Likewise. (DECODER_TESTS): Add getcpu.test. --- tests/.gitignore |1 + tests/Makefile.am |2 ++ tests/getcpu.c| 48 tests/getcpu.test |6 ++ 4 files changed, 57 insertions(+) create mode 100644 tests/getcpu.c create mode 100755 tests/getcpu.test diff --git a/tests/.gitignore b/tests/.gitignore index 2820b2b..bdb2d9a 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -70,6 +70,7 @@ ftruncate64 futex futimesat get_mempolicy +getcpu getcwd getdents getdents64 diff --git a/tests/Makefile.am b/tests/Makefile.am index f6f980a..ac579c7 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -129,6 +129,7 @@ check_PROGRAMS = \ futex \ futimesat \ get_mempolicy \ + getcpu \ getcwd \ getdents \ getdents64 \ @@ -465,6 +466,7 @@ DECODER_TESTS = \ futex.test \ futimesat.test \ get_mempolicy.test \ + getcpu.test \ getcwd.test \ getdents.test \ getdents64.test \ diff --git a/tests/getcpu.c b/tests/getcpu.c new file mode 100644 index 000..a96fd49 --- /dev/null +++ b/tests/getcpu.c @@ -0,0 +1,48 @@ +#include "tests.h" + +#include + +#ifdef __NR_getcpu + +# include +# include + +int +main(void) +{ + static const unsigned *bogus_cpu = + (unsigned *) (unsigned long) 0xfeedfaceULL; + static const unsigned *bogus_node = + (unsigned *) (unsigned long) 0xfca7c0deULL; + static const unsigned *bogus_tcache = + (unsigned *) (unsigned long) 0xda7adeadULL; + + long res; + unsigned *cpu = tail_alloc(sizeof(*cpu)); + unsigned *node = tail_alloc(sizeof(*node)); + long * tcache = tail_alloc(128); + + res = syscall(__NR_getcpu, NULL, NULL, NULL); + printf("getcpu(NULL, NULL, NULL) = %s\n", sprintrc(res)); + + res = syscall(__NR_getcpu, bogus_cpu, bogus_node, bogus_tcache); + printf("getcpu(%p, %p, %p) = %s\n", + bogus_cpu, bogus_node, bogus_tcache, sprintrc(res)); + + res = syscall(__NR_getcpu, cpu, node, tcache); + if (res != 0) + perror_msg_and_skip("getcpu"); + + printf("getcpu([%u], [%u], %p) = 0\n", + *cpu, *node, tcache); + + puts("+++ exited with 0 +++"); + + return 0; +} + +#else + +SKIP_MAIN_UNDEFINED("__NR_getcpu"); + +#endif diff --git a/tests/getcpu.test b/tests/getcpu.test new file mode 100755 index 000..3dbe5e0 --- /dev/null +++ b/tests/getcpu.test @@ -0,0 +1,6 @@ +#!/bin/sh + +# Check getcwd syscall decoding. + +. "${srcdir=.}/init.sh" +run_strace_match_diff -a25 -- 1.7.10.4 -- ___ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel
[PATCH 04/11] xlat: Add values for falloc_flags constants
In order to avoid dependence of declared constants to headers available on build system. * xlat/falloc_flags.in: Add values for constants. --- xlat/falloc_flags.in | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/xlat/falloc_flags.in b/xlat/falloc_flags.in index 936e960..9d8ecf2 100644 --- a/xlat/falloc_flags.in +++ b/xlat/falloc_flags.in @@ -1,6 +1,6 @@ -FALLOC_FL_KEEP_SIZE -FALLOC_FL_PUNCH_HOLE -FALLOC_FL_NO_HIDE_STALE -FALLOC_FL_COLLAPSE_RANGE -FALLOC_FL_ZERO_RANGE -FALLOC_FL_INSERT_RANGE +FALLOC_FL_KEEP_SIZE 0x01 +FALLOC_FL_PUNCH_HOLE 0x02 +FALLOC_FL_NO_HIDE_STALE 0x04 +FALLOC_FL_COLLAPSE_RANGE 0x08 +FALLOC_FL_ZERO_RANGE 0x10 +FALLOC_FL_INSERT_RANGE 0x20 -- 1.7.10.4 -- ___ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel
[PATCH 06/11] fadvise: Change printing of len argument to unsigned in fadvise64 syscall
long sys_fadvise64(int fd, loff_t offset, size_t len, int advice); * fadvise.c (SYS_FUNC(fadvise64)): change conversion specifier from "%ld" to "%lu" for printing len argument since kernel expects argument of type size_t. --- fadvise.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fadvise.c b/fadvise.c index 2001394..208f533 100644 --- a/fadvise.c +++ b/fadvise.c @@ -42,7 +42,7 @@ SYS_FUNC(fadvise64) printfd(tcp, tcp->u_arg[0]); argn = printllval(tcp, ", %lld", 1); - tprintf(", %ld, ", tcp->u_arg[argn++]); + tprintf(", %lu, ", tcp->u_arg[argn++]); printxval(advise, tcp->u_arg[argn], "POSIX_FADV_???"); return RVAL_DECODED; -- 1.7.10.4 -- ___ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel
[PATCH 05/11] fallocate: Change print format of offset and len arguments to signed
Since types of these arguments is off_t and kernel actually expects signed values (in order to fail in case negative values are provided), it is reasonable to display these values as signed as well. * fallocate.c (SYS_FUNC(fallocate)): Change conversion specifier for printing "offset" and "len" syscall arguments from %llu to %lld. --- fallocate.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fallocate.c b/fallocate.c index 0b1cfec..b707279 100644 --- a/fallocate.c +++ b/fallocate.c @@ -19,10 +19,10 @@ SYS_FUNC(fallocate) tprints(", "); /* offset */ - argn = printllval(tcp, "%llu, ", 2); + argn = printllval(tcp, "%lld, ", 2); /* len */ - printllval(tcp, "%llu", argn); + printllval(tcp, "%lld", argn); return RVAL_DECODED; } -- 1.7.10.4 -- ___ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel
[PATCH 10/11] tests: Add test for decoding fallocate syscall
* tests/.gitignore: Add fallocate. * tests/Makefile.am (check_PROGRAMS): Likewise. (DECODER_TESTS): Add fallocate.test. * fallocate.c: New file. * fallocate.test: Likewise. --- configure.ac |1 + tests/.gitignore |1 + tests/Makefile.am|2 ++ tests/fallocate.c| 38 ++ tests/fallocate.test |6 ++ 5 files changed, 48 insertions(+) create mode 100644 tests/fallocate.c create mode 100755 tests/fallocate.test diff --git a/configure.ac b/configure.ac index 5c924e7..404dfb9 100644 --- a/configure.ac +++ b/configure.ac @@ -281,6 +281,7 @@ AC_TYPE_UID_T AC_CHECK_FUNCS(m4_normalize([ accept4 + fallocate fanotify_mark fopen64 fork diff --git a/tests/.gitignore b/tests/.gitignore index bdb2d9a..c3665c2 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -44,6 +44,7 @@ execve-v execveat execveat-v faccessat +fallocate fanotify_mark fchdir fchmod diff --git a/tests/Makefile.am b/tests/Makefile.am index ac579c7..4fdc877 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -103,6 +103,7 @@ check_PROGRAMS = \ execveat \ execveat-v \ faccessat \ + fallocate \ fanotify_mark \ fchdir \ fchmod \ @@ -442,6 +443,7 @@ DECODER_TESTS = \ execveat-v.test \ execveat.test \ faccessat.test \ + fallocate.test \ fanotify_mark.test \ fchdir.test \ fchmod.test \ diff --git a/tests/fallocate.c b/tests/fallocate.c new file mode 100644 index 000..563f2ec --- /dev/null +++ b/tests/fallocate.c @@ -0,0 +1,38 @@ +#include "tests.h" + +#include + +#if defined(__NR_fallocate) && defined(HAVE_FALLOCATE) && HAVE_FALLOCATE + +# include +# include + +# include "xlat.h" +# include "xlat/falloc_flags.h" + +int +main(void) +{ + static const int bogus_fd = 0xbeefface; + static const int bogus_mode = 0xdeadca75; + static const off_t bogus_offset = (off_t) 0xbadc0dedda7a1057LLU; + static const off_t bogus_len = (off_t) 0xbadfaceca7b0d1e5LLU; + + long rc; + + rc = fallocate(bogus_fd, bogus_mode, bogus_offset, bogus_len); + printf("fallocate(%d, ", bogus_fd); + printflags(falloc_flags, (unsigned) bogus_mode, "FALLOC_FL_???"); + printf(", %lld, %lld) = %s\n", + (long long) bogus_offset, (long long) bogus_len, sprintrc(rc)); + + puts("+++ exited with 0 +++"); + + return 0; +} + +#else + +SKIP_MAIN_UNDEFINED("__NR_fallocate && HAVE_FALLOCATE"); + +#endif diff --git a/tests/fallocate.test b/tests/fallocate.test new file mode 100755 index 000..405187e --- /dev/null +++ b/tests/fallocate.test @@ -0,0 +1,6 @@ +#!/bin/sh + +# Check getcwd syscall decoding. + +. "${srcdir=.}/init.sh" +run_strace_match_diff -a18 -- 1.7.10.4 -- ___ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel
[PATCH 07/11] util: Add getarg_ull/getarg_ll functions
These allow retrieving specific argument in full taking into account peculiarities of runtimes which employ EXT_ARG (x32, for example). * defs.h: Add declarations of getarg_ull, getarg_ll. * util.c (getarg_ull): New function. (getarg_ll): Likewise. (printargs): Use getarg_ull for argument retrieval. --- defs.h |2 ++ util.c | 44 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/defs.h b/defs.h index 26dbf8e..593e316 100644 --- a/defs.h +++ b/defs.h @@ -546,6 +546,8 @@ extern int printllval(struct tcb *, const char *, int) extern void printaddr(long); extern void printxvals(const uint64_t, const char *, const struct xlat *, ...) ATTRIBUTE_SENTINEL; +extern unsigned long long getarg_ull(struct tcb *tcp, int argn); +extern long long getarg_ll(struct tcb *tcp, int argn); extern int printargs(struct tcb *); extern int printargs_u(struct tcb *); extern int printargs_d(struct tcb *); diff --git a/util.c b/util.c index 056711d..b17ab29 100644 --- a/util.c +++ b/util.c @@ -1413,24 +1413,44 @@ print_array(struct tcb *tcp, return cur >= end_addr; } -int -printargs(struct tcb *tcp) +unsigned long long +getarg_ull(struct tcb *tcp, int argn) { - if (entering(tcp)) { - int i; - int n = tcp->s_ent->nargs; - for (i = 0; i < n; i++) { #if HAVE_STRUCT_TCB_EXT_ARG # if SUPPORTED_PERSONALITIES > 1 - if (current_personality == 1) - tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]); - else + if (current_personality == 1) + return (unsigned long) tcp->u_arg[argn]; + else # endif - tprintf("%s%#llx", i ? ", " : "", tcp->ext_arg[i]); + return (unsigned long long) tcp->ext_arg[argn]; #else - tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]); + return (unsigned long) tcp->u_arg[argn]; #endif - } +} + +long long +getarg_ll(struct tcb *tcp, int argn) +{ +#if HAVE_STRUCT_TCB_EXT_ARG +# if SUPPORTED_PERSONALITIES > 1 + if (current_personality == 1) + return (long) tcp->u_arg[argn]; + else +# endif + return (long long) tcp->ext_arg[argn]; +#else + return (long) tcp->u_arg[argn]; +#endif +} + +int +printargs(struct tcb *tcp) +{ + if (entering(tcp)) { + int i; + int n = tcp->s_ent->nargs; + for (i = 0; i < n; i++) + tprintf("%s%#llx", i ? ", " : "", getarg_ull(tcp, i)); } return 0; } -- 1.7.10.4 -- ___ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel
[PATCH 08/11] fadvise: Use getarg_ull for obtaining len argument of fadvise64 syscall
Since it is size_t, it is 64-bit wide on x32 and special care should be made in order to obtain it. * fadvise.c (SYS_FUNC(fadvise64)): Use getarg_ull for obtaining value of the "len" syscall argument. --- fadvise.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fadvise.c b/fadvise.c index 208f533..34933f7 100644 --- a/fadvise.c +++ b/fadvise.c @@ -42,7 +42,7 @@ SYS_FUNC(fadvise64) printfd(tcp, tcp->u_arg[0]); argn = printllval(tcp, ", %lld", 1); - tprintf(", %lu, ", tcp->u_arg[argn++]); + tprintf(", %llu, ", getarg_ull(tcp, argn++)); printxval(advise, tcp->u_arg[argn], "POSIX_FADV_???"); return RVAL_DECODED; -- 1.7.10.4 -- ___ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel
[PATCH 11/11] tests: Add test for decoding fadvise syscall
* tests/.gitignore: Add fadvise64, fadvise64_64. * tests/Makefile.am (check_PROGRAMS): Likewise. (DECODER_TESTS): Add fadvise64.test, fadvise64_64.test. * fadvise64.c: New file. * fadvise64_64.c: Likewise. * fadvise64.test: Likewise. * fadvise64_64.test: Likewise. --- tests/.gitignore|2 ++ tests/Makefile.am |4 +++ tests/fadvise64.c | 71 +++ tests/fadvise64.test|6 tests/fadvise64_64.c| 59 +++ tests/fadvise64_64.test |6 6 files changed, 148 insertions(+) create mode 100644 tests/fadvise64.c create mode 100755 tests/fadvise64.test create mode 100644 tests/fadvise64_64.c create mode 100755 tests/fadvise64_64.test diff --git a/tests/.gitignore b/tests/.gitignore index c3665c2..b41459a 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -44,6 +44,8 @@ execve-v execveat execveat-v faccessat +fadvise64 +fadvise64_64 fallocate fanotify_mark fchdir diff --git a/tests/Makefile.am b/tests/Makefile.am index 4fdc877..424c5bb 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -103,6 +103,8 @@ check_PROGRAMS = \ execveat \ execveat-v \ faccessat \ + fadvise64 \ + fadvise64_64 \ fallocate \ fanotify_mark \ fchdir \ @@ -443,6 +445,8 @@ DECODER_TESTS = \ execveat-v.test \ execveat.test \ faccessat.test \ + fadvise64.test \ + fadvise64_64.test \ fallocate.test \ fanotify_mark.test \ fchdir.test \ diff --git a/tests/fadvise64.c b/tests/fadvise64.c new file mode 100644 index 000..812d4f3 --- /dev/null +++ b/tests/fadvise64.c @@ -0,0 +1,71 @@ +#include "tests.h" + +#include + +#if defined(__NR_fadvise64) + +# include +# include +# include +# include + +# include "xlat.h" +# include "xlat/advise.h" + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define __LONG_LONG_PAIR(HI, LO) LO, HI +#elif __BYTE_ORDER == __BIG_ENDIAN +# define __LONG_LONG_PAIR(HI, LO) HI, LO +#endif + +void do_fadvise64(int fd, long long offset, long long len, int advice) +{ + long ret; + +# if (LONG_MAX > INT_MAX) || defined(__x86_64__) && defined(__ILP32__) \ +|| defined(LINUX_MIPSN32) + ret = syscall(__NR_fadvise64, fd, offset, len, advice); + + printf("fadvise64(%d, %lld, %llu, ", fd, offset, len); +# else /* LONG_MAX > INT_MAX */ +# if defined(POWERPC) + ret = syscall(__NR_fadvise64, fd, 0, + __LONG_LONG_PAIR ((long) (offset >> 32), (long) offset), + (long) len, advice); + printf("fadvise64(%d, %lld, %lu, ", fd, offset, (long) len); +# elif defined(LINUX_MIPSO32) + ret = syscall(__NR_fadvise64, fd, 0, + __LONG_LONG_PAIR ((long) (offset >> 32), (long) offset), + __LONG_LONG_PAIR ((long) (len >> 32), (long) len), advice); + printf("fadvise64(%d, %lld, %lld, ", fd, offset, len); +# else + ret = syscall(__NR_fadvise64, fd, + __LONG_LONG_PAIR ((long) (offset >> 32), (long) offset), + (long) len, advice); + printf("fadvise64(%d, %lld, %lu, ", fd, offset, (long) len); +# endif +# endif /* LONG_MAX > INT_MAX */ + printxval(advise, (unsigned) advice, "POSIX_FADV_???"); + printf(") = %s\n", sprintrc(ret)); +} + +int +main(void) +{ + static const int bogus_fd = 0xbeefface; + static const long long bogus_offset = 0xbadc0dedda7a1057LLU; + static const long long bogus_len = (long) 0xbadfaceca7b0d1e5LLU; + static const int bogus_advice = 0xdeadca75; + + do_fadvise64(bogus_fd, bogus_offset, bogus_len, bogus_advice); + + puts("+++ exited with 0 +++"); + + return 0; +} + +#else + +SKIP_MAIN_UNDEFINED("__NR_fadvise64"); + +#endif diff --git a/tests/fadvise64.test b/tests/fadvise64.test new file mode 100755 index 000..46c5856 --- /dev/null +++ b/tests/fadvise64.test @@ -0,0 +1,6 @@ +#!/bin/sh + +# Check fadvise64 syscall decoding. + +. "${srcdir=.}/init.sh" +run_strace_match_diff -a18 diff --git a/tests/fadvise64_64.c b/tests/fadvise64_64.c new file mode 100644 index 000..35f64a0 --- /dev/null +++ b/tests/fadvise64_64.c @@ -0,0 +1,59 @@ +#include "tests.h" + +#include + +#if defined(__NR_fadvise64_64) || defined(__NR_arm_fadvise64_64) + +# include +# include +# include +# include + +# include "xlat.h" +# include "xlat/advise.h" + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define __LONG_LONG_PAIR(HI, LO) LO, HI +#elif __BYTE_ORDER == __BIG_ENDIAN +# define __LONG_LONG_PAIR(HI, LO) HI, LO +#endif + +void do_fadvise64_64(int fd, long long offset, long long len, int advice) +{ + long ret; + +# ifdef ARM + ret = syscall(__NR_arm_fadvise64_64, fd, advice, + __LONG_LONG_PAIR ((long) (offset >> 32), (long) offset), + __LONG_LONG_PAIR ((long) (len >> 32), (long)len)); +# else + ret = syscall(__NR_fadvise64_64, fd, + __LONG_LONG_PAIR
[PATCH 09/11] Use sys_fadvise64 as a decoder for fadvise64 syscall on x32
fadvise_64_64 decoder previously employed but it has different sign of the "len" argument (loff_t against size_t). * linux/x32/syscallent.h: Change SEN(fadvise64_64) to SEN(fadvise64) for record 221. --- linux/x32/syscallent.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/x32/syscallent.h b/linux/x32/syscallent.h index 305cbbc..10443d3 100644 --- a/linux/x32/syscallent.h +++ b/linux/x32/syscallent.h @@ -219,7 +219,7 @@ [218] = { 1, 0, SEN(set_tid_address), "set_tid_address" }, [219] = { 0, 0, SEN(restart_syscall), "restart_syscall" }, [220] = { 4, TI, SEN(semtimedop),"semtimedop" }, -[221] = { 4, TD, SEN(fadvise64_64), "fadvise64" }, +[221] = { 4, TD, SEN(fadvise64), "fadvise64" }, [222] = { 3, 0, SEN(printargs), "64:timer_create" }, [223] = { 4, 0, SEN(timer_settime), "timer_settime" }, [224] = { 2, 0, SEN(timer_gettime), "timer_gettime" }, -- 1.7.10.4 -- ___ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel