I was hanging out on the perl developer's IRC channel today, and the 
topic of providing dtrace support for perl came up, specifically how to
provide a ustack helper. I'd already read John Levon's blog post on how
he did this for python
(http://blogs.sun.com/levon/entry/python_and_dtrace_in_build), and I saw
the following comment from Bryan:

"Unfortunately, ustack helpers are impossible for environments like Ruby
and Perl, so Python and Java (and PHP if the helper were ever
integrated) may stand alone for quite some time to come..."

I assume this is because of the difficulty of unwinding the interpreter
stacks of Perl and Ruby - I don't know about Ruby, but Perl doesn't use
the C stack for holding the Perl-level stack, it maintains its own stack
(in fact, several of them).

I'm wondering if the following scheme might be a solution.

If the perl interpreter detects it is running under dtrace it builds a
'shadow' stack which it adjusts on each interpreter frame entry/exit -
basically a simple array containing perl source file name, line number
and subroutine name. The D stack helper becomes simple - it just reads
the info from the shadow stack, rather than having to try to untangle
the real interpreter stack.

The other problem is that the code which calls the ustack helper
(http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/dtrace/dtrace.c#5306)
calls the helper once for each C stack frame - and in perl there is no
direct relationship between the number of C stack frames and the number
of interpreter stack frames. We would need to be able to iterate
depending on the number of interpreter stack frames, not the number of C
stack frames.

My first thought would be to add a new D primitive - astack (application
stack). This would take one argument, which would be 1 on the first
call, and 0 on subsequent calls. The astack helper would return a string
on each call, as per ustack, and return null to indicate that it had
finished. To prevent endless loops, a maximum number of iterations would
be enforced (via a D pragma?)

The only other wrinkle (pointed out by John Levon) is dealing with 
threads - we would need a separate shadow stack for each thread, which 
means the code that maintains the shadow stacks needs some way of 
sharing a value (ideally a 0-based index) with the stack helper code. 
And I don't know enough about dtrace to fully understand how the 
per-thread D variable 'self' is allocated, or if it is accessible from 
userland.

Is there any merit in this idea, or have I missed some glaring problem?

-- 
Alan Burlison
--
_______________________________________________
dtrace-discuss mailing list
dtrace-discuss@opensolaris.org

Reply via email to