[dtrace-discuss] Handling userland char ** pointers

Nicolas Williams Nicolas.Williams at sun.com
Tue Aug 8 14:04:02 PDT 2006


On Tue, Aug 08, 2006 at 01:30:41PM -0700, Jonathan Adams wrote:
> The problem is that the storage used by copyin() is released at the end of
> the *enabling* (*NOT* the end of the probe firing).  You need to copy the
> values you need out of the copyin()ed result before the '}' for your clause.

Or he could use a single probe to do the trace(copyinstr(copyin())):

pid$target::sub2:entry
{
	trace(copyinstr(*(uintptr_t *)copyin(arg0,
		(curpsinfo->pr_dmodel == PR_MODEL_ILP32) ? 4 : 8)));
}

Worked for me on snv_40.

I was going to follow up to say this, but something nags me: the
dereference of the return value of copying after casting it to
uintptr_t.  This part of the expression is the same whether the userland
program is a 32-bit or 64-bit program, and I'm surprised it works...

That is, in this case copyin() returns a pointer to a 32-bit or 64-bit
quantity, but the rest of the script treats that pointer the same way
and it works.  Why?

> Types are always evaluated as kernel types.

Sure, but how did the cast to uintptr_t * know how many bytes were
returned by copyin()?

I would think something like this would be correct, that here DTrace
would know the size of the data copied in because of the first cast to
uin32_t * or uint64_t *:

pid$target::sub2:entry
/curpsinfo->pr_dmodel == PR_MODEL_ILP32/
{
	this->p32 = (uint32_t *)copyin(arg0, 4);
	trace(copyinstr(*(uintptr_t *)this->p32));
}

pid$target::sub2:entry
/curpsinfo->pr_dmodel == PR_MODEL_LP64/
{
	this->p64 = (uint32_t *)copyin(arg0, 8);
	trace(copyinstr(*(uintptr_t *)this->p64));
}

Nico
-- 


More information about the dtrace-discuss mailing list