DTrace for Linux
Generate complete D scripts that compile and run cleanly on Linux systems with DTrace.
Output Requirements
- Return a full runnable D program every time.
- Include a shebang for script output:
#!/usr/sbin/dtrace -s.
- Prefer predicates for filtering and aggregations for volume control.
- Include
dtrace:::ERROR when the script could fault or when robust diagnostics are useful.
- Avoid placeholders, pseudo-code, and partial solutions.
Safety Rules
- Prefer stable providers:
syscall, proc, sched, profile, io, pid, usdt, and dtrace.
- Avoid dangerous actions unless explicitly necessary.
- Do not recommend
system() unless there is no viable alternative.
- Treat
copyout*(), raise(), and system() as destructive.
Forbidden Language Constructs
Never use these constructs in D scripts:
if
else
for
while
switch
case
default
do
goto
continue
Use only:
- Predicates:
/expr/
- Ternary operator:
cond ? a : b
Clause Structure
Use this canonical form:
probe-descriptions
/ optional predicate /
{
statements;
}
- Probe description format:
provider:module:function:name
- Omitted fields are wildcard matches.
- Multiple probes may be comma-separated in one clause.
- Avoid numeric probe IDs.
Script Skeleton
#!/usr/sbin/dtrace -s
dtrace:::BEGIN
{
printf("Tracing started...\n");
}
/* tracing clauses */
dtrace:::END
{
/* printa() for aggregations when needed */
}
dtrace:::ERROR
{
printf("DTrace error at %s:%s:%s:%s\n", probeprov, probemod, probefunc, probename);
}
Preferred Idioms
- Filter early with predicates:
/execname == "date"/
/pid == $target/
- Use per-thread state for timing:
self->ts = timestamp;
/self->ts/ { @lat = quantize(timestamp - self->ts); self->ts = 0; }
- Use aggregations instead of unbounded prints:
@counts[key] = count();
@sum[key] = sum(value);
@dist = quantize(value);
Variables
- Global:
x, arr[key] (shared, not MP-safe by default)
- Thread-local:
self->x (preferred for correlation)
- Clause-local:
this->x (temporary per-probe firing)
- Built-in probe/process vars:
pid, ppid, tid, execname
probeprov, probemod, probefunc, probename
timestamp, vtimestamp, errno
arg0 ... arg9, args[]
- Macro vars:
$target, $pid, $uid, $1, $2, ...
Common Functions
- Recording:
trace(), printf(), printa(), exit()
- Aggregation:
count(), sum(), avg(), min(), max(), stddev(), quantize(), lquantize(), llquantize()
- Memory/string:
copyin(), copyinstr(), strlen(), substr(), strstr()
- Stacks:
stack(), ustack()
- Speculation:
speculation(), speculate(), commit(), discard()
Provider Quick Reference
dtrace: lifecycle (BEGIN, END, ERROR)
syscall: syscall entry/return
proc: process lifecycle (exec, exit, ...)
sched: scheduler activity (on-cpu, off-cpu, ...)
profile: timed sampling (profile-N, tick-N)
io: I/O start/complete
pid: user-function boundaries in a target process
usdt: user static tracepoints
Patterns
Count syscalls by executable:
#!/usr/sbin/dtrace -s
syscall:::entry
/execname != ""/
{
@syscalls[execname] = count();
}
dtrace:::END
{
printa(@syscalls);
}
Time syscall latency:
#!/usr/sbin/dtrace -s
syscall::write:entry
{
self->ts = timestamp;
}
syscall::write:return
/self->ts/
{
@lat[execname] = quantize(timestamp - self->ts);
self->ts = 0;
}
Target one process:
#!/usr/sbin/dtrace -s
syscall:::entry
/pid == $target/
{
@calls[probefunc] = count();
}
Response Style
- Be precise and production-minded.
- Prefer compact scripts with clear predicates.
- Add brief comments only where they prevent ambiguity.
- After presenting a script, include one short run command when useful:
Verification Workflow
Always verify generated scripts before presenting them as final.
- Write the script to a file, for example
script.d.
- Run compile-only verification:
sudo dtrace -e -s script.d
- If compile-only is unavailable on the target distro, use a short bounded run:
sudo timeout 3 dtrace -s script.d
- Treat verification failures as blocking:
- Fix the script and re-run verification until it passes.
- Report verification status with the output:
Verified: yes plus the command used.
1---2name: dtrace-linux3description: Generate and validate runnable DTrace scripts for Linux debugging and performance investigations in an agentic coding framework capable of using SKILLs. Use for incident response, root-cause analysis, latency triage, syscall/process/scheduler/I-O tracing, and stack/profile sampling. Always return complete scripts with safe defaults, stable providers, strict D language constraints, and a verification step before final output.4---56# DTrace for Linux78Generate complete D scripts that compile and run cleanly on Linux systems with DTrace.910## Output Requirements1112- Return a full runnable D program every time.13- Include a shebang for script output: `#!/usr/sbin/dtrace -s`.14- Prefer predicates for filtering and aggregations for volume control.15- Include `dtrace:::ERROR` when the script could fault or when robust diagnostics are useful.16- Avoid placeholders, pseudo-code, and partial solutions.1718## Safety Rules1920- Prefer stable providers: `syscall`, `proc`, `sched`, `profile`, `io`, `pid`, `usdt`, and `dtrace`.21- Avoid dangerous actions unless explicitly necessary.22- Do not recommend `system()` unless there is no viable alternative.23- Treat `copyout*()`, `raise()`, and `system()` as destructive.2425## Forbidden Language Constructs2627Never use these constructs in D scripts:2829- `if`30- `else`31- `for`32- `while`33- `switch`34- `case`35- `default`36- `do`37- `goto`38- `continue`3940Use only:4142- Predicates: `/expr/`43- Ternary operator: `cond ? a : b`4445## Clause Structure4647Use this canonical form:4849```d50probe-descriptions51/ optional predicate /52{53 statements;54}55```5657- Probe description format: `provider:module:function:name`58- Omitted fields are wildcard matches.59- Multiple probes may be comma-separated in one clause.60- Avoid numeric probe IDs.6162## Script Skeleton6364```d65#!/usr/sbin/dtrace -s6667dtrace:::BEGIN68{69 printf("Tracing started...\n");70}7172/* tracing clauses */7374dtrace:::END75{76 /* printa() for aggregations when needed */77}7879dtrace:::ERROR80{81 printf("DTrace error at %s:%s:%s:%s\n", probeprov, probemod, probefunc, probename);82}83```8485## Preferred Idioms8687- Filter early with predicates:88 - `/execname == "date"/`89 - `/pid == $target/`90- Use per-thread state for timing:91 - `self->ts = timestamp;`92 - `/self->ts/ { @lat = quantize(timestamp - self->ts); self->ts = 0; }`93- Use aggregations instead of unbounded prints:94 - `@counts[key] = count();`95 - `@sum[key] = sum(value);`96 - `@dist = quantize(value);`9798## Variables99100- Global: `x`, `arr[key]` (shared, not MP-safe by default)101- Thread-local: `self->x` (preferred for correlation)102- Clause-local: `this->x` (temporary per-probe firing)103- Built-in probe/process vars:104 - `pid`, `ppid`, `tid`, `execname`105 - `probeprov`, `probemod`, `probefunc`, `probename`106 - `timestamp`, `vtimestamp`, `errno`107 - `arg0` ... `arg9`, `args[]`108- Macro vars:109 - `$target`, `$pid`, `$uid`, `$1`, `$2`, ...110111## Common Functions112113- Recording: `trace()`, `printf()`, `printa()`, `exit()`114- Aggregation: `count()`, `sum()`, `avg()`, `min()`, `max()`, `stddev()`, `quantize()`, `lquantize()`, `llquantize()`115- Memory/string: `copyin()`, `copyinstr()`, `strlen()`, `substr()`, `strstr()`116- Stacks: `stack()`, `ustack()`117- Speculation: `speculation()`, `speculate()`, `commit()`, `discard()`118119## Provider Quick Reference120121- `dtrace`: lifecycle (`BEGIN`, `END`, `ERROR`)122- `syscall`: syscall entry/return123- `proc`: process lifecycle (`exec`, `exit`, ...)124- `sched`: scheduler activity (`on-cpu`, `off-cpu`, ...)125- `profile`: timed sampling (`profile-N`, `tick-N`)126- `io`: I/O start/complete127- `pid`: user-function boundaries in a target process128- `usdt`: user static tracepoints129130## Patterns131132Count syscalls by executable:133134```d135#!/usr/sbin/dtrace -s136137syscall:::entry138/execname != ""/139{140 @syscalls[execname] = count();141}142143dtrace:::END144{145 printa(@syscalls);146}147```148149Time syscall latency:150151```d152#!/usr/sbin/dtrace -s153154syscall::write:entry155{156 self->ts = timestamp;157}158159syscall::write:return160/self->ts/161{162 @lat[execname] = quantize(timestamp - self->ts);163 self->ts = 0;164}165```166167Target one process:168169```d170#!/usr/sbin/dtrace -s171172syscall:::entry173/pid == $target/174{175 @calls[probefunc] = count();176}177```178179## Response Style180181- Be precise and production-minded.182- Prefer compact scripts with clear predicates.183- Add brief comments only where they prevent ambiguity.184- After presenting a script, include one short run command when useful:185 - `sudo dtrace -s script.d`186187## Verification Workflow188189Always verify generated scripts before presenting them as final.1901911. Write the script to a file, for example `script.d`.1922. Run compile-only verification:193 - `sudo dtrace -e -s script.d`1943. If compile-only is unavailable on the target distro, use a short bounded run:195 - `sudo timeout 3 dtrace -s script.d`1964. Treat verification failures as blocking:197 - Fix the script and re-run verification until it passes.1985. Report verification status with the output:199 - `Verified: yes` plus the command used.