Compare commits

...

10 Commits

Author SHA1 Message Date
a3740c54c2 Implement queueing of threads before dispatching them
It is possible that some tracees call a lot of cheap syscalls too fast,
and that can lead to starvation to the point some tracees are not served
for indefinite amount of time.  In order to solve that unfairness, try
to collect all the pending tracees first along with the relevant
information and only then dispatch the events.

* defs.h: Include "list.h".
(struct tcb): Add wait_data_idx and wait_list fields.
* strace.c (struct tcb_wait_data): Add "msg" field.
(tcb_wait_tab): New static variable.
(expand_tcbtab): Resize tcb_wait_tab along with tcbtab, provide
an additional slot for extra event.
(droptcb): Remove tcp from wait_list.
(maybe_switch_tcbs): Get old pid from
tcb_wait_tab[tcp->wait_data_idx].msg.
(next_event): Add pending_tcps, extra_tcp, wait_nohang, elem, and
wait_tab_pos variables; check for elements in pending_tcps and skip
waiting if the list is not empty; check for extra_tcp and skip waiting
along with swapping wait_data_idx with wait_extra_data_idx;
after the initial wait, call wait4() in loop with WNOHANG flag set;
fetch siginfo on signal and eventmsg on PTRACE_EVENT_EXEC;
return the first tcp in pending_tcps list.
* tests/Makefile.am (XFAIL_TEST): Remove looping_threads.test.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=478419
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=526740
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=851457
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1609318
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1610774
Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
Co-Authored-by: Denys Vlasenko <dvlasenk@redhat.com>
Co-Authored-by: Andreas Schwab <aschwab@redhat.com>
Co-Authored-by: Jeff Law <law@redhat.com>
Co-Authored-by: DJ Delorie <dj@redhat.com>
2018-11-05 17:40:36 +00:00
c528d41d26 Add a generic list implementation
Similar to one used in the Linux kernel.

* macros.h (cast_ptr, containerof): New macros.
* list.h: New file.
* Makefile.am (strace_SOURCES): Add it.
2018-11-05 17:40:36 +00:00
04bda223d9 tests: check tracing of looping threads
* test/many_looping_threads.c: Remove.
* test/.gitignore: Remove many_looping_threads.
* test/Makefile (PROGS): Likewise.
(many_looping_threads): Remove.
* tests/looping_threads.c: New file.
* tests/looping_threads.test: New test.
* tests/.gitignore: Add looping_threads.
* tests/Makefile.am (check_PROGRAMS): Likewise.
(looping_threads_LDADD): New variable.
(MISC_TESTS, XFAIL_TESTS): Add looping_threads.test.
2018-11-05 17:40:36 +00:00
f9e5f12b7c tests: extend test coverage of RND* ioctl commands
* tests/ioctl_random.c (main): Check the error path of RNDADDENTROPY
parser.  Check decoding of unrecognized RND* ioctl commands.
2018-11-05 17:40:36 +00:00
2649c8c8b6 Add support for /dev/[u]random ioctls
* random_ioctl.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* defs.h (DECL_IOCTL): Add random.
* ioctl.c (ioctl_decode): Add 'R' case.
* xlat/random_ioctl_cmds.in: New file.
* tests/ioctl_random.c: New file.
* tests/.gitignore: Add ioctl_random.
* tests/pure_executables.list: Likewise.
* tests/gen_tests.in (ioctl_random): New entry.

Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
2018-11-05 17:40:36 +00:00
e2d2dc699f Add dist/INSTALL
* dist/INSTALL: New file.
* bootstrap: Copy it.
* .gitignore: Add /INSTALL.

References: https://github.com/strace/strace/issues/17
References: https://github.com/strace/strace/issues/55
Closes: https://github.com/strace/strace/issues/67
2018-11-01 13:00:37 +00:00
846e277d0f Rename INSTALL to README-configure
* INSTALL-git.md: Replace INSTALL with README-configure.
* maint/install.texi: Likewise.
* INSTALL: Rename to README-configure, regenerate.
* Makefile.am (EXTRA_DIST): Add README-configure.

References: https://github.com/strace/strace/issues/85
Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
2018-11-01 13:00:37 +00:00
e471c53d1d dist/README: add more references
* dist/README: Mention README-hacking, add links to repositories
and the mailing list archive.

Suggested-by: Jamal Hadi Salim <jhs@mojatatu.com>
Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
2018-11-01 13:00:37 +00:00
5f7f0b6c85 README.md: add a link to the new contributors guide
* README.md: Add a link to the Guide of new contributors.

Suggested-by: Jamal Hadi Salim <jhs@mojatatu.com>
2018-11-01 13:00:37 +00:00
4c9516cc9b Post-release administrivia
* NEWS: Add a header line for the next release.
* debian/changelog.in: Add a changelog entry for 4.25-1.
* strace.spec.in: Likewise.
2018-10-30 10:43:31 +00:00
29 changed files with 859 additions and 190 deletions

1
.gitignore vendored
View File

@ -25,6 +25,7 @@
/configure
/depcomp
/gnu
/INSTALL
/install-sh
/ioctl_iocdef.[ih]
/ioctl_redefs[12].h

View File

@ -5,5 +5,5 @@ that are needed to build strace. Some of these files are generated by tools
from the GNU Autoconf and GNU Automake packages.
Note: rather than running `autoreconf` directly, please invoke `./bootstrap`
script and follow the instructions given in [INSTALL](INSTALL) file for further
script and follow the instructions given in [INSTALL](README-configure) file for further
building and installation.

View File

@ -185,6 +185,7 @@ strace_SOURCES = \
linux/asm_stat.h \
linux/x32/asm_stat.h \
linux/x86_64/asm_stat.h \
list.h \
listen.c \
lookup_dcookie.c \
loop.c \
@ -267,6 +268,7 @@ strace_SOURCES = \
ptp.c \
ptrace.h \
quota.c \
random_ioctl.c \
readahead.c \
readlink.c \
reboot.c \
@ -402,6 +404,7 @@ EXTRA_DIST = \
CREDITS \
ChangeLog \
ChangeLog-CVS \
README-configure \
README-linux-ptrace \
debian/changelog \
debian/compat \

3
NEWS
View File

@ -1,3 +1,6 @@
Noteworthy changes in release ?.?? (????-??-??)
===============================================
Noteworthy changes in release 4.25 (2018-10-30)
===============================================

View File

@ -15,10 +15,10 @@ Basic Installation
Briefly, the shell command './configure && make && make install' should
configure, build, and install this package. The following more-detailed
instructions are generic; see the 'README' file for instructions
specific to this package. Some packages provide this 'INSTALL' file but
do not implement all of the features documented below. The lack of an
optional feature in a given package is not necessarily a bug. More
recommendations for GNU packages can be found in *note Makefile
specific to this package. Some packages provide this 'README-configure'
file but do not implement all of the features documented below. The
lack of an optional feature in a given package is not necessarily a bug.
More recommendations for GNU packages can be found in *note Makefile
Conventions: (standards)Makefile Conventions.
The 'configure' shell script attempts to guess correct values for

View File

@ -9,6 +9,8 @@ See the file [NEWS](NEWS) for information on what has changed in recent versions
Please read the file [INSTALL-git](INSTALL-git.md) for installation instructions.
Please take a look at [the guide for new contributors](https://strace.io/wiki/NewContributorGuide) if you want to get involved in strace development.
The user discussion and development of strace take place on [the strace mailing list](https://lists.strace.io/mailman/listinfo/strace-devel) -- everyone is welcome to post bug reports, feature requests, comments and patches to strace-devel@lists.strace.io. The mailing list archives are available at https://lists.strace.io/pipermail/strace-devel/ and other archival sites.
The GIT repository of strace is available at [GitHub](https://github.com/strace/strace/) and [GitLab](https://gitlab.com/strace/strace/).

View File

@ -26,7 +26,7 @@ for m in m32 mx32; do
done
done
for f in README; do
for f in README INSTALL; do
cp "dist/$f" .
done

6
debian/changelog.in vendored
View File

@ -4,6 +4,12 @@ strace (@PACKAGE_VERSION@-1) experimental; urgency=low
-- Strace <@PACKAGE_BUGREPORT@> @DEB_CHANGELOGTIME@
strace (4.25-1) unstable; urgency=medium
* New upstream version.
-- Dmitry V. Levin <ldv@altlinux.org> Tue, 30 Oct 2018 08:09:10 +0000
strace (4.24-1) unstable; urgency=medium
* New upstream version.

11
defs.h
View File

@ -57,6 +57,7 @@
#include "error_prints.h"
#include "gcc_compat.h"
#include "kernel_types.h"
#include "list.h"
#include "macros.h"
#include "mpers_type.h"
#include "string_to_uint.h"
@ -236,6 +237,15 @@ struct tcb {
struct mmap_cache_t *mmap_cache;
/*
* Data that is stored during process wait traversal.
* We use indices as the actual data is stored in an array
* that is realloc'ed in runtime.
*/
size_t wait_data_idx;
struct list_item wait_list;
#ifdef HAVE_LINUX_KVM_H
struct vcpu_info *vcpu_info_list;
#endif
@ -973,6 +983,7 @@ DECL_IOCTL(kvm);
DECL_IOCTL(nbd);
DECL_IOCTL(nsfs);
DECL_IOCTL(ptp);
DECL_IOCTL(random);
DECL_IOCTL(scsi);
DECL_IOCTL(term);
DECL_IOCTL(ubi);

134
dist/INSTALL vendored Normal file
View File

@ -0,0 +1,134 @@
0. BUILD REQUIREMENTS
- Sane POSIX shell.
- gcc-like compiler that supports C99 and some GNU extensions (namely, empty
structures, empty definitions, zero length arrays, ranged designated
initialisers).
- libc. GNU libc and musl are supported.
- Linux UAPI headers.
- GNU Make.
- GNU coreutils.
- For running test suite: gawk, grep, sed, runtime environment for all
personalities.
- Requirements for optional features are documented in their description.
1. CONFIGURATION AND OPTIONAL FEATURES
Configuration is done using GNU Autoconf-generated configure script.
Please refer to the README-configure file for generic information regarding
configure usage.
In addition to standard configure options, strace's configure file provides
the following options:
1.1. Additional build and testing hardening
--enable-gcc-Werror turn on gcc's -Werror option
--enable-code-coverage Whether to enable code coverage support
--with-gcov=GCOV use given GCOV for coverage (GCOV=gcov).
--enable-valgrind Whether to enable Valgrind on the unit tests
--disable-valgrind-memcheck
Whether to skip memcheck during the Valgrind tests
--disable-valgrind-helgrind
Whether to skip helgrind during the Valgrind tests
--disable-valgrind-drd Whether to skip drd during the Valgrind tests
--enable-valgrind-sgcheck
Whether to use sgcheck during the Valgrind tests
1.2. Optional features
1.2.1. Multiple personalities support
--enable-mpers=yes|no|check|m32|mx32
whether to enable multiple personalities support
required for proper decoding of structures used by
tracees with personalities that differ from the
personality of strace, default is yes.
Personality is a way system call is performed (in terms of ABI). For example,
Linux kernel on multiple 64-bit architectures that evolve from their 32-bit
counterparts have support for running 32-bit binaries with 32-bit system call
ABI, and that system call ABI constitutes a separate personality in strace's
terms. Another example is 32-on-64 bit ABI; while exploiting the same way for
performing system calls as native 64-bit system calls, this ABI has different
type sizes and, as a result, also constitutes a separate personality; the only
such ABI that is currently supported by strace is x32 on x86_64. This is
important as different ABIs use different alignments and type sizes, as a
result, fields in structures in unions have different offsets on different
ABIs. In order to be able to correctly parse all the structures used in various
system calls and ioctl commands, strace compiles these structure definitions
for these different ABI and then parses DWARF of these compiled definitions in
order to generate proper structure definitions that compiled with decoder code.
Taking the aforementioned into account, there are the following requirements:
- gawk (at least version 3)
- Ability to compile for m32 personality (on architectures where it is supported)
- On x86_64, x32, powerpc64, sparc64, riscv64, tile64: gcc -m32
- s390x: gcc -m31
- AArch64: a separate compiler for armv7 EABI
- See information about configuration in "1.3.2. AArch64: AArch32 support"
- Ability to compile for mx32 personality (on architectures where it is supported)
- On x86_64: gcc -mx32
- For tests: runtime support (linker, libc, and loader)
1.2.2. Stack unwinding (-k option)
--with-libunwind use libunwind to implement stack tracing support
--with-libiberty use libiberty to demangle symbols in stack trace
1.3. Architecture-specific features
1.3.1. ARMv7: OABI support
--enable-arm-oabi enable OABI support on ARM EABI
1.3.2. AArch64: AArch32 support
CC_FOR_M32
CPP_FOR_M32
CFLAGS_FOR_M32
CPPFLAGS_FOR_M32
1.4. Miscellanea
1.4.1. Static build configuration
For static linking, provide LDFLAGS='-static -pthread'.
1.4.2. Cross-compilation configuration
2. BUILDING
make
make V=1
3. TESTING
make check
TESTS='list of tests'
VALGRIND_FLAGS
TIMEOUT_DURATION
BTRFS_MOUNTPOINT
4. ADDITIONAL TARGETS
make code-coverage-capture
make code-coverage-capture CODE_COVERAGE_BRANCH_COVERAGE=
5. INSTALLATION
make install
6. PACKAGING
6.1. Distribution tarball
./make-dist
Requires git
6.2. dpkg package
6.3. RPM package

8
dist/README vendored
View File

@ -10,13 +10,21 @@ of Paul Kranenburg; see the file COPYING for details.
See the file CREDITS for a list of authors and other contributors.
See the file INSTALL for compilation and installation instructions.
See the file NEWS for information on what has changed in recent versions.
See the file README-hacking for information related to strace development.
The project's homepage is at
https://strace.io
The GIT repository of strace is available at
https://github.com/strace/strace/ and https://gitlab.com/strace/strace/
strace has a mailing list:
strace-devel@lists.strace.io
Everyone is welcome to post bug reports, feature requests, comments
and patches to the list. The mailing list archives are available at
https://lists.strace.io/pipermail/strace-devel/
System requirements:
* Linux kernel >= 2.6.18 is recommended. Older versions might still work
but they haven't been thoroughly tested with this release.

View File

@ -329,6 +329,8 @@ ioctl_decode(struct tcb *tcp)
return inotify_ioctl(tcp, code, arg);
case 0xab:
return nbd_ioctl(tcp, code, arg);
case 'R':
return random_ioctl(tcp, code, arg);
default:
break;
}

137
list.h Normal file
View File

@ -0,0 +1,137 @@
/*
* Some simple implementation of a list similar to one used in the kernel.
*
* Copyright (c) 2016-2018 The strace developers.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef STRACE_LIST_H
#define STRACE_LIST_H
#include "macros.h"
struct list_item {
struct list_item *prev;
struct list_item *next;
};
#define EMPTY_LIST(l_) struct list_item l_ = { &l_, &l_ }
static inline void
list_init(struct list_item *l)
{
l->prev = l;
l->next = l;
}
static inline bool
list_is_empty(struct list_item *l)
{
return (l->next == l) && (l->prev == l);
}
#define list_elem(var, type, field) containerof((var), type, field)
#define list_head(head, type, field) \
(list_is_empty(head) ? NULL : list_elem((head)->next, type, field))
#define list_tail(head, type, field) \
(list_is_empty(head) ? NULL : list_elem((head)->prev, type, field))
#define list_next(val, field) \
list_elem((val)->field.next, typeof(*(val)), field)
#define list_prev(val, field) \
list_elem((val)->field.prev, typeof(*(val)), field)
static inline void
list_insert(struct list_item *head, struct list_item *item)
{
item->next = head->next;
item->prev = head;
head->next->prev = item;
head->next = item;
}
static inline void
list_append(struct list_item *head, struct list_item *item)
{
item->next = head;
item->prev = head->prev;
head->prev->next = item;
head->prev = item;
}
static inline void
list_remove(struct list_item *item)
{
if (!item->next || !item->prev)
return;
item->prev->next = item->next;
item->next->prev = item->prev;
item->next = item->prev = NULL;
}
static inline struct list_item *
list_remove_tail(struct list_item *head)
{
struct list_item *t = list_is_empty(head) ? NULL : head->prev;
if (t)
list_remove(t);
return t;
}
static inline struct list_item *
list_remove_head(struct list_item *head)
{
struct list_item *h = list_is_empty(head) ? NULL : head->next;
if (h)
list_remove(h);
return h;
}
static inline void
list_replace(struct list_item *old, struct list_item *new)
{
new->next = old->next;
new->prev = old->prev;
old->prev->next = new;
old->next->prev = new;
old->next = old->prev = NULL;
}
#define list_foreach(var_, head_, field_) \
for (var_ = list_elem((head_)->next, typeof(*var_), field_); \
&(var_->field_) != (head_); var_ = list_next(var_, field_))
#define list_foreach_safe(var_, head_, field_, _tmp) \
for (var_ = list_elem((head_)->next, typeof(*var_), field_), \
_tmp = list_elem((var_)->field_.next, typeof(*var_), field_); \
&var_->field_ != head_; var_ = _tmp, _tmp = list_next(_tmp, field_))
#endif /* !STRACE_LIST_H */

View File

@ -57,6 +57,15 @@
(offsetof(type_, member_) + sizeof(((type_ *)0)->member_))
#endif
#ifndef cast_ptr
# define cast_ptr(type, var) ((type) (uintptr_t) (const volatile void *) (var))
#endif
#ifndef containerof
# define containerof(x, s, m) \
cast_ptr(s *, (const volatile char *) (x) - offsetof(s, m))
#endif
static inline bool
is_filled(const char *ptr, char fill, size_t size)
{

View File

@ -1,5 +1,5 @@
@c This file is imported from GNU Autoconf and edited to produce
@c the INSTALL file.
@c the README-configure file.
@ifclear autoconf
@ -24,8 +24,8 @@ should configure, build, and install this package. The following
more-detailed instructions are generic; see the @file{README} file for
instructions specific to this package.
@ifclear autoconf
Some packages provide this @file{INSTALL} file but do not implement all
of the features documented below. The lack of an optional feature in a
Some packages provide this @file{README-configure} file but do not implement
all of the features documented below. The lack of an optional feature in a
given package is not necessarily a bug.
@end ifclear
More recommendations for GNU packages can be found in

81
random_ioctl.c Normal file
View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2018 The strace developers.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "defs.h"
#include "print_fields.h"
#include <linux/types.h>
#include <linux/random.h>
#define XLAT_MACROS_ONLY
# include "xlat/random_ioctl_cmds.h"
#undef XLAT_MACROS_ONLY
/*
* RNDGETPOOL was removed in 2.6.9, so non-ancient kernels always
* return -EINVAL for that.
*/
int
random_ioctl(struct tcb *const tcp, const unsigned int code,
const kernel_ulong_t arg)
{
struct rand_pool_info info;
kernel_ulong_t buf;
switch (code) {
case RNDGETENTCNT:
if (entering(tcp))
return 0;
ATTRIBUTE_FALLTHROUGH;
case RNDADDTOENTCNT:
tprints(", ");
printnum_int(tcp, arg, "%d");
break;
case RNDADDENTROPY:
tprints(", ");
if (!umove_or_printaddr(tcp, arg, &info)) {
PRINT_FIELD_D("{", info, entropy_count);
PRINT_FIELD_D(", ", info, buf_size);
tprints(", buf=");
buf = arg + offsetof(struct rand_pool_info, buf);
printstrn(tcp, buf, info.buf_size);
tprints("}");
}
break;
/* ioctls with no parameters */
case RNDZAPENTCNT:
case RNDCLEARPOOL:
case RNDRESEEDCRNG:
break;
default:
return RVAL_DECODED;
}
return RVAL_IOCTL_DECODED;
}

335
strace.c
View File

@ -161,10 +161,17 @@ static struct tcb *current_tcp;
struct tcb_wait_data {
enum trace_event te; /**< Event passed to dispatch_event() */
int status; /**< status, returned by wait4() */
unsigned long msg; /**< Value returned by PTRACE_GETEVENTMSG */
siginfo_t si; /**< siginfo, returned by PTRACE_GETSIGINFO */
};
static struct tcb **tcbtab;
/*
* Since the queueing of tracees stops as soon as wait4() returns EAGAIN,
* or at least two events for a single tracee, tab_wait_tab size shouldn't
* exceed tcbtabsize + 1.
*/
static struct tcb_wait_data *tcb_wait_tab;
static unsigned int nprocs;
static size_t tcbtabsize;
@ -750,6 +757,9 @@ expand_tcbtab(void)
for (tcb_ptr = tcbtab + old_tcbtabsize;
tcb_ptr < tcbtab + tcbtabsize; tcb_ptr++, newtcbs++)
*tcb_ptr = newtcbs;
tcb_wait_tab = xreallocarray(tcb_wait_tab, sizeof(*tcb_wait_tab),
tcbtabsize + 1);
}
static struct tcb *
@ -853,6 +863,8 @@ droptcb(struct tcb *tcp)
if (printing_tcp == tcp)
printing_tcp = NULL;
list_remove(&tcp->wait_list);
memset(tcp, 0, sizeof(*tcp));
}
@ -2071,10 +2083,8 @@ maybe_switch_tcbs(struct tcb *tcp, const int pid)
{
FILE *fp;
struct tcb *execve_thread;
long old_pid = 0;
long old_pid = tcb_wait_tab[tcp->wait_data_idx].msg;
if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, &old_pid) < 0)
return tcp;
/* Avoid truncation in pid2tcb() param passing */
if (old_pid <= 0 || old_pid == pid)
return tcp;
@ -2240,17 +2250,27 @@ print_event_exit(struct tcb *tcp)
static const struct tcb_wait_data *
next_event(void)
{
static struct tcb_wait_data wait_data;
int pid;
int status;
struct tcb *tcp;
struct tcb_wait_data *wd = &wait_data;
struct rusage ru;
if (interrupted)
return NULL;
struct tcb *tcp = NULL;
struct list_item *elem;
static EMPTY_LIST(pending_tcps);
if (!list_is_empty(&pending_tcps))
goto next_event_get_tcp;
static struct tcb *extra_tcp;
static size_t wait_extra_data_idx;
if (extra_tcp) {
tcp = extra_tcp;
extra_tcp = NULL;
tcp->wait_data_idx = wait_extra_data_idx;
debug_msg("dequeued extra event for pid %u", tcp->pid);
goto next_event_exit;
}
/*
* Used to exit simply when nprocs hits zero, but in this testcase:
* int main(void) { _exit(!!fork()); }
@ -2292,8 +2312,10 @@ next_event(void)
* then the system call will be interrupted and
* the expiration will be handled by the signal handler.
*/
pid = wait4(-1, &status, __WALL, (cflag ? &ru : NULL));
const int wait_errno = errno;
int status;
struct rusage ru;
int pid = wait4(-1, &status, __WALL, (cflag ? &ru : NULL));
int wait_errno = errno;
/*
* The window of opportunity to handle expirations
@ -2309,135 +2331,194 @@ next_event(void)
return NULL;
}
if (pid < 0) {
if (wait_errno == EINTR) {
wd->te = TE_NEXT;
return wd;
size_t wait_tab_pos = 0;
bool wait_nohang = false;
for (;;) {
struct tcb_wait_data *wd;
if (pid < 0) {
if (wait_errno == EINTR)
break;
if (wait_nohang)
break;
if (nprocs == 0 && wait_errno == ECHILD)
return NULL;
/*
* If nprocs > 0, ECHILD is not expected,
* treat it as any other error here:
*/
errno = wait_errno;
perror_msg_and_die("wait4(__WALL)");
}
if (nprocs == 0 && wait_errno == ECHILD)
return NULL;
/*
* If nprocs > 0, ECHILD is not expected,
* treat it as any other error here:
*/
errno = wait_errno;
perror_msg_and_die("wait4(__WALL)");
}
wd->status = status;
if (!pid)
break;
if (pid == popen_pid) {
if (!WIFSTOPPED(status))
popen_pid = 0;
wd->te = TE_NEXT;
return wd;
}
if (pid == popen_pid) {
if (!WIFSTOPPED(status))
popen_pid = 0;
break;
}
if (debug_flag)
print_debug_info(pid, status);
if (debug_flag)
print_debug_info(pid, status);
/* Look up 'pid' in our table. */
tcp = pid2tcb(pid);
/* Look up 'pid' in our table. */
tcp = pid2tcb(pid);
if (!tcp) {
tcp = maybe_allocate_tcb(pid, status);
if (!tcp) {
wd->te = TE_NEXT;
return wd;
tcp = maybe_allocate_tcb(pid, status);
if (!tcp)
break;
}
if (cflag) {
struct timespec stime = {
.tv_sec = ru.ru_stime.tv_sec,
.tv_nsec = ru.ru_stime.tv_usec * 1000
};
ts_sub(&tcp->dtime, &stime, &tcp->stime);
tcp->stime = stime;
}
if (wait_tab_pos > tcbtabsize)
error_func_msg_and_die("Wait data storage overflow "
"(wait_tab_pos %zu, nprocs %u, "
"tcbtabsize %zu)", wait_tab_pos,
nprocs, tcbtabsize);
wd = tcb_wait_tab + wait_tab_pos;
memset(wd, 0, sizeof(*wd));
if (WIFSIGNALED(status)) {
wd->te = TE_SIGNALLED;
} else if (WIFEXITED(status)) {
wd->te = TE_EXITED;
} else {
/*
* As WCONTINUED flag has not been specified to wait4,
* it cannot be WIFCONTINUED(status), so the only case
* that remains is WIFSTOPPED(status).
*/
const unsigned int sig = WSTOPSIG(status);
const unsigned int event = (unsigned int) status >> 16;
switch (event) {
case 0:
/*
* Is this post-attach SIGSTOP?
* Interestingly, the process may stop
* with STOPSIG equal to some other signal
* than SIGSTOP if we happened to attach
* just before the process takes a signal.
*/
if (sig == SIGSTOP &&
(tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
debug_func_msg("ignored SIGSTOP on "
"pid %d", tcp->pid);
tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
wd->te = TE_RESTART;
} else if (sig == syscall_trap_sig) {
wd->te = TE_SYSCALL_STOP;
} else {
/*
* True if tracee is stopped by signal
* (as opposed to "tracee received
* signal").
* TODO: shouldn't we check for
* errno == EINVAL too?
* We can get ESRCH instead, you know...
*/
bool stopped = ptrace(PTRACE_GETSIGINFO,
pid, 0, &wd->si) < 0;
wd->te = stopped ? TE_GROUP_STOP
: TE_SIGNAL_DELIVERY_STOP;
}
break;
case PTRACE_EVENT_STOP:
/*
* PTRACE_INTERRUPT-stop or group-stop.
* PTRACE_INTERRUPT-stop has sig == SIGTRAP here.
*/
switch (sig) {
case SIGSTOP:
case SIGTSTP:
case SIGTTIN:
case SIGTTOU:
wd->te = TE_GROUP_STOP;
break;
default:
wd->te = TE_RESTART;
}
break;
case PTRACE_EVENT_EXEC:
/*
* TODO: shouldn't we check for
* errno == EINVAL here, too?
* We can get ESRCH instead, you know...
*/
if (ptrace(PTRACE_GETEVENTMSG, pid, NULL,
&wd->msg) < 0)
wd->msg = 0;
wd->te = TE_STOP_BEFORE_EXECVE;
break;
case PTRACE_EVENT_EXIT:
wd->te = TE_STOP_BEFORE_EXIT;
break;
default:
wd->te = TE_RESTART;
}
}
if (tcp->wait_list.next) {
wait_extra_data_idx = wait_tab_pos;
extra_tcp = tcp;
debug_func_msg("queued extra pid %d", tcp->pid);
} else {
tcp->wait_data_idx = wait_tab_pos;
list_append(&pending_tcps, &tcp->wait_list);
debug_func_msg("queued pid %d", tcp->pid);
}
wd->status = status;
wait_tab_pos++;
if (extra_tcp)
break;
pid = wait4(-1, &status, __WALL | WNOHANG, (cflag ? &ru : NULL));
wait_errno = errno;
wait_nohang = true;
}
next_event_get_tcp:
elem = list_remove_head(&pending_tcps);
if (!elem) {
memset(tcb_wait_tab, 0, sizeof(*tcb_wait_tab));
tcb_wait_tab->te = TE_NEXT;
return tcb_wait_tab;
} else {
tcp = list_elem(elem, struct tcb, wait_list);
debug_func_msg("dequeued pid %d", tcp->pid);
}
next_event_exit:
/* Is this the very first time we see this tracee stopped? */
if (tcp->flags & TCB_STARTUP)
startup_tcb(tcp);
clear_regs(tcp);
/* Set current output file */
set_current_tcp(tcp);
if (cflag) {
struct timespec stime = {
.tv_sec = ru.ru_stime.tv_sec,
.tv_nsec = ru.ru_stime.tv_usec * 1000
};
ts_sub(&tcp->dtime, &stime, &tcp->stime);
tcp->stime = stime;
}
if (WIFSIGNALED(status)) {
wd->te = TE_SIGNALLED;
return wd;
}
if (WIFEXITED(status)) {
wd->te = TE_EXITED;
return wd;
}
/*
* As WCONTINUED flag has not been specified to wait4,
* it cannot be WIFCONTINUED(status), so the only case
* that remains is WIFSTOPPED(status).
*/
/* Is this the very first time we see this tracee stopped? */
if (tcp->flags & TCB_STARTUP)
startup_tcb(tcp);
const unsigned int sig = WSTOPSIG(status);
const unsigned int event = (unsigned int) status >> 16;
switch (event) {
case 0:
/*
* Is this post-attach SIGSTOP?
* Interestingly, the process may stop
* with STOPSIG equal to some other signal
* than SIGSTOP if we happened to attach
* just before the process takes a signal.
*/
if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
debug_func_msg("ignored SIGSTOP on pid %d", tcp->pid);
tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
wd->te = TE_RESTART;
} else if (sig == syscall_trap_sig) {
wd->te = TE_SYSCALL_STOP;
} else {
memset(&wd->si, 0, sizeof(wd->si));
/*
* True if tracee is stopped by signal
* (as opposed to "tracee received signal").
* TODO: shouldn't we check for errno == EINVAL too?
* We can get ESRCH instead, you know...
*/
bool stopped = ptrace(PTRACE_GETSIGINFO, pid, 0, &wd->si) < 0;
wd->te = stopped ? TE_GROUP_STOP : TE_SIGNAL_DELIVERY_STOP;
}
break;
case PTRACE_EVENT_STOP:
/*
* PTRACE_INTERRUPT-stop or group-stop.
* PTRACE_INTERRUPT-stop has sig == SIGTRAP here.
*/
switch (sig) {
case SIGSTOP:
case SIGTSTP:
case SIGTTIN:
case SIGTTOU:
wd->te = TE_GROUP_STOP;
break;
default:
wd->te = TE_RESTART;
}
break;
case PTRACE_EVENT_EXEC:
wd->te = TE_STOP_BEFORE_EXECVE;
break;
case PTRACE_EVENT_EXIT:
wd->te = TE_STOP_BEFORE_EXIT;
break;
default:
wd->te = TE_RESTART;
}
return wd;
return tcb_wait_tab + tcp->wait_data_idx;
}
static int

View File

@ -91,6 +91,9 @@ echo 'END OF TEST SUITE INFORMATION'
* @RPM_CHANGELOGTIME@ @PACKAGE_BUGREPORT@ - @PACKAGE_VERSION@-1
- @PACKAGE_STRING@ snapshot.
* Tue Oct 30 2018 Dmitry V. Levin <ldv@altlinux.org> - 4.25-1
- v4.24 -> v4.25.
* Tue Aug 14 2018 Dmitry V. Levin <ldv@altlinux.org> - 4.24-1
- v4.23 -> v4.24.

1
test/.gitignore vendored
View File

@ -1,7 +1,6 @@
childthread
clone
leaderkill
many_looping_threads
mmap_offset_decode
mtd
seccomp

View File

@ -3,8 +3,7 @@ CFLAGS += -Wall
PROGS = \
sig skodic clone leaderkill childthread \
sigkill_rain wait_must_be_interruptible threaded_execve \
mtd ubi seccomp sfd mmap_offset_decode x32_lseek x32_mmap \
many_looping_threads
mtd ubi seccomp sfd mmap_offset_decode x32_lseek x32_mmap
all: $(PROGS)
@ -12,8 +11,6 @@ leaderkill: LDFLAGS += -pthread
childthread: LDFLAGS += -pthread
many_looping_threads: LDFLAGS += -pthread
clean distclean:
rm -f *.o core $(PROGS) *.gdb

View File

@ -1,49 +0,0 @@
// This testcase, when run with large number of threads
// under stace -f, may never finish because strace does not
// ensure any fairness in thread scheduling:
// it restarts threads as they stop. If daughter threads crowd out
// the "mother" and _they_ get continually restarted by strace,
// the end of spawning loop will never be reached.
//
// Also, it is a testcase which triggers the
// "strace: Exit of unknown pid 32457 seen"
// message when on testcase exit, strace sees deaths of newly-attached
// threads _before_ their first syscall stop.
//
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
static int thd_no;
static void *sub_thd(void *c)
{
dprintf(1, "sub-thread %d created\n", ++thd_no);
for (;;)
getuid();
return NULL;
}
int main(int argc, char *argv[])
{
int i;
pthread_t *thd;
int num_threads = 1;
if (argv[1])
num_threads = atoi(argv[1]);
thd = malloc(num_threads * sizeof(thd[0]));
dprintf(1, "test start, num_threads:%d...\n", num_threads);
for (i = 0; i < num_threads; i++) {
pthread_create(&thd[i], NULL, sub_thd, NULL);
dprintf(1, "after pthread_create\n");
}
/* Exit. This kills all threads */
return 0;
}

2
tests/.gitignore vendored
View File

@ -158,6 +158,7 @@ ioctl_nsfs
ioctl_perf
ioctl_perf-success
ioctl_ptp
ioctl_random
ioctl_rtc
ioctl_rtc-v
ioctl_scsi
@ -209,6 +210,7 @@ list_sigaction_signum
llseek
localtime
lookup_dcookie
looping_threads
lseek
lstat
lstat64

View File

@ -129,6 +129,7 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
ksysent \
list_sigaction_signum \
localtime \
looping_threads \
mmsg-silent \
mmsg_name-v \
msg_control-v \
@ -192,6 +193,7 @@ fstat64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
fstatat64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
ftruncate64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
localtime_LDADD = $(clock_LIBS) $(LDADD)
looping_threads_LDADD = -lpthread $(LDADD)
lstat64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
mmap64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
mmap64_Xabbrev_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
@ -325,6 +327,7 @@ MISC_TESTS = \
interactive_block.test \
ksysent.test \
localtime.test \
looping_threads.test \
opipe.test \
options-syntax.test \
pc.test \

View File

@ -150,6 +150,7 @@ ioctl_nbd +ioctl.test -y
ioctl_nsfs +ioctl.test -esignal=none
ioctl_perf +ioctl.test
ioctl_ptp +ioctl.test
ioctl_random +ioctl.test
ioctl_rtc +ioctl.test
ioctl_rtc-v +ioctl.test -v
ioctl_scsi +ioctl.test

80
tests/ioctl_random.c Normal file
View File

@ -0,0 +1,80 @@
/*
* Check decoding of RND* commands of ioctl syscall.
*
* Copyright (c) 2018 The strace developers.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "tests.h"
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/random.h>
#define XLAT_MACROS_ONLY
# include "xlat/random_ioctl_cmds.h"
#undef XLAT_MACROS_ONLY
#define RVAL_EBADF " = -1 EBADF (%m)\n"
int
main(void)
{
union {
char c[sizeof(struct rand_pool_info) + 8];
struct rand_pool_info info;
} u;
struct rand_pool_info *info = &u.info;
int cnt = 6;
memcpy(info->buf, "12345678", 8);
info->buf_size = 8;
info->entropy_count = 3;
ioctl(-1, RNDGETENTCNT, &cnt);
printf("ioctl(-1, RNDGETENTCNT, %p)" RVAL_EBADF, &cnt);
ioctl(-1, RNDADDTOENTCNT, &cnt);
printf("ioctl(-1, RNDADDTOENTCNT, [6])" RVAL_EBADF);
ioctl(-1, RNDADDENTROPY, NULL);
printf("ioctl(-1, RNDADDENTROPY, NULL)" RVAL_EBADF);
ioctl(-1, RNDADDENTROPY, info);
printf("ioctl(-1, RNDADDENTROPY, {entropy_count=3, buf_size=8, buf=\"12345678\"})" RVAL_EBADF);
ioctl(-1, RNDZAPENTCNT);
printf("ioctl(-1, RNDZAPENTCNT)" RVAL_EBADF);
ioctl(-1, RNDCLEARPOOL);
printf("ioctl(-1, RNDCLEARPOOL)" RVAL_EBADF);
ioctl(-1, RNDRESEEDCRNG);
printf("ioctl(-1, RNDRESEEDCRNG)" RVAL_EBADF);
ioctl(-1, _IO('R', 0xff), NULL);
printf("ioctl(-1, _IOC(_IOC_NONE, %#x, 0xff, 0), 0)" RVAL_EBADF, 'R');
puts("+++ exited with 0 +++");
return 0;
}

110
tests/looping_threads.c Normal file
View File

@ -0,0 +1,110 @@
/*
* Check tracing of looping threads.
*
* Copyright (c) 2009-2018 The strace developers.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "tests.h"
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
static void *
thread(void *arg)
{
for (;;)
getuid();
return arg;
}
int
main(int ac, const char *av[])
{
assert(ac == 3);
int timeout = atoi(av[1]);
assert(timeout > 0);
int num_threads = atoi(av[2]);
assert(num_threads > 0);
/* Create a new process group. */
if (setpgid(0, 0))
perror_msg_and_fail("setpgid");
/*
* When the main process terminates, the process group becomes orphaned.
* If any member of the orphaned process group is stopped, then
* a SIGHUP signal followed by a SIGCONT signal is sent to each process
* in the orphaned process group.
* Create a process in a stopped state to activate this behaviour.
*/
pid_t stopped = fork();
if (stopped < 0)
perror_msg_and_fail("fork");
if (!stopped) {
raise(SIGSTOP);
_exit(0);
}
const sigset_t set = {};
const struct sigaction act = { .sa_handler = SIG_DFL };
if (sigaction(SIGALRM, &act, NULL))
perror_msg_and_fail("sigaction");
if (sigprocmask(SIG_SETMASK, &set, NULL))
perror_msg_and_fail("sigprocmask");
alarm(timeout);
/*
* Create all threads in a subprocess, this guarantees that
* their tracer will not be their parent.
*/
pid_t pid = fork();
if (pid < 0)
perror_msg_and_fail("fork");
if (!pid) {
for (int i = 0; i < num_threads; i++) {
pthread_t t;
if ((errno = pthread_create(&t, NULL, thread, NULL)))
perror_msg_and_fail("pthread_create #%d", i);
}
/* This terminates all threads. */
_exit(0);
}
int s;
if (waitpid(pid, &s, 0) != pid)
perror_msg_and_fail("waitpid");
assert(WIFEXITED(s));
return WEXITSTATUS(s);
}

37
tests/looping_threads.test Executable file
View File

@ -0,0 +1,37 @@
#!/bin/sh
#
# Check tracing of looping threads.
#
# Copyright (c) 2009-2018 The strace developers.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
. "${srcdir=.}/init.sh"
check_prog nproc
timeout="$(($TIMEOUT_DURATION/10))"
nproc="$((64+$timeout+$(nproc)))"
run_prog "../$NAME" "$timeout" "$nproc"
run_strace -f -qq -enone -esignal=none $args

View File

@ -121,6 +121,7 @@ ioctl_mtd
ioctl_nbd
ioctl_perf
ioctl_ptp
ioctl_random
ioctl_rtc
ioctl_scsi
ioctl_sg_io_v3

View File

@ -0,0 +1,7 @@
RNDGETENTCNT _IOR( 'R', 0x00, int )
RNDADDTOENTCNT _IOW( 'R', 0x01, int )
RNDGETPOOL _IOR( 'R', 0x02, int [2] )
RNDADDENTROPY _IOW( 'R', 0x03, int [2] )
RNDZAPENTCNT _IO( 'R', 0x04 )
RNDCLEARPOOL _IO( 'R', 0x06 )
RNDRESEEDCRNG _IO( 'R', 0x07 )