As a support analyst, several times I ran into an occasion when I wished I could stop the process right when it writes certain string to a file(or STDOUT or socket). Maybe I can do it like:
$ 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.

Comments:

[Trackback] This is a sequel to my last entry . I modified the dtrace script like below. I had to comment out &quot;exit()&quot; line to suspend the process. Unlike when I ran this against 'cat' process, java process continued to run after stop() is called and dt...

Posted by Let the Sunshine In on August 29, 2008 at 04:14 PM JST #

Post a Comment:
  • HTML Syntax: NOT allowed

This blog copyright 2010 by Katsumi Inoue