12

How to run strace on a user process for specific period of time, say 1 minute, without terminating the user process and without using Ctrl+C?

I want to create a script to automating strace execution for a user process.

adywp
  • 143
  • 1
  • 7

2 Answers2

18

With timeout in GNU coreutils, you can do:

  • Get the process id
  • Run timeout 60 strace -p PID

Here is an example.

test.sh:

#!/bin/bash

while :; do
    echo "$$"
    sleep 100
done

Run it:

$ ./test.sh
27121

Run strace with timeout:

% cuonglm at ~
% timeout 60 strace -p 27121
Process 27121 attached - interrupt to quit
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 27311
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD (Child exited) @ 0 (0) ---
wait4(-1, 0x7fff374b8598, WNOHANG, NULL) = -1 ECHILD (No child processes)
rt_sigreturn(0xffffffffffffffff)        = 0
rt_sigaction(SIGINT, {0x45c4d0, [], SA_RESTORER, 0x7fcdc10e05c0}, {0x443910, [], SA_RESTORER, 0x7fcdc10e05c0}, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
write(1, "27121\n", 6)                  = 6
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fcdc1a699d0) = 27328
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGINT, {0x443910, [], SA_RESTORER, 0x7fcdc10e05c0}, {0x45c4d0, [], SA_RESTORER, 0x7fcdc10e05c0}, 8) = 0
wait4(-1,

After 1 minute:

....
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fcdc1a699d0) = 27328
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGINT, {0x443910, [], SA_RESTORER, 0x7fcdc10e05c0}, {0x45c4d0, [], SA_RESTORER, 0x7fcdc10e05c0}, 8) = 0
wait4(-1,  <unfinished ...>
Process 27121 detached
% cuonglm at ~
cuonglm
  • 150,973
  • 38
  • 327
  • 406
  • On CentOS 7, at least, this appears to need a SIGKILL (9) otherwise the strace doesn't get killed: `timeout -s 9 10s strace ` – SiHa Mar 24 '21 at 17:24
3

timeout seems to be the most general solution. Just type timeout 60s command and the command will end in 60 seconds. It will send a TERM if the program is running by default. You can specify the signal you want to get, using the --signal option.

The duration can be set in seconds, minutes, hours or days, each of them has an specific suffix to determine what will be used.

Braiam
  • 35,380
  • 25
  • 108
  • 167