BTrace User's Guide

BTrace is a safe, dynamic tracing tool for Java. BTrace works by dynamically (bytecode) instrumenting classes of a running Java program. BTrace inserts tracing actions into the classes of a running Java program and hotswaps the traced program classes.

BTrace Terminology

Probe Point
"location" or "event" at which a set of tracing statements are executed. Probe point is "place" or "event" of interest where we want to execute some tracing statements.
Trace Actions or Actions
Trace statements that are executed whenever a probe "fires".
Action Methods
BTrace trace statements that are executed when a probe fires are defined inside a static method a class. Such methods are called "action" methods.

BTrace Program Structure

A BTrace program is a plain Java class that has one or more public static void methods that are annotated with BTrace annotations. The annotations are used to specify traced program "locations" (also known as "probe points"). The tracing actions are specified inside the static method bodies. These static methods are referred as "action" methods.

BTrace Restrictions

To guarantee that the tracing actions are "read-only" (i.e., the trace actions don't change the state of the program traced) and bounded (i.e., trace actions terminate in bounded time), a BTrace program is allowed to do only a restricted set of actions. In particular, a BTrace class

A simple BTrace program


// import all BTrace annotations
import com.sun.btrace.annotations.*;
// import statics from BTraceUtils class
import static com.sun.btrace.BTraceUtils.*;

// @BTrace annotation tells that this is a BTrace program
@BTrace
public class HelloWorld {
 
    // @OnMethod annotation tells where to probe.
    // In this example, we are interested in entry 
    // into the Thread.start() method. 
    @OnMethod(
        clazz="java.lang.Thread",
        method="start"
    )
    public static void func() {
        // println is defined in BTraceUtils
        // you can only call the static methods of BTraceUtils
        println("about to start a thread!");
    }
}

The above BTrace program can be run against a running Java process. This program will print "about to start a thread!" at the BTrace client whenever the target program is about to start a thread by Thread.start() method. There are other interesting probe points possible. For example, we can insert trace action at return from a method, exception return from a method, a field get or set within method(s), object/array creation, line number(s), throwing an exception. Please refer to the @OnMethod and other annotations for details.

Steps to run BTrace

  1. Find the process id of the target Java process that you want to trace. You can use jps tool to find the pid.
  2. Write a BTrace program - you may want to start modifying one of the samples.
  3. Run btrace tool by the following command line:
       btrace <pid> <btrace-script>
    

BTrace Command Line

BTrace is run using the command line tool btrace as shown below:

    btrace [-I <include-path>] [-p <port>] [-cp <classpath>] <pid> <btrace-script> [<args>]

where

optional

Pre-compiling BTrace scripts

It is possible to precompile BTrace program using btracec script. btracec is a javac-like program that takes a BTrace program and produces a .class file.


    btracec [-I <include-path>] [-cp <classpath>] [-d <directory>] <one-or-more-BTrace-.java-files>

where This script uses BTrace compiler class - rather than regular javac and therefore will validate your BTrace program at compile time [so that you can avoid BTrace verify error at runtime].

Starting an application with BTrace agent

So far, we saw how to trace a running Java program. It is also possible to start an application with BTrace agent in it. If you want to start tracing the application from the very "beginning", you may want to start the app with BTrace agent and specify a trace script along with it [i.e., BTrace agent is attach-on-demand loadable as well as pre-loadable agent] You can use the following command to start an app and specify BTrace script file. But, you need to precompile your BTrace script for this kind of usage.


    java -javaagent:btrace-agent.jar=script=<pre-compiled-btrace-script> <MainClass> <AppArguments>

When starting the application this way, the trace output goes to a file named <btrace-class-file-name>.btrace in the current directory. Also, you can avoid starting server for other remote BTrace clients by specifying noServer=true as an argument to the BTrace agent.

There is a convenient script called btracer to do the above:

    btracer <pre-compiled-btrace.class> <application-main-class> <application-args>

BTrace Annotations

Method Annotations

Argument Annotations

Field Annotations

Class Annotations

DTrace Integration

Solaris DTrace is a dynamic, safe tracing system for Solaris programs - both kernel and user land programs. Because of the obvious parallels b/w DTrace and BTrace, it is natural to expect integration b/w BTrace and DTrace. There are two ways in which BTrace is integrated with DTrace.

BTrace Samples

BTrace samples

One lines about samples: