Tools
DTrace | SystemTap | |
Tool |
dtrace(1M) |
stap(1) |
List probes |
# dtrace -l # dtrace -l -P io |
# stap -l 'ioblock.*' # stap -L 'ioblock.*' |
One-liner |
# dtrace -n ' syscall::read:entry { trace(arg1); } ' |
# stap -e ' probe syscall.read { println(fd); } ' |
Script |
# dtrace -s script.d(optionally add -C for preprocessor, -q for quiet mode) |
# stap script.stp |
Custom probe |
# dtrace -P io -n start |
- |
Integer arguments |
# dtrace -n ' syscall::read:entry / cpu == $1 / ' 0 |
# stap -e ' probe syscall.read { if(cpu() != $1) next; println(fd); } ' 0 |
String arguments |
# dtrace -n ' syscall::read:entry / execname == $1 / ' '"cat"' |
# stap -e ' probe syscall.read { if(execname() == @1) println(fd); } ' cat |
Guru/destructive mode ( ! ) |
# dtrace -w ... |
# stap -g ... |
Redirect to file |
# dtrace -o FILE ...(appends) |
# stap -o FILE ...(rewrites) |
Tracing process |
# dtrace -n ' syscall::read:entry / pid == $target / { ... }' -c 'cat /etc/motd'(or -p PID ) |
# stap -e ' probe syscall.read { if(pid() == target()) ... } ' -c 'cat /etc/motd'(or -x PID ) |
Probe names
DTrace | SystemTap | |
Begin/end |
dtrace:::BEGIN , dtrace:::END |
begin , end |
foo() entry |
fbt::foo:entry |
kernel.function("foo") module("mod").function("foo") |
foo() return |
fbt::foo:return |
kernel.function("foo").return |
Wildcards |
fbt::foo*:entry |
kernel.function("foo*") |
Static probe mark |
sdt:::mark |
kernel.trace("mark") |
System call |
syscall::read:entry |
syscall.read |
Timer once per second |
tick-1s |
timer.s(1) |
Profiling |
profile-997hz |
timer.profile() , perf.* |
read() from libc |
pid$target:libc:read:entry Traces process with pid == $target |
process("/lib64/libc.so.6").function("read") Traces any process that loads libc |
In DTrace parts of probe name may be omitted: fbt::foo:entry
-> foo:entry
Units for timer probes: ns
, us
, ms
, s
, hz
, jiffies
(SystemTap), m
, h
, d
(all three - DTrace)
Printing
DTrace | SystemTap | |
Value |
trace(v) |
print(v) |
Value + newline | - |
println(v) |
Delimited values | - |
printd(",",v1,v2) printdln(",",v1,v2) |
Memory dump |
tracemem( ptr, 16) |
printf("%16M", ptr) |
Formatted |
printf("%s", str) |
|
Backtrace |
ustack(n) ustack() |
print_ubacktrace() print_ustack( ubacktrace()) |
Symbol |
usym(addr) ufunc(addr) uaddr(addr) |
print(usymname(addr)) print(usymdata(addr)) |
If u prefix is specified, userspace symbols and backtraces are printed, if not –- kernel symbols are used
String operations
Operation | DTrace | SystemTap_ |
Get from kernel |
stringof(expr) (string) expr |
kernel_string*() |
Convert scalar |
sprint() and sprintf() |
|
Copy from user |
copyinstr() |
user_string*() |
Compare |
== , != , > , >= , < , <= |
|
Concat |
strjoin(str1, str2) |
str1 . str2 |
Get length |
strlen(str) |
|
Check for substring |
strstr( haystack, needle) |
isinstr( haystack, needle) |
Context variables
Description | DTrace | SystemTap |
Thread |
curthread |
task_current() |
Thread ID |
tid |
tid() |
PID |
pid |
pid() |
Parent PID |
ppid |
ppid() |
User/group ID |
uid /gid |
uid() /gid() euid() /egid() |
Executable name |
execname curpsinfo-> ps_fname |
execname() |
Command line |
curpsinfo-> ps_psargs |
cmdline_*() |
CPU number |
cpu |
cpu() |
Probe names |
probeprov probemod probefunc probename |
pp() pn() ppfunc() probefunc() probemod() |
Time
Time source | DTrace | SystemTap |
System timer |
`lbolt `lbolt64 |
jiffies() |
CPU cycles | - |
get_cycles() |
Monotonic time |
timestamp |
local_clock_unit()
cpu_clock_unit(cpu) |
CPU time of thread |
vtimestamp |
- |
Real time |
walltimestamp |
gettimeofday_unit() |
Where unit is one of s
, ms
, us
, ns
Aggregations
Time source | DTrace | SystemTap |
Add value |
@aggr[keys] = func(value); |
aggr[keys] <<< value; |
Printing |
printa(@aggr); printa("format string", @aggr); |
foreach([keys] in aggr) { print(keys, @func(aggr[keys])); } |
Clear |
clear(@aggr); or trunc(@aggr); |
delete aggr; |
Normalization by 1000 |
normalize(@aggr, 1000); denormalize(@aggr); |
@func(aggr) / 1000 in printing |
Select 20 values |
trunc(@aggr, 20); |
foreach([keys] in aggr limit 20) { print(keys, @func(aggr[keys])); } |
Histograms (linear in [10;100] with step 5 and logarithmical) |
@lin = lquantize(value, 10, 100, 5); @log = quantize(value); ... printa(@lin); printa(@log); |
aggr <<< value; ... print(@hist_linear(aggr, 10, 100, 5)); print(@hist_log(aggr)); |
Where func is one of count
, sum
, min
, max
, avg
, stddev
Process management
SystemTap
Getting task_struct pointers:
-
task_current()
– current task_struct -
task_parent(t)
– parent of taskt
-
pid2task(pid)
– task_struct by pid
Working with task_struct pointers:
-
task_pid(t)
&task_tid(t)
-
task_state(t)
– 0 (running), 1-2 (blocked) -
task_execname(t)
DTrace
kthread_t* curthread
fields:
- t_tid, t_pri, t_start, t_pctcpu
psinfo_t* curpsinfo
fields:
-
pr_pid
,pr_uid
, pr_gid, pr_fname, pr_psargs, pr_start
lwpsinfo_t* curlwpsinfo
fields:
-
pr_lwpid
,pr_state
/pr_sname
psinfo_t*
and lwpsinfo_t*
are passed to some proc:::
probes
Scheduler
DTrace | SystemTap | |
1 |
sched:::dequeue |
kernel.function("dequeue_task") |
2 |
sched:::on-cpu |
scheduler.cpu_on |
3 |
sched:::off-cpu |
scheduler.cpu_off |
4 |
sched:::enqueue |
kernel.function("enqueue_task") |
5 | - |
scheduler.migrate |
6 |
sched:::sleep |
- |
7 |
sched:::wakeup |
scheduler.wakeup |
Virtual memory
Probes
SystemTap
-
vm.brk
– allocating heap -
vm.mmap
– allocating anon memory -
vm.munmap
– freeing anon memory
DTrace
-
as_map:entry
– allocating proc mem -
as_unmap:entry
– freeing proc mem
Page faults
Type | DTrace | SystemTap |
Any |
vminfo::as_fault |
vm.pagefault vm.pagefault.return perf.sw.page_faults |
Minor |
perf.sw.page_faults_min |
|
Major |
vminfo:::maj_fault |
perf.sw.page_faults_maj |
CoW |
vminfo:::cow_fault |
|
Protection |
vminfo:::prot_fault |
Block Input-Output
Block request structure fields:
Field |
bufinfo_t struct buf |
struct bio |
Flags |
b_flags |
bi_flags |
R/W |
b_flags |
bi_rw |
Size |
b_bcount |
bi_size |
Block |
b_blkno b_lblkno |
bi_sector |
Callback |
b_iodone |
bi_end_io |
Device |
b_edev b_dip |
bi_bdev |
* flags B_WRITE
, B_READ
Network stack
Non-native languages
Function call | DTrace | SystemTap |
Java* |
method-entry
|
hotspot.method_entry
|
Perl |
perl$target:::sub-entry
|
process("...").mark("sub__entry")
|
Python |
python$target:::function-entry
|
python.function.entry
|
PHP |
function-entry
|
process("...").mark("function__entry")
|
*requires -XX:+DTraceMethodProbes