Re: dtrace: failed to compile script trace.d: line 22: probe description pid14677::objc_msgSend:return does not match any probes
Re: dtrace: failed to compile script trace.d: line 22: probe description pid14677::objc_msgSend:return does not match any probes
- Subject: Re: dtrace: failed to compile script trace.d: line 22: probe description pid14677::objc_msgSend:return does not match any probes
- From: Ken Thomases <email@hidden>
- Date: Wed, 29 Jul 2009 00:01:30 -0500
On Jul 28, 2009, at 3:01 PM, Hamish Allan wrote:
pid$target::objc_msgSend:entry
/ self->collect > 0 /
{
// Technique from
http://www.friday.com/bbum/2008/01/26/objective-c-printing-class-name-from-dtrace/
// Is there really no more straightforward way to log the class
name than this?
isaptr = *(uint32_t*)copyin(arg0, 4);
classnameptr = *(uint32_t*)copyin(isaptr+8, 4);
classname = copyinstr(classnameptr);
printf("[%s %s]\n", classname, copyinstr(arg1));
}
There is a more straightforward way to log the class name. In an objc
provider probe, the probemod variable will contain the class name.
The link you were looking at, above, is for getting the class name for
an object other than the one being messaged. For example, the
argument to a function or method. But if you're interested in the
class of the object being messaged when an objc probe fires, you can
get that more easily.
You can use a probe with an empty action, and the -F option to dtrace,
to get a flow diagram of the method calls. However, that's pretty
much busted by the presence of multiple CPU cores and/or multiple
threads. Multiple CPU cores can result in DTrace getting data out of
order. Multiple threads just plain confuses its attempts to flow the
calls. So, I use something like the following to get raw data in tab-
delimited table format, and then post-process it with other tools:
============================
#pragma D option quiet
self int order, level;
#define CLASSES_PROBE(name) \
objc$target:SomeClass*::name, \
objc$target:SomeOtherClass*::name, \
objc$target:EtCetera*::name,
CLASSES_PROBE(entry),
CLASSES_PROBE(return)
{
printf("%s\t%s\t%s\t%lld\t%d\t", probemod, probefunc, probename,
(long long)tid, ++self->order);
}
CLASSES_PROBE(entry)
{
printf("%d\n", self->level++);
}
CLASSES_PROBE(return)
{
printf("%d\n", --self->level);
}
============================
During post-processing, the tid column can be used to separate the
threads into their respective data streams. Within a thread, the self-
>order column can be used to sort the rows back into order (when
DTrace gets data out of order). The self->level column can be used to
recreate the indenting of a flow diagram. The probename (entry or
return) could also be used, but then you'd have to recompute the call
depth by counting entries vs. returns, so why not have it done by
DTrace itself.
Another technique I've seen mentioned is to use the timestamp variable
to reconstruct the order of the data. That's probably cheaper to
collect than maintaining the self->order variable per thread, but may
not have the resolution to distinguish the order absolutely. (The
timestamp is expressed in nanoseconds, but may not have that
resolution.) On the other hand, it can be used to correlate the
action across threads, so that, after you've separated out the data by
thread, you can still tell when each call happened in each thread
relative to the others.
Cheers,
Ken
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden