13. Perl part: the virtual machine
●
●
●
●
Interpreter instance (my_perl) holds current
OP pointer
OP points to a package it was compiled from
Each OP is implemented by Perl_pp_*()
function
runops() loop consumes OP tree, calling
Perl_pp_*()
14. /* The package a process is
* executing */
global package;
/* A Perl instruction */
probe process
("/usr/lib/perl5/CORE/libperl.so")
.function ("Perl_pp_*")
{
pid = pid ();
package[pid] = user_string (
$my_perl->Icurcop
->cop_stashpv);
}
15. Kernel part: memory management
●
User calls malloc()
●
libc calls mmap2() to map anonymous memory
●
kernel maps read-only shared zero-page
●
write causes a page fault
●
do_wp_page() copies on write
16. /* Allocations per package and pid */
global allocs;
/* Account for COW */
probe kernel.function ("do_wp_page")
{
pid = pid ();
pkg = package[pid];
if (pkg != "")
allocs[pkg, pid] <<<
mem_page_size ();
}
17. Output
●
Do it as fast as we can
●
We are resource-constrained for safety
●
Process it in userspace later on
●
Also, flush it upon end
18. /* Dump frequently, to so that we
* won't overflow */
probe timer.ms (100), end
{
foreach ([pkg, pid] in allocs) {
printf (""%d","%s"n",
@sum (allocs[pkg, pid]),
pkg)
}
delete allocs;
}