SlideShare a Scribd company logo
1 of 31
Download to read offline
DTrace
Experimental DTrace (XD)
language extensions
Matt.Ahrens@delphix.com
D is a (safe) power tool
● Some D concepts (predicates) are unfamiliar
to procedural programmers
● Some simple ideas require many steps
● These steps are (for the most part)
fundamentally necessary but tedious
● Solution: syntactic sugar
if/else in XD
vdev_queue_pending_remove:entry
{
if (stringof(args[1]->io_spa->spa_name) == $$1) {
if (args[1]->io_type == ZIO_TYPE_READ) {
@bytes_read = sum(args[1]->io_size);
} else if (args[1]->io_type == ZIO_TYPE_WRITE &&
args[1]->io_bookmark.zb_level != 2) {
@bytes_written = sum(args[1]->io_size);
}
}
}
if/else converted to D
dtrace:::ERROR{ self->_XD_error = 0x1; }
::vdev_queue_pending_remove:entry{ self->_XD_error = 0x0; }
::vdev_queue_pending_remove:entry /!self->_XD_error/
{ this->_XD_condition1 = 0x1 && stringof(args[1]->io_spa->spa_name) == $$1; }
::vdev_queue_pending_remove:entry /!self->_XD_error/
{ this->_XD_condition2 = this->_XD_condition1 && args[1]->io_type == ZIO_TYPE_READ; }
::vdev_queue_pending_remove:entry /(!self->_XD_error) && this->_XD_condition2/
{ @bytes_read = sum(args[1]->io_size); }
::vdev_queue_pending_remove:entry /!self->_XD_error/
{ this->_XD_condition3 = this->_XD_condition1 && !this->_XD_condition2; }
::vdev_queue_pending_remove:entry /!self->_XD_error/
{ this->_XD_condition4 =
this->_XD_condition3 && args[1]->io_type == ZIO_TYPE_WRITE && args[1]->io_bookmark.zb_level != 2; }
::vdev_queue_pending_remove:entry /!self->_XD_error && this->_XD_condition4/
{ @bytes_written = sum(args[1]->io_size); }
while loop in XD
pid$target::zprop_free_list:entry
{
ll_user = arg0;
printf("-- START --");
while10 (ll_user != NULL) {
ll_kern = copyin(ll_user, sizeof(zprop_list_t));
printf("%d", ll_kern->pl_prop);
ll_user = ll_kern->pl_next;
}
printf("-- END --");
}
entry-> variables in XD
spa_sync:return
{
printf("%s(%s, %u) took %ums",
probefunc,
entry->args[0]->spa_name, entry->args[1],
entry->elapsed_ms);
}
callers[] in XD
zrl_add:entry / callers["resolvepath,traverse"] / {@[stack()] = count()}
● The value of callers[] is a count, not just a toggle
○ Useful for examining recursive functions.
● callers["resolvepath,traverse"]
○ Either function must be in the stack
● callers["resolvepath"] && callers["traverse"]
○ Both functions must be in the stack
● Possible performance considerations
○ Each element means two more probes, be cognizant of enabled probe
effect.
How does it do that?
Changes are primarily in libdtrace
● Create parse tree
○ new nodes for "if", "while"
● Transform parse tree to remove XD
○ create new clauses
○ swap out entry->*, callers[]
● Finish compiling the (now strictly D) parse tree
● No kernel changes
How can I use it?
● https://github.com/ahrens/illumos/tree/dpp
○ fork of illumos
○ 100% libdtrace, should be easy to port
● To see the D generated from your XD
○ dtrace -xd -x tree=8 …
● Examples: https://github.com/ahrens/dtrace
● Bugs?
○ email matt@delphix.com your XD script
Field use
● In production at Delphix since April 2014
● if/else: increases legibility of larger scripts
○ ~50% of scripts use “if”
● while: rarely used
● entry->arg[], entry->elapsed
○ Extremely helpful for one-liners
○ ~75% of scripts use “entry->”
● callers[]
○ Helpful for one-liners
○ ~33% of scripts use “callers[]”
Field use (one-liner example)
● Histograms of time in foo(), broken down by
request size, when called from bar()
dtrace -xd -n ‘
foo:return
/callers[“bar”]/
{
@[entry->args[2]->b_size] =
quantize(entry->elapsed_us);
}’
Integration status
● Pollutes namespace with “_XD_*” variables
○ Should be possible to fix
● if/else: agreement that this is a good idea
○ “if” and “else” are already reserved keywords
● while: not that useful, let’s not bother
● entry->arg[], entry->elapsed
○ Concern about FBT concepts leaking into language
○ Concern about “entry” polluting namespace
○ But sooooo useful! Needs more discussion.
Integration status
● callers[]
○ Concern about dependence on FBT
○ Concern about hiding perf cost
○ Idea: implement by examining stack instead?
■ Pro: linear performance impact
■ Downside: reliance on backtrace accuracy
■ Downside: requires kernel changes
● “Is there an address in the range [x,y] in the backtrace”
What next?
1. Integrate if/else to illumos
2. Figure out entry-> concerns
3. Integrate entry-> to illumos
4. Figure out callers[] FBT vs stack()
5. Integrate callers[]
What next?
● "for" and "do" loops; "break", "continue"(?)
● #pragma D option defaultscope=local
○ bare variables will have probe-local scope
■ i.e. implicit "this->"
○ use "global->" for global variables
○ use "thread->" for thread-local variables
● "inline" functions to replace preprocessor?
● better error diagnosability?
○ dtrace: error on enabled probe ID 463 (ID 33804:
fbt:zfs:put_nvlist:entry): invalid address (0x0) in
action #1 at DIF offset 36
What next? (continued)
● Predicate Scoping
○ Applying a predicate to multiple clauses specified in a block:
/callers["spa_sync"]/
{
zio_read:entry {
stack();
}
metaslab_sync:return {
trace(entry->elapsed_ms);
}
}
DTrace
XD: DTrace language extensions
Matt.Ahrens@delphix.com
if/else in D
vdev_queue_pending_remove:entry
/stringof(args[1]->io_spa->spa_name) == $$1 &&
args[1]->io_type == ZIO_TYPE_READ/
{
@bytes_read = sum(args[1]->io_size);
}
vdev_queue_pending_remove:entry
/stringof(args[1]->io_spa->spa_name) == $$1 &&
args[1]->io_type == ZIO_TYPE_WRITE &&
args[1]->io_bookmark.zb_level != -2/
{
@bytes_written = sum(args[1]->io_size);
if/else in XD
vdev_queue_pending_remove:entry
{
if (stringof(args[1]->io_spa->spa_name) == $$1) {
if (args[1]->io_type == ZIO_TYPE_READ) {
@bytes_read = sum(args[1]->io_size);
} else if (args[1]->io_type == ZIO_TYPE_WRITE &&
args[1]->io_bookmark.zb_level != 2) {
@bytes_written = sum(args[1]->io_size);
}
}
}
if/else converted to D
dtrace:::ERROR{ self->_XD_error = 0x1; }
::vdev_queue_pending_remove:entry{ self->_XD_error = 0x0; }
::vdev_queue_pending_remove:entry /!self->_XD_error/
{ this->_XD_condition1 = 0x1 && stringof(args[1]->io_spa->spa_name) == $$1; }
::vdev_queue_pending_remove:entry /!self->_XD_error/
{ this->_XD_condition2 = this->_XD_condition1 && args[1]->io_type == ZIO_TYPE_READ; }
::vdev_queue_pending_remove:entry /(!self->_XD_error) && this->_XD_condition2/
{ @bytes_read = sum(args[1]->io_size); }
::vdev_queue_pending_remove:entry /!self->_XD_error/
{ this->_XD_condition3 = this->_XD_condition1 && !this->_XD_condition2; }
::vdev_queue_pending_remove:entry /!self->_XD_error/
{ this->_XD_condition4 =
this->_XD_condition3 && args[1]->io_type == ZIO_TYPE_WRITE && args[1]->io_bookmark.zb_level != 2; }
::vdev_queue_pending_remove:entry /!self->_XD_error && this->_XD_condition4/
{ @bytes_written = sum(args[1]->io_size); }
while loop in D
pid$target::zprop_free_list:entry { ll_user = arg0; printf("-- START --");
}
pid$target::zprop_free_list:entry /ll_user != NULL/ {
ll_kern = copyin(ll_user, sizeof(zprop_list_t));
printf("%d", ll_kern->pl_prop);
ll_user = ll_kern->pl_next;
}
pid$target::zprop_free_list:entry /ll_user != NULL/ {
ll_kern = copyin(ll_user, sizeof(zprop_list_t));
printf("%d", ll_kern->pl_prop);
ll_user = ll_kern->pl_next;
}
/* More copies go here */
pid$target::zprop_free_list:entry { printf("-- END --"); }
while loop in XD
pid$target::zprop_free_list:entry
{
ll_user = arg0;
printf("-- START --");
while10 (ll_user != NULL) {
ll_kern = copyin(ll_user, sizeof(zprop_list_t));
printf("%d", ll_kern->pl_prop);
ll_user = ll_kern->pl_next;
}
printf("-- END --");
}
while loop converted to D
pid$target::zprop_free_list:entry { ll_user = arg0; printf("-- START --"); }
pid$target::zprop_free_list:entry {this->_XD_condition2 = (ll_user != 0x0);}
pid$target::zprop_free_list:entry /this->_XD_condition2/ {
ll_kern = copyin(ll_user, sizeof(zprop_list_t));
printf(" %d", ll_kern->pl_prop);
ll_user = ll_kern->pl_next;
}
pid$target::zprop_free_list:entry {this->_XD_condition2 = (ll_user != 0x0);}
pid$target::zprop_free_list:entry /this->_XD_condition2/ {
ll_kern = copyin(ll_user, sizeof(zprop_list_t));
printf(" %d", ll_kern->pl_prop);
ll_user = ll_kern->pl_next;
}
/* ... repeat 8 more times ... */
pid$target::zprop_free_list:entry { printf("-- END --"); }
printing nvlists in XD
● manually-managed stack for nested nvlists
● print "function" implemented as C preprocessor macro
○ implement "inline" XD functions?
● also straightforward to implement nvlist_lookup_
{uint64,string,etc}
● definitely need to increase dtrace_dof_maxsize!
● pseudocode follows
○ assume everything starts with "this->"
elem = list->nvl_first;
while20 (elem != NULL) {
printf("%s", stringof(elem->name));
if (elem->type == DATA_TYPE_UINT64) {
printf(": %un", *(uint64_t *)elem->valuep);
elem = elem->next;
} else if (elem->type == DATA_TYPE_STRING) {
printf(": %sn", stringof((char *)elem->valuep));
elem = elem->next;
} else if (elem->type == DATA_TYPE_NVLIST) {
stack[curframe].elem = elem;
stack[curframe].list = list;
curframe++;
list = (nvlist_t *)elem->nvi_valuep;
elem = list->nvl_first;
}
if (elem == NULL && curframe > 0) {
curframe--;
elem = stack[curframe].elem;
list = stack[curframe].list;
}
}
if (elem != NULL)
entry->* variables in D
spa_sync:entry
{
self->spa = args[0];
self->txg = args[1];
self->start = timestamp;
}
spa_sync:return
/self->start/
{
printf("%s(%s, %u) took %ums",
probefunc, self->spa->spa_name, self->txg,
(timestamp - self->start)/1000/1000);
self->spa = 0;
self->txg = 0;
self->start = 0;
}
Hope this function
isn't recursive!
entry->* variables in XD
spa_sync:return
{
printf("%s(%s, %u) took %ums",
probefunc,
entry->args[0]->spa_name, entry->args[1],
entry->elapsed_ms);
}
entry->* converted to D
::spa_sync:entry
{
self->_XD_entry_args1[stackdepth] = args[1];
self->_XD_entry_args0[stackdepth] = args[0];
self->_XD_entry_timestamp[stackdepth] = timestamp;
}
::spa_sync:return
{ this->_XD_condition1 = 0x1 && self->_XD_entry_timestamp[stackdepth]; }
::spa_sync:return
/this->_XD_condition1/
{
printf("%s(%s, %u) took %ums",
probefunc, self->_XD_entry_args0[stackdepth]->spa_name,
self->_XD_entry_arg1[stackdepth],
(timestamp - self->_XD_entry_timestamp[stackdepth]) / 1000 / 1000);
}
::spa_sync:return
{
self->_XD_entry_arg1[stackdepth] = 0x0;
callers[] in D
resolvepath:entry,traverse:entry
{
self->trace = 1;
}
zrl_add:entry
/ self->trace != 0 /
{
@[stack()] = count();
}
resolvepath:return,traverse:return
{
self->trace = 0;
}
What if resolvepath and traverse are both
on the stack?
callers[] in XD
Now a one-liner:
zrl_add:entry / callers["resolvepath,traverse"] / {@[stack()] = count()}
● The value of callers[] is a count, not just a toggle
○ Useful for examining recursive functions.
● callers["resolvepath,traverse"]
○ Either function must be in the stack
● callers["resolvepath"] && callers["traverse"]
○ Both functions must be in the stack
● Possible performance considerations
○ Each element means two more probes, be cognizant of enabled probe
effect.
callers[] converted to D
::resolvepath:entry,
::traverse:entry
{ ++self->_XD_callers1; }
::zrl_add:entry
{ this->_XD_condition1 = 0x1 && self->_XD_callers1; }
::zrl_add:entry
/this->_XD_condition1/
{ @_[stack()] = count(); }
::resolvepath:return,
::traverse:return
/self->_XD_callers1/
{ --self->_XD_callers1; }

More Related Content

What's hot

Fundamental of Shell Programming
Fundamental of Shell ProgrammingFundamental of Shell Programming
Fundamental of Shell ProgrammingRahul Hada
 
BPF: Next Generation of Programmable Datapath
BPF: Next Generation of Programmable DatapathBPF: Next Generation of Programmable Datapath
BPF: Next Generation of Programmable DatapathThomas Graf
 
Centralized Logging with syslog
Centralized Logging with syslogCentralized Logging with syslog
Centralized Logging with syslogamiable_indian
 
NPF scripting with Lua by Lourival Vieira Neto
NPF scripting with Lua by Lourival Vieira NetoNPF scripting with Lua by Lourival Vieira Neto
NPF scripting with Lua by Lourival Vieira Netoeurobsdcon
 
VLANs in the Linux Kernel
VLANs in the Linux KernelVLANs in the Linux Kernel
VLANs in the Linux KernelKernel TLV
 
Introduction to eBPF and XDP
Introduction to eBPF and XDPIntroduction to eBPF and XDP
Introduction to eBPF and XDPlcplcp1
 
Tips and Tricks for Increased Development Efficiency
Tips and Tricks for Increased Development EfficiencyTips and Tricks for Increased Development Efficiency
Tips and Tricks for Increased Development EfficiencyOlivier Bourgeois
 
Gsummit apis-2013
Gsummit apis-2013Gsummit apis-2013
Gsummit apis-2013Gluster.org
 
Linux kernel TLS и HTTPS / Александр Крижановский (Tempesta Technologies)
Linux kernel TLS и HTTPS / Александр Крижановский (Tempesta Technologies)Linux kernel TLS и HTTPS / Александр Крижановский (Tempesta Technologies)
Linux kernel TLS и HTTPS / Александр Крижановский (Tempesta Technologies)Ontico
 
Configuring Syslog by Octavio
Configuring Syslog by OctavioConfiguring Syslog by Octavio
Configuring Syslog by OctavioRowell Dionicio
 
The TCP/IP Stack in the Linux Kernel
The TCP/IP Stack in the Linux KernelThe TCP/IP Stack in the Linux Kernel
The TCP/IP Stack in the Linux KernelDivye Kapoor
 
Fun with Network Interfaces
Fun with Network InterfacesFun with Network Interfaces
Fun with Network InterfacesKernel TLV
 
Networking and Go: An Epic Journey
Networking and Go: An Epic JourneyNetworking and Go: An Epic Journey
Networking and Go: An Epic JourneySneha Inguva
 
E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)
E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)
E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)Valeriy Kravchuk
 
Keeping your files safe in the post-Snowden era with SXFS
Keeping your files safe in the post-Snowden era with SXFSKeeping your files safe in the post-Snowden era with SXFS
Keeping your files safe in the post-Snowden era with SXFSRobert Wojciechowski
 
Linux Linux Traffic Control
Linux Linux Traffic ControlLinux Linux Traffic Control
Linux Linux Traffic ControlSUSE Labs Taipei
 
Anatomy of neutron from the eagle eyes of troubelshoorters
Anatomy of neutron from the eagle eyes of troubelshoortersAnatomy of neutron from the eagle eyes of troubelshoorters
Anatomy of neutron from the eagle eyes of troubelshoortersSadique Puthen
 
2015 FOSDEM - OVS Stateful Services
2015 FOSDEM - OVS Stateful Services2015 FOSDEM - OVS Stateful Services
2015 FOSDEM - OVS Stateful ServicesThomas Graf
 

What's hot (20)

Fundamental of Shell Programming
Fundamental of Shell ProgrammingFundamental of Shell Programming
Fundamental of Shell Programming
 
BPF: Next Generation of Programmable Datapath
BPF: Next Generation of Programmable DatapathBPF: Next Generation of Programmable Datapath
BPF: Next Generation of Programmable Datapath
 
Centralized Logging with syslog
Centralized Logging with syslogCentralized Logging with syslog
Centralized Logging with syslog
 
NPF scripting with Lua by Lourival Vieira Neto
NPF scripting with Lua by Lourival Vieira NetoNPF scripting with Lua by Lourival Vieira Neto
NPF scripting with Lua by Lourival Vieira Neto
 
VLANs in the Linux Kernel
VLANs in the Linux KernelVLANs in the Linux Kernel
VLANs in the Linux Kernel
 
Introduction to eBPF and XDP
Introduction to eBPF and XDPIntroduction to eBPF and XDP
Introduction to eBPF and XDP
 
Tips and Tricks for Increased Development Efficiency
Tips and Tricks for Increased Development EfficiencyTips and Tricks for Increased Development Efficiency
Tips and Tricks for Increased Development Efficiency
 
Gsummit apis-2013
Gsummit apis-2013Gsummit apis-2013
Gsummit apis-2013
 
Linux kernel TLS и HTTPS / Александр Крижановский (Tempesta Technologies)
Linux kernel TLS и HTTPS / Александр Крижановский (Tempesta Technologies)Linux kernel TLS и HTTPS / Александр Крижановский (Tempesta Technologies)
Linux kernel TLS и HTTPS / Александр Крижановский (Tempesta Technologies)
 
Configuring Syslog by Octavio
Configuring Syslog by OctavioConfiguring Syslog by Octavio
Configuring Syslog by Octavio
 
The TCP/IP Stack in the Linux Kernel
The TCP/IP Stack in the Linux KernelThe TCP/IP Stack in the Linux Kernel
The TCP/IP Stack in the Linux Kernel
 
Fun with FUSE
Fun with FUSEFun with FUSE
Fun with FUSE
 
Fun with Network Interfaces
Fun with Network InterfacesFun with Network Interfaces
Fun with Network Interfaces
 
Networking and Go: An Epic Journey
Networking and Go: An Epic JourneyNetworking and Go: An Epic Journey
Networking and Go: An Epic Journey
 
E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)
E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)
E bpf and dynamic tracing for mariadb db as (mariadb day during fosdem 2020)
 
Keeping your files safe in the post-Snowden era with SXFS
Keeping your files safe in the post-Snowden era with SXFSKeeping your files safe in the post-Snowden era with SXFS
Keeping your files safe in the post-Snowden era with SXFS
 
Docker and Fluentd
Docker and FluentdDocker and Fluentd
Docker and Fluentd
 
Linux Linux Traffic Control
Linux Linux Traffic ControlLinux Linux Traffic Control
Linux Linux Traffic Control
 
Anatomy of neutron from the eagle eyes of troubelshoorters
Anatomy of neutron from the eagle eyes of troubelshoortersAnatomy of neutron from the eagle eyes of troubelshoorters
Anatomy of neutron from the eagle eyes of troubelshoorters
 
2015 FOSDEM - OVS Stateful Services
2015 FOSDEM - OVS Stateful Services2015 FOSDEM - OVS Stateful Services
2015 FOSDEM - OVS Stateful Services
 

Similar to Experimental dtrace

Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...
Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...
Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...Data Con LA
 
Pydiomatic
PydiomaticPydiomatic
Pydiomaticrik0
 
Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaPatrick Allaert
 
Learning groovy -EU workshop
Learning groovy  -EU workshopLearning groovy  -EU workshop
Learning groovy -EU workshopadam1davis
 
Lex (lexical analyzer)
Lex (lexical analyzer)Lex (lexical analyzer)
Lex (lexical analyzer)Sami Said
 
Devel::hdb debugger talk
Devel::hdb debugger talkDevel::hdb debugger talk
Devel::hdb debugger talkabrummett
 
Functions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrupFunctions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrupSyedHaroonShah4
 
PHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityPHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityGeorgePeterBanyard
 
C++11: Feel the New Language
C++11: Feel the New LanguageC++11: Feel the New Language
C++11: Feel the New Languagemspline
 
TI1220 Lecture 14: Domain-Specific Languages
TI1220 Lecture 14: Domain-Specific LanguagesTI1220 Lecture 14: Domain-Specific Languages
TI1220 Lecture 14: Domain-Specific LanguagesEelco Visser
 
Addressing Scenario
Addressing ScenarioAddressing Scenario
Addressing ScenarioTara Hardin
 

Similar to Experimental dtrace (20)

What's New in C++ 11?
What's New in C++ 11?What's New in C++ 11?
What's New in C++ 11?
 
Oops lecture 1
Oops lecture 1Oops lecture 1
Oops lecture 1
 
Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...
Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...
Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...
 
Pydiomatic
PydiomaticPydiomatic
Pydiomatic
 
Python idiomatico
Python idiomaticoPython idiomatico
Python idiomatico
 
Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 Verona
 
Learning groovy -EU workshop
Learning groovy  -EU workshopLearning groovy  -EU workshop
Learning groovy -EU workshop
 
Lex (lexical analyzer)
Lex (lexical analyzer)Lex (lexical analyzer)
Lex (lexical analyzer)
 
Dart workshop
Dart workshopDart workshop
Dart workshop
 
Csdfsadf
CsdfsadfCsdfsadf
Csdfsadf
 
C
CC
C
 
C
CC
C
 
Devel::hdb debugger talk
Devel::hdb debugger talkDevel::hdb debugger talk
Devel::hdb debugger talk
 
Functions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrupFunctions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrup
 
Dafunctor
DafunctorDafunctor
Dafunctor
 
PHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityPHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing Insanity
 
C++11: Feel the New Language
C++11: Feel the New LanguageC++11: Feel the New Language
C++11: Feel the New Language
 
TI1220 Lecture 14: Domain-Specific Languages
TI1220 Lecture 14: Domain-Specific LanguagesTI1220 Lecture 14: Domain-Specific Languages
TI1220 Lecture 14: Domain-Specific Languages
 
Addressing Scenario
Addressing ScenarioAddressing Scenario
Addressing Scenario
 
Clojure basics
Clojure basicsClojure basics
Clojure basics
 

More from Matthew Ahrens

OpenZFS novel algorithms: snapshots, space allocation, RAID-Z - Matt Ahrens
OpenZFS novel algorithms: snapshots, space allocation, RAID-Z - Matt AhrensOpenZFS novel algorithms: snapshots, space allocation, RAID-Z - Matt Ahrens
OpenZFS novel algorithms: snapshots, space allocation, RAID-Z - Matt AhrensMatthew Ahrens
 
OpenZFS Channel programs
OpenZFS Channel programsOpenZFS Channel programs
OpenZFS Channel programsMatthew Ahrens
 
OpenZFS code repository
OpenZFS code repositoryOpenZFS code repository
OpenZFS code repositoryMatthew Ahrens
 
OpenZFS Developer Summit Introduction
OpenZFS Developer Summit IntroductionOpenZFS Developer Summit Introduction
OpenZFS Developer Summit IntroductionMatthew Ahrens
 

More from Matthew Ahrens (8)

OpenZFS novel algorithms: snapshots, space allocation, RAID-Z - Matt Ahrens
OpenZFS novel algorithms: snapshots, space allocation, RAID-Z - Matt AhrensOpenZFS novel algorithms: snapshots, space allocation, RAID-Z - Matt Ahrens
OpenZFS novel algorithms: snapshots, space allocation, RAID-Z - Matt Ahrens
 
OpenZFS dotScale
OpenZFS dotScaleOpenZFS dotScale
OpenZFS dotScale
 
OpenZFS - BSDcan 2014
OpenZFS - BSDcan 2014OpenZFS - BSDcan 2014
OpenZFS - BSDcan 2014
 
OpenZFS - AsiaBSDcon
OpenZFS - AsiaBSDconOpenZFS - AsiaBSDcon
OpenZFS - AsiaBSDcon
 
OpenZFS Channel programs
OpenZFS Channel programsOpenZFS Channel programs
OpenZFS Channel programs
 
OpenZFS code repository
OpenZFS code repositoryOpenZFS code repository
OpenZFS code repository
 
OpenZFS Developer Summit Introduction
OpenZFS Developer Summit IntroductionOpenZFS Developer Summit Introduction
OpenZFS Developer Summit Introduction
 
OpenZFS at EuroBSDcon
OpenZFS at EuroBSDconOpenZFS at EuroBSDcon
OpenZFS at EuroBSDcon
 

Recently uploaded

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Intelisync
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 

Recently uploaded (20)

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 

Experimental dtrace

  • 1. DTrace Experimental DTrace (XD) language extensions Matt.Ahrens@delphix.com
  • 2. D is a (safe) power tool ● Some D concepts (predicates) are unfamiliar to procedural programmers ● Some simple ideas require many steps ● These steps are (for the most part) fundamentally necessary but tedious ● Solution: syntactic sugar
  • 3. if/else in XD vdev_queue_pending_remove:entry { if (stringof(args[1]->io_spa->spa_name) == $$1) { if (args[1]->io_type == ZIO_TYPE_READ) { @bytes_read = sum(args[1]->io_size); } else if (args[1]->io_type == ZIO_TYPE_WRITE && args[1]->io_bookmark.zb_level != 2) { @bytes_written = sum(args[1]->io_size); } } }
  • 4. if/else converted to D dtrace:::ERROR{ self->_XD_error = 0x1; } ::vdev_queue_pending_remove:entry{ self->_XD_error = 0x0; } ::vdev_queue_pending_remove:entry /!self->_XD_error/ { this->_XD_condition1 = 0x1 && stringof(args[1]->io_spa->spa_name) == $$1; } ::vdev_queue_pending_remove:entry /!self->_XD_error/ { this->_XD_condition2 = this->_XD_condition1 && args[1]->io_type == ZIO_TYPE_READ; } ::vdev_queue_pending_remove:entry /(!self->_XD_error) && this->_XD_condition2/ { @bytes_read = sum(args[1]->io_size); } ::vdev_queue_pending_remove:entry /!self->_XD_error/ { this->_XD_condition3 = this->_XD_condition1 && !this->_XD_condition2; } ::vdev_queue_pending_remove:entry /!self->_XD_error/ { this->_XD_condition4 = this->_XD_condition3 && args[1]->io_type == ZIO_TYPE_WRITE && args[1]->io_bookmark.zb_level != 2; } ::vdev_queue_pending_remove:entry /!self->_XD_error && this->_XD_condition4/ { @bytes_written = sum(args[1]->io_size); }
  • 5. while loop in XD pid$target::zprop_free_list:entry { ll_user = arg0; printf("-- START --"); while10 (ll_user != NULL) { ll_kern = copyin(ll_user, sizeof(zprop_list_t)); printf("%d", ll_kern->pl_prop); ll_user = ll_kern->pl_next; } printf("-- END --"); }
  • 6. entry-> variables in XD spa_sync:return { printf("%s(%s, %u) took %ums", probefunc, entry->args[0]->spa_name, entry->args[1], entry->elapsed_ms); }
  • 7. callers[] in XD zrl_add:entry / callers["resolvepath,traverse"] / {@[stack()] = count()} ● The value of callers[] is a count, not just a toggle ○ Useful for examining recursive functions. ● callers["resolvepath,traverse"] ○ Either function must be in the stack ● callers["resolvepath"] && callers["traverse"] ○ Both functions must be in the stack ● Possible performance considerations ○ Each element means two more probes, be cognizant of enabled probe effect.
  • 8. How does it do that? Changes are primarily in libdtrace ● Create parse tree ○ new nodes for "if", "while" ● Transform parse tree to remove XD ○ create new clauses ○ swap out entry->*, callers[] ● Finish compiling the (now strictly D) parse tree ● No kernel changes
  • 9. How can I use it? ● https://github.com/ahrens/illumos/tree/dpp ○ fork of illumos ○ 100% libdtrace, should be easy to port ● To see the D generated from your XD ○ dtrace -xd -x tree=8 … ● Examples: https://github.com/ahrens/dtrace ● Bugs? ○ email matt@delphix.com your XD script
  • 10. Field use ● In production at Delphix since April 2014 ● if/else: increases legibility of larger scripts ○ ~50% of scripts use “if” ● while: rarely used ● entry->arg[], entry->elapsed ○ Extremely helpful for one-liners ○ ~75% of scripts use “entry->” ● callers[] ○ Helpful for one-liners ○ ~33% of scripts use “callers[]”
  • 11. Field use (one-liner example) ● Histograms of time in foo(), broken down by request size, when called from bar() dtrace -xd -n ‘ foo:return /callers[“bar”]/ { @[entry->args[2]->b_size] = quantize(entry->elapsed_us); }’
  • 12. Integration status ● Pollutes namespace with “_XD_*” variables ○ Should be possible to fix ● if/else: agreement that this is a good idea ○ “if” and “else” are already reserved keywords ● while: not that useful, let’s not bother ● entry->arg[], entry->elapsed ○ Concern about FBT concepts leaking into language ○ Concern about “entry” polluting namespace ○ But sooooo useful! Needs more discussion.
  • 13. Integration status ● callers[] ○ Concern about dependence on FBT ○ Concern about hiding perf cost ○ Idea: implement by examining stack instead? ■ Pro: linear performance impact ■ Downside: reliance on backtrace accuracy ■ Downside: requires kernel changes ● “Is there an address in the range [x,y] in the backtrace”
  • 14. What next? 1. Integrate if/else to illumos 2. Figure out entry-> concerns 3. Integrate entry-> to illumos 4. Figure out callers[] FBT vs stack() 5. Integrate callers[]
  • 15. What next? ● "for" and "do" loops; "break", "continue"(?) ● #pragma D option defaultscope=local ○ bare variables will have probe-local scope ■ i.e. implicit "this->" ○ use "global->" for global variables ○ use "thread->" for thread-local variables ● "inline" functions to replace preprocessor? ● better error diagnosability? ○ dtrace: error on enabled probe ID 463 (ID 33804: fbt:zfs:put_nvlist:entry): invalid address (0x0) in action #1 at DIF offset 36
  • 16. What next? (continued) ● Predicate Scoping ○ Applying a predicate to multiple clauses specified in a block: /callers["spa_sync"]/ { zio_read:entry { stack(); } metaslab_sync:return { trace(entry->elapsed_ms); } }
  • 17. DTrace XD: DTrace language extensions Matt.Ahrens@delphix.com
  • 18. if/else in D vdev_queue_pending_remove:entry /stringof(args[1]->io_spa->spa_name) == $$1 && args[1]->io_type == ZIO_TYPE_READ/ { @bytes_read = sum(args[1]->io_size); } vdev_queue_pending_remove:entry /stringof(args[1]->io_spa->spa_name) == $$1 && args[1]->io_type == ZIO_TYPE_WRITE && args[1]->io_bookmark.zb_level != -2/ { @bytes_written = sum(args[1]->io_size);
  • 19. if/else in XD vdev_queue_pending_remove:entry { if (stringof(args[1]->io_spa->spa_name) == $$1) { if (args[1]->io_type == ZIO_TYPE_READ) { @bytes_read = sum(args[1]->io_size); } else if (args[1]->io_type == ZIO_TYPE_WRITE && args[1]->io_bookmark.zb_level != 2) { @bytes_written = sum(args[1]->io_size); } } }
  • 20. if/else converted to D dtrace:::ERROR{ self->_XD_error = 0x1; } ::vdev_queue_pending_remove:entry{ self->_XD_error = 0x0; } ::vdev_queue_pending_remove:entry /!self->_XD_error/ { this->_XD_condition1 = 0x1 && stringof(args[1]->io_spa->spa_name) == $$1; } ::vdev_queue_pending_remove:entry /!self->_XD_error/ { this->_XD_condition2 = this->_XD_condition1 && args[1]->io_type == ZIO_TYPE_READ; } ::vdev_queue_pending_remove:entry /(!self->_XD_error) && this->_XD_condition2/ { @bytes_read = sum(args[1]->io_size); } ::vdev_queue_pending_remove:entry /!self->_XD_error/ { this->_XD_condition3 = this->_XD_condition1 && !this->_XD_condition2; } ::vdev_queue_pending_remove:entry /!self->_XD_error/ { this->_XD_condition4 = this->_XD_condition3 && args[1]->io_type == ZIO_TYPE_WRITE && args[1]->io_bookmark.zb_level != 2; } ::vdev_queue_pending_remove:entry /!self->_XD_error && this->_XD_condition4/ { @bytes_written = sum(args[1]->io_size); }
  • 21. while loop in D pid$target::zprop_free_list:entry { ll_user = arg0; printf("-- START --"); } pid$target::zprop_free_list:entry /ll_user != NULL/ { ll_kern = copyin(ll_user, sizeof(zprop_list_t)); printf("%d", ll_kern->pl_prop); ll_user = ll_kern->pl_next; } pid$target::zprop_free_list:entry /ll_user != NULL/ { ll_kern = copyin(ll_user, sizeof(zprop_list_t)); printf("%d", ll_kern->pl_prop); ll_user = ll_kern->pl_next; } /* More copies go here */ pid$target::zprop_free_list:entry { printf("-- END --"); }
  • 22. while loop in XD pid$target::zprop_free_list:entry { ll_user = arg0; printf("-- START --"); while10 (ll_user != NULL) { ll_kern = copyin(ll_user, sizeof(zprop_list_t)); printf("%d", ll_kern->pl_prop); ll_user = ll_kern->pl_next; } printf("-- END --"); }
  • 23. while loop converted to D pid$target::zprop_free_list:entry { ll_user = arg0; printf("-- START --"); } pid$target::zprop_free_list:entry {this->_XD_condition2 = (ll_user != 0x0);} pid$target::zprop_free_list:entry /this->_XD_condition2/ { ll_kern = copyin(ll_user, sizeof(zprop_list_t)); printf(" %d", ll_kern->pl_prop); ll_user = ll_kern->pl_next; } pid$target::zprop_free_list:entry {this->_XD_condition2 = (ll_user != 0x0);} pid$target::zprop_free_list:entry /this->_XD_condition2/ { ll_kern = copyin(ll_user, sizeof(zprop_list_t)); printf(" %d", ll_kern->pl_prop); ll_user = ll_kern->pl_next; } /* ... repeat 8 more times ... */ pid$target::zprop_free_list:entry { printf("-- END --"); }
  • 24. printing nvlists in XD ● manually-managed stack for nested nvlists ● print "function" implemented as C preprocessor macro ○ implement "inline" XD functions? ● also straightforward to implement nvlist_lookup_ {uint64,string,etc} ● definitely need to increase dtrace_dof_maxsize! ● pseudocode follows ○ assume everything starts with "this->"
  • 25. elem = list->nvl_first; while20 (elem != NULL) { printf("%s", stringof(elem->name)); if (elem->type == DATA_TYPE_UINT64) { printf(": %un", *(uint64_t *)elem->valuep); elem = elem->next; } else if (elem->type == DATA_TYPE_STRING) { printf(": %sn", stringof((char *)elem->valuep)); elem = elem->next; } else if (elem->type == DATA_TYPE_NVLIST) { stack[curframe].elem = elem; stack[curframe].list = list; curframe++; list = (nvlist_t *)elem->nvi_valuep; elem = list->nvl_first; } if (elem == NULL && curframe > 0) { curframe--; elem = stack[curframe].elem; list = stack[curframe].list; } } if (elem != NULL)
  • 26. entry->* variables in D spa_sync:entry { self->spa = args[0]; self->txg = args[1]; self->start = timestamp; } spa_sync:return /self->start/ { printf("%s(%s, %u) took %ums", probefunc, self->spa->spa_name, self->txg, (timestamp - self->start)/1000/1000); self->spa = 0; self->txg = 0; self->start = 0; } Hope this function isn't recursive!
  • 27. entry->* variables in XD spa_sync:return { printf("%s(%s, %u) took %ums", probefunc, entry->args[0]->spa_name, entry->args[1], entry->elapsed_ms); }
  • 28. entry->* converted to D ::spa_sync:entry { self->_XD_entry_args1[stackdepth] = args[1]; self->_XD_entry_args0[stackdepth] = args[0]; self->_XD_entry_timestamp[stackdepth] = timestamp; } ::spa_sync:return { this->_XD_condition1 = 0x1 && self->_XD_entry_timestamp[stackdepth]; } ::spa_sync:return /this->_XD_condition1/ { printf("%s(%s, %u) took %ums", probefunc, self->_XD_entry_args0[stackdepth]->spa_name, self->_XD_entry_arg1[stackdepth], (timestamp - self->_XD_entry_timestamp[stackdepth]) / 1000 / 1000); } ::spa_sync:return { self->_XD_entry_arg1[stackdepth] = 0x0;
  • 29. callers[] in D resolvepath:entry,traverse:entry { self->trace = 1; } zrl_add:entry / self->trace != 0 / { @[stack()] = count(); } resolvepath:return,traverse:return { self->trace = 0; } What if resolvepath and traverse are both on the stack?
  • 30. callers[] in XD Now a one-liner: zrl_add:entry / callers["resolvepath,traverse"] / {@[stack()] = count()} ● The value of callers[] is a count, not just a toggle ○ Useful for examining recursive functions. ● callers["resolvepath,traverse"] ○ Either function must be in the stack ● callers["resolvepath"] && callers["traverse"] ○ Both functions must be in the stack ● Possible performance considerations ○ Each element means two more probes, be cognizant of enabled probe effect.
  • 31. callers[] converted to D ::resolvepath:entry, ::traverse:entry { ++self->_XD_callers1; } ::zrl_add:entry { this->_XD_condition1 = 0x1 && self->_XD_callers1; } ::zrl_add:entry /this->_XD_condition1/ { @_[stack()] = count(); } ::resolvepath:return, ::traverse:return /self->_XD_callers1/ { --self->_XD_callers1; }