Absent leaves
Finally getting to add an entry. Solaris being an ongoing development I've lost time to update this blog. Making some time for this will be my new endeavor (hopefully).
With that I ran into (and solved with dtrace) a little problem here. Wanting to see if a particular program was calling a particular libc(3LIB) function, setlocale(2) as it happened. We could use apptrace(1) but the program was being run from within a suite of software and this suite wasn't easy (or we were unwilling) to change it to use apptrace(1). Using dtrace to find if a process is calling a particular funcion is dead easy;
# dtrace -n 'pid$target::read:entry{}' -p 15250
dtrace: description 'pid$target::read:entry' matched 4 probes
CPU ID FUNCTION:NAME
1 46195 read:entry
#
But what of when a process would load a library after dtrace is tracing it ? This came up in the dtrace forum on this thread. Bryan, of course, came up with an answer. That and with Morgan Herrington's help, aka script-reuse, the following three dtrace scripts were written. The first, master.d, would watch for the invocation of a particular program. It would then stop the program via the dtrace function, stop() and also fork off the second dtrace script, mon_pre.d. This second dtrace script then starts the program again via prun, but stops it when the program enters main(). Finally it would fork off the last dtrace script, mon.d. Finally the third and last dtrace script would watch for particular functions being called.
master.d
#!/usr/sbin/dtrace -s
#pragma D option destructive
syscall::exece:return
/execname == $$1/
{
stop();
printf("%d %s\n", pid, execname);
printf("forking pre-monitor to watch ...%s\n\n", $$1);
printf("./mon_pre.d %d &\n\n", pid);
system("./mon_pre.d %d &", pid);
exit(0);
}
mon_pre.d
#!/usr/sbin/dtrace -Fs
#pragma D option destructive
BEGIN
{
printf("pruning process %d \n", $1);
system("prun %d", $1);
}
pid$1::main:entry
{
stop();
printf("forking final monitor to watch %d\n\n", $1);
system("./mon.d %d &", pid);
exit(0);
}
and finally mon.d
#!/usr/sbin/dtrace -Fs
#pragma D option destructive
BEGIN
{
printf("pruning %d process\n", $1);
system("prun %d", $1);
}
pid$1:libc:setlocale:entry,
pid$1:libc:textdomain:entry
{
@[probefunc] = count();
}
pid$1::exit:entry
{
exit(0);
}
One thing these scripts show is the use of the destructive mode of dtrace. Which should be used very very carefully lest one hangs ones system or worse. Credit is due to Morgan who wrote these scripts. Thanks Morgan !
Posted at 06:28PM Jan 26, 2005 by smg in Dtrace | Comments[1]
Posted by sean on January 28, 2005 at 07:04 AM GMT #