docs/OnelinerGuide.md
DTrace-style oneliners for quick Java debugging without writing full scripts.
BTrace oneliners provide a fast, concise way to debug running Java applications without creating separate script files. Inspired by DTrace oneliners, they compile to standard BTrace Java code internally, ensuring zero performance overhead.
When to use oneliners:
When to use full BTrace scripts:
# Basic syntax
btrace -n 'class::method @location { action }' <PID>
# Real examples
btrace -n 'javax.swing.*::setText @entry { print method, args }' 1234
btrace -n 'java.sql.Statement::execute* @return if duration>100ms { print method, duration }' 1234
btrace -n 'java.util.HashMap::get @entry { count }' 1234
class-pattern::method-pattern @location [filter] { action [, action]* }
Components:
class-pattern - Class name with wildcards or regexmethod-pattern - Method name with wildcards or regex@location - Where to probe: @entry, @return, or @errorfilter (optional) - Conditional filteraction - What to do: print, count, time, or stackWildcards (simple pattern matching):
# Match all classes in package
'javax.swing.*::*'
# Match all subpackages
'javax.swing.**::*'
# Match method names
'MyClass::get*'
'MyClass::*Service'
Regex (advanced pattern matching):
# Regex in class name
'/com\.myapp\..*/::execute'
# Regex in method name
'java.sql.Statement::/execute.*/'
# Both
'/com\.myapp\..*/::/handle.*/
Special method names:
<init> - Constructors<clinit> - Static initializers* - All methods| Location | Description | Available Identifiers |
|---|---|---|
@entry | Method entry | method, args, self, class |
@return | Method return | method, args, duration, return, self, class |
@error | Exception thrown | method, args, duration, self, class |
Examples:
# Trace method entry
btrace -n 'MyClass::myMethod @entry { print method }' <PID>
# Trace method return
btrace -n 'MyClass::myMethod @return { print method, return }' <PID>
# Trace exceptions
btrace -n 'MyClass::myMethod @error { print method, stack }' <PID>
Duration filter (only for @return and @error):
# Slow methods > 100ms
'MyClass::* @return if duration>100ms { print method, duration }'
# Very slow methods >= 500ms
'MyClass::* @return if duration>=500ms { print method }'
# Fast methods < 10ms
'MyClass::* @return if duration<10ms { print method }'
Argument filter (all locations):
# String argument equals
'MyClass::process @entry if args[0]=="CREATE" { print }'
# Numeric argument comparison
'MyClass::setValue @entry if args[0]>100 { print args }'
# Check null
'MyClass::process @entry if args[1]==null { print method }'
Supported comparators:
> - Greater than< - Less than== - Equals>= - Greater than or equal<= - Less than or equal!= - Not equals# Print bare message
{ print }
# Print specific identifiers
{ print method }
{ print method, args }
{ print method, duration, return }
# Available identifiers:
# method - Method name
# args - Method arguments
# duration - Execution time (nanoseconds, @return/@error only)
# return - Return value (@return only)
# self - This instance
# class - Class name
Examples:
# Method with arguments
btrace -n 'MyClass::process @entry { print method, args }' <PID>
# Slow method with timing
btrace -n 'MyClass::query @return if duration>100ms { print method, duration }' <PID>
# Return value
btrace -n 'MyClass::calculate @return { print method, return }' <PID>
# Simple count
{ count }
Prints total count when BTrace exits (Ctrl+C).
Examples:
# Count HashMap.get calls
btrace -n 'java.util.HashMap::get @entry { count }' <PID>
# Count exceptions
btrace -n 'java.lang.Exception::<init> @entry { count }' <PID>
# Display execution time in milliseconds
{ time }
Only valid for @return and @error locations.
Examples:
# Time database queries
btrace -n 'java.sql.Statement::execute* @return { time }' <PID>
# Time method execution
btrace -n 'MyClass::expensiveOperation @return { time }' <PID>
# Full stack trace
{ stack }
# Limited depth
{ stack(10) }
Examples:
# Stack on OutOfMemoryError
btrace -n 'java.lang.OutOfMemoryError::<init> @return { stack(10) }' <PID>
# Call path to method
btrace -n 'MyClass::suspiciousMethod @entry { stack(5) }' <PID>
Separate actions with commas:
# Print and count
{ print method, count }
# Print, count, and stack
{ print method, count, stack(3) }
Find slow database queries:
btrace -n 'java.sql.Statement::execute* @return if duration>100ms { print method, duration }' <PID>
Find slow HTTP requests:
btrace -n 'javax.servlet.http.HttpServlet::service @return if duration>500ms { print method, duration }' <PID>
Time all methods in a class:
btrace -n 'com.myapp.MyService::* @return { time }' <PID>
Trace all Swing UI updates:
btrace -n 'javax.swing.*::* @entry { print method, args }' <PID>
Monitor file operations:
btrace -n 'java.io.FileInputStream::<init> @entry { print args }' <PID>
Count cache hits:
btrace -n 'com.myapp.Cache::get @entry { count }' <PID>
Track all exceptions:
btrace -n 'java.lang.Exception::<init> @entry { print self, stack(5) }' <PID>
Track specific exception:
btrace -n 'java.sql.SQLException::<init> @entry { print self, stack(10) }' <PID>
Monitor OutOfMemoryError:
btrace -n 'java.lang.OutOfMemoryError::<init> @return { stack(15) }' <PID>
Track user objects:
btrace -n 'com.myapp.User::<init> @entry { print args, count }' <PID>
Monitor configuration changes:
btrace -n 'com.myapp.Config::set* @entry { print method, args }' <PID>
Track specific argument values:
btrace -n 'com.myapp.OrderService::process @entry if args[0]=="PRIORITY" { print method, args, stack }' <PID>
Find who's calling deprecated methods:
btrace -n 'com.myapp.LegacyService::oldMethod @entry { print stack(3) }' <PID>
Identify slow REST endpoints:
btrace -n 'org.springframework.web.bind.annotation.RequestMapping::* @return if duration>1000ms { print method, duration }' <PID>
Monitor database connection usage:
btrace -n 'javax.sql.DataSource::getConnection @entry { count }' <PID>
Match multiple packages:
btrace -n '/com\.myapp\.(service|controller)\..*/::* @entry { print method }' <PID>
Match getter/setter methods:
btrace -n 'com.myapp.User::/[gs]et.*/ @entry { print method, args }' <PID>
Slow methods with stack traces:
btrace -n 'com.myapp.*::* @return if duration>200ms { print method, duration, stack(5) }' <PID>
Count specific argument values:
btrace -n 'com.myapp.OrderService::processOrder @entry if args[0]=="EXPRESS" { count }' <PID>
Filter by return value (manual workaround - not directly supported yet):
# Use duration filter as proxy for successful operations
btrace -n 'com.myapp.Service::operation @return if duration>0ms { print return }' <PID>
Current limitations of Alternative 1 (Minimal) oneliners:
Future enhancements (Alternative 2):
probe1 | probe2 | probe3@hist=histogram; ... { @hist << duration by method }@call:TargetClass::targetMethodby method, classUse specific patterns instead of wildcards when possible:
# Good - specific
'com.myapp.UserService::getUserById'
# Less optimal - very broad
'**::*'
Add filters to reduce overhead:
# Only trace slow calls
@return if duration>100ms
Limit stack depth:
# Good
{ stack(5) }
# Expensive
{ stack } # full stack
Start broad, then narrow:
# Step 1: Find which class
btrace -n 'com.myapp.*::* @entry { print class, method }' <PID>
# Step 2: Focus on specific class
btrace -n 'com.myapp.UserService::* @entry { print method, args }' <PID>
# Step 3: Drill into specific method
btrace -n 'com.myapp.UserService::getUserById @entry { print args, stack }' <PID>
Use count to quantify issues:
# How often is this called?
btrace -n 'com.myapp.Database::query @entry { count }' <PID>
Combine with external tools:
# Save output to file
btrace -n 'com.myapp.*::* @entry { print method }' <PID> > trace.log
# Pipe to grep
btrace -n 'com.myapp.*::* @entry { print method }' <PID> | grep "User"
Oneliners run in untrusted mode by default - Use -u flag for trusted operations
Be careful with production - Test oneliners in staging first
Use read-only actions - print, count, stack are safe; avoid modifying state
Problem: Oneliner runs but produces no output
Solutions:
Verify the method is being called:
# Add entry point
btrace -n 'MyClass::* @entry { print method }' <PID>
Check pattern matching:
# Try exact match first
btrace -n 'com.example.MyClass::myMethod @entry { print }' <PID>
Verify location:
# Try all locations
btrace -n 'MyClass::myMethod @entry { print }' <PID>
btrace -n 'MyClass::myMethod @return { print }' <PID>
Problem: "Oneliner syntax error at position X"
Solutions:
Check quotes - use single quotes for shell:
# Correct
btrace -n 'MyClass::method @entry { print }' <PID>
# Wrong - shell interprets $
btrace -n "MyClass::method @entry { print }" <PID>
Check spacing around symbols:
# Correct
if duration>100ms
# Wrong
ifduration>100ms
Verify filter location:
# Error - duration only for @return/@error
'@entry if duration>100ms'
# Correct
'@return if duration>100ms'
Problem: "Oneliner compilation failed"
Solutions:
Enable debug mode to see generated code:
btrace -v -n 'MyClass::method @entry { print }' <PID>
Check for unsupported features:
@return or @error@returnTry equivalent full BTrace script to isolate issue
When you outgrow oneliners, convert them to full BTrace scripts:
Oneliner:
btrace -n 'MyClass::process @return if duration>100ms { print method, duration }' <PID>
Equivalent BTrace script (MyTrace.java):
import org.openjdk.btrace.core.annotations.*;
import static org.openjdk.btrace.core.BTraceUtils.*;
@BTrace
public class MyTrace {
@OnMethod(clazz="MyClass", method="process", location=@Location(Kind.RETURN))
public static void onProcess(@ProbeMethodName String method, @Duration long duration) {
if (duration > 100_000_000L) { // 100ms in nanoseconds
println(method + " " + duration);
}
}
}
Found an issue or have a suggestion for oneliners? Please:
oneliner label