http://www.perlmonks.org?node_id=356343

Perl's profilers bite. I should know, I wrote one: Devel::Profiler. It's marginally better than the most common alternative, Devel::DProf, but it's very slow and breaks in many common scenarios. I've got an idea that might produce something better, but I want to get a reality check before I go and dump time into it.

I got the idea while reading an article about Intel's VTune profiler in Doctor Dobb's Journal. VTune works via an interupt handler which wakes up periodically and samples the instruction pointer of the process. These samples are used to construct a profile of the activity of the process. It's not a "perfect" profile in that it will miss things that happen infrequently or take very little time, but that's entirely acceptable in a profiler.

The up-side is that a sampling profiler like VTune is minimally invasive. It doesn't instrument the code being profiled and it can run so fast that it doesn't slow down the code being profiled. This means that the profiling data should be very reliable, corresponding closely to the behavior of the code when it's not being profiled.

So I started wondering what VTune-for-Perl would be like. Here's some random ideas:

  • Something would run at the start of the process and put the pointer for the currently executing opcode somewhere predictable (on disk? on a fifo?). I think that's called 'curcop' in the Perl core, but I could be wrong.
  • The interupt handler would wake up and saves the value of curcop each time it runs. The interval would be configurable just like it is in VTune.
  • At the end of the process code would need to be run to turn the curcop values into subroutine names and (if possible) line numbers. It seems like a walk of the op-tree with the B:: tools might allow this, but I'm not sure. I do know that this has to happen at the end because of eval"", dynamic requires, autoloading, etc.
Given the above, I have a few problems:

  • I don't know how to write an interupt handler. I think it would require a kernel module under Linux, which would be entirely new ground for me.
  • I don't know how I would get ahold of &curcop at the start of the process. Maybe write a tiny XS module to do it?
  • I don't know how to map curcop values to subroutine names.

Help or pointers to RTFM on any of these topics would be greatly appreciated.

-sam

PS: Please don't suggest I use the Perl debugger (it's broken) or fix the Perl debugger (I can't and I think the only person that can is Ilya and he's too busy). If someone did fix the debugger I could just use Devel::DProf and it would probably be good enough. If you want to know what's wrong with the debugger, do a search on perl5-porters for bug-reports concerning seg-faults from Devel::DProf.