Zyzik, Matt wrote:
All,
I have the following dtrace script:
syscall::*fork*:entry
/curpsinfo->pr_argc > 0/
{
this->argp = (uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
*(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) :
*(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8));
this->arg1 = copyinstr(this->argp);
printf("first arg: %s\n", this->arg1); }
I am trying to get the non-truncated first parameter of every process that
forks. The above script works, except once in a while I get these messages due
to unmapped pages:
dtrace: error on enabled probe ID 1 (ID 19253: syscall::fork1:entry):
invalid address (0xffbfe000) in action #1 at DIF offset 232
What can I do to avoid this issue? I am on Solaris 10 boxes.
If your script will run before the processes you're interested in, you could do:
proc:::exec
{
self->name = args[0];
}
proc:::exec-failure
{
self->name = 0;
}
proc:::exec-success
/self->name != 0/
{
proc_execname[curpsinfo->pr_addr] = self->name;
self->name = 0;
}
proc:::create
{
this->arg0 = proc_arg0[curpsinfo->pr_addr];
this->arg0 = (this->arg0 != NULL)?
this->arg0 : strtok(curpsinfo->pr_psargs, " ");
proc_arg0[args[0]->pr_addr] = this->arg0;
printf("%s", this->arg0);
}
proc:::exit
{
proc_arg0[curpsinfo->pr_addr] = 0; }
This will give you the pathname passed to exec, not the value of argv[0]. If
you want that, replace all of the 'exec*' probes with:
proc:::exec-success
{
proc_execname[curpsinfo->pr_addr] =
copyinstr((uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
*(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) :
*(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8))); }
I agree this solution would work if my dtrace script ran before the processes I
am interested in, but I don't have that option. I am trying to run this script
amongst long running daemons. Is there any way to accomplish what I am trying
to do? I can sleep well if someone confirms it's not possible.
--Matt
Assuming there are no spaces involved, and argv0 is < 80 characters, then:
this->arg0 = strtok(curpsinfo->pr_psargs, " ");
will work. Otherwise, there's no great way to do it.
Cheers,
- jonathan
I just want to say to the rest of the mailing list that I am
interested in a "not so great" way to do it. If anyone knows any exotic means
of force-faulting those pages, please share.
proc:::start
/!progenyof($pid)/
{
stop();
system("pargs %d | grep argv.0.: ; prun %d", pid, pid); }
I should also mention that I plan to aggregate on the values, like this:
"@agg[this->arg1] = count();"; and
print with the "tick-5s" probe. In that case, the above-mentioned method won't
be useful as I cannot collect
the output from the system(..) function.
What if you did something like this:
system("dd if=/proc/%d/as of=/dev/null bs=1 count=%d skip=%d", pid,
object_size, object_addr);
Would it fault in the missing pages for you? If so, you could safely
copyin() afterward.
Ryan
_______________________________________________
dtrace-discuss mailing list
[email protected]