下面的SystemTap脚本的目的是在启动具有给定文件名的进程时启动strace
。
使用以下命令调用它:
stap -g -v './sstrace.stp' "$PATTERN"
其中PATTERN可以是mount
。
#!/usr/bin/env stap
# Assign command line parameter to the variable.
@define target_filename %( @1 %) # The regex the script will trigger on given as CLI parameter
probe begin {
printf( "Probe starting ...\n" )
printf( "Try to attach strace upon executing binary (regex) /%s/\n\n" , @target_filename )
}
probe end {
printf( "Wrapping up ...\n" )
}
probe syscall.execve {
if ( filename =~ @target_filename ) {
start_trace( pid() )
}
}
###
### FUNCTIONS
###
function start_trace( pid ) {
raise( 19 )
# Sleeping is bad practice in SystemTap probe, but don't know how to otherwise
# wait for strace to initialize in time. This will not work as expected when
# workting interactively. Compare these two results while increasing below sleep
# to 1 second.
# $ sudo ./go date
# $ date; echo hi
# $ bash -c 'date; echo hi'
system( sprintf( "strace -f -p %i & sleep 0.01; kill -CONT %i" , pid , pid ) )
}
这个想法是我停止执行(raise( -19 )
)目标进程足够长的时间,以使strace
可以附加到该进程,然后重新启动目标进程(kill -CONT $TARGET_PID
)。这通常可行,但不幸的是断断续续。
工作正常时,strace
会在execve()
之后立即弹出,类似于:
$ strace date 2>&1 | head
execve("/bin/date", ["date"], 0x7ffeb7ce6430 /* 64 vars */) = 0
brk(NULL) = 0x5578de8fa000 <== strace kicks in here.
access("/etc/ld.so.nohwcap", F_O............
现在,我至少要真正理解并希望解决的问题是,在某些系统上我无法kill -STOP
进行目标进程,它仅引发以下错误:kill: process xyz does not. exist
我知道在调用execve
系统调用时,该PID已经存在。我不明白的是为什么它似乎没有遵守SIGSTOP
。
有人知道为什么会这样吗,如何修复SystemTap脚本,或者有一种更聪明的方法来实现开始动态跟踪进程的目标?