summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSahil Siddiq <icegambit91@gmail.com>2023-03-20 11:10:56 +0530
committerDmitry V. Levin <ldv@strace.io>2023-04-03 19:13:29 +0000
commitac1d1e25d8d45b8e74ec4cde0f06a7b1df621304 (patch)
tree0b2bffbdbdc2e14ed31c4aa8f8a77e6fb3ebcaca
parentd3b97fce7229fa8db7a87e03fcd445b8f97fe743 (diff)
downloadstrace-ac1d1e25d8d45b8e74ec4cde0f06a7b1df621304.tar.gz
Introduce -l/--syscall-limit options
Add new options to detach strace after capturing the specified number of syscalls. * src/defs.h (syscall_limit): New variable declaration. * src/strace.c (syscall_limit): New variable. (usage): Mention new options. (init): Handle them. (next_event): Break the event loop when syscall_limit == 0. * src/syscall.c (syscall_exiting_trace): Update syscall_limit. Signed-off-by: Sahil Siddiq <icegambit91@gmail.com> Resolves: https://github.com/strace/strace/issues/179
-rw-r--r--src/defs.h1
-rw-r--r--src/strace.c20
-rw-r--r--src/syscall.c3
3 files changed, 23 insertions, 1 deletions
diff --git a/src/defs.h b/src/defs.h
index 6c93d8460..245958772 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -513,6 +513,7 @@ extern int Tflag_scale;
extern int Tflag_width;
extern bool iflag;
extern bool count_wallclock;
+extern long long syscall_limit;
struct path_set_item {
const char *path;
diff --git a/src/strace.c b/src/strace.c
index 7a58bdbd6..cea445fe2 100644
--- a/src/strace.c
+++ b/src/strace.c
@@ -84,6 +84,7 @@ int Tflag_scale = 1000;
int Tflag_width = 6;
bool iflag;
bool count_wallclock;
+long long syscall_limit = -1;
static bool nflag;
static int tflag_scale = 1000000000;
static unsigned tflag_width = 0;
@@ -461,6 +462,10 @@ Statistics:\n\
-w, --summary-wall-clock\n\
summarise syscall latency (default is system time)\n\
\n\
+Stop condition:\n\
+ -l LIMIT, --syscall-limit=LIMIT\n\
+ Detach all tracees after tracing LIMIT syscalls\n\
+\n\
Tampering:\n\
-e inject=SET[:error=ERRNO|:retval=VALUE][:signal=SIG][:syscall=SYSCALL]\n\
[:delay_enter=DELAY][:delay_exit=DELAY]\n\
@@ -2245,7 +2250,7 @@ init(int argc, char *argv[])
#endif
static const char optstring[] =
- "+a:Ab:cCdDe:E:fFhiI:kno:O:p:P:qrs:S:tTu:U:vVwxX:yYzZ";
+ "+a:Ab:cCdDe:E:fFhiI:kl:no:O:p:P:qrs:S:tTu:U:vVwxX:yYzZ";
enum {
GETOPT_SECCOMP = 0x100,
@@ -2291,6 +2296,7 @@ init(int argc, char *argv[])
{ "instruction-pointer", no_argument, 0, 'i' },
{ "interruptible", required_argument, 0, 'I' },
{ "stack-traces", no_argument, 0, 'k' },
+ { "syscall-limit", required_argument, 0, 'l' },
{ "syscall-number", no_argument, 0, 'n' },
{ "output", required_argument, 0, 'o' },
{ "summary-syscall-overhead", required_argument, 0, 'O' },
@@ -2432,6 +2438,11 @@ init(int argc, char *argv[])
"build of strace");
#endif
break;
+ case 'l':
+ syscall_limit = string_to_ulonglong(optarg);
+ if (syscall_limit <= 0)
+ error_opt_arg(c, lopt, optarg);
+ break;
case 'n':
nflag = 1;
break;
@@ -3353,6 +3364,13 @@ next_event(void)
if (interrupted)
return NULL;
+ if (syscall_limit == 0) {
+ if (!is_number_in_set(QUIET_ATTACH, quiet_set))
+ error_msg("System call limit has been reached, detaching tracees");
+ strace_child = 0;
+ return NULL;
+ }
+
invalidate_umove_cache();
struct tcb *tcp = NULL;
diff --git a/src/syscall.c b/src/syscall.c
index cc37aa30c..696b81dfd 100644
--- a/src/syscall.c
+++ b/src/syscall.c
@@ -849,6 +849,9 @@ syscall_exiting_trace(struct tcb *tcp, struct timespec *ts, int res)
}
}
+ if (syscall_limit != -1)
+ syscall_limit--;
+
tprint_arg_end();
tprint_space();
tabto();