DTrace: Suspend a process when it writes certain string to log file
$ tail -f server.log | grep 'Catch me!' | pstop 12345
But I thought dtrace is more efficient. So I searched for such a script both internally and externally. Didn't turn up anything. So, I thought this is a good opportunity to do exercise on dtrace.
Here's the script.
#!/bin/bash
if [ $# != 4 ]; then
echo "Usage: $0 (Process ID) (part of filename) (string to match) (offset)"
exit 1
fi
fd=$(pfiles $1 | /usr/sfw/bin/ggrep -B 2 $2 | head -1 | sed 's/:.*//')
strlen=$(echo -n $3 | wc -c)
dtrace='
#pragma D option quiet
#pragma D option destructive
syscall::write:entry
/arg0 == '$fd' && pid == $target && arg2 > '$strlen' + '$4'/
{
this->match = "'$3'" == copyinstr(arg1+'$4', '$strlen') ? 1 : 0;
}
syscall::write:entry
/arg0 == '$fd' && pid == $target && this->match == 1/
{
stop();
printf("Now is the good time to analyze the process with commands ");
printf("like gcore,pstack,jstack.\n");
printf("Resume it by \"$ prun '$1'\"");
exit(0);
}
'
/usr/sbin/dtrace -p $1 -n "$dtrace"
Here's how I tested it. This kludgy looking piece worked for 'cat' at least :)
-bash-3.00$ cat >/tmp/blah.out & [1] 15432 -bash-3.00$ ~/my_dangerous_dtrace.sh $! blah 'Catch Me!' 4 & [2] 15433 [1]+ Stopped cat >/tmp/blah.out -bash-3.00$ fg %1 cat >/tmp/blah.out 01234 0123Catch Me! Now is the good time to analyze the process with commands like gcore,pstack,jstack. Resume it by "$ prun 15432" ^C^C^C^C^D <-- Neither Ctrl-C or Ctrl-D don't stop 'cat' because it's suspended.
I haven't tested this with real world application. I am intending to test this with GlassFish soon. Meanwhile, I'll experiment if I could make my dtrace script more efficient.
Posted by Let the Sunshine In on August 29, 2008 at 04:14 PM JST #