Showing posts with label btrace. Show all posts
Showing posts with label btrace. Show all posts

Thursday, October 20, 2016

Btrace: trace all Exceptions

see http://www.javamonamour.org/2013/06/getting-started-with-btrace.html for an introduction to btrace. This product is WONDERFUL.
In this new case, I want to trace where a given exception (java.io.FileNotFoundException) is thrown. I use the OnThrow.java example on the btrace site, slightly customized:

import static com.sun.btrace.BTraceUtils.*;

/**
 * This example demonstrates printing stack trace
 * of an exception and thread local variables. This
 * trace script prints exception stack trace whenever
 * java.lang.Throwable's constructor returns. This way
 * you can trace all exceptions that may be caught and
 * "eaten" silently by the traced program. Note that the
 * assumption is that the exceptions are thrown soon after
 * creation [like in "throw new FooException();"] rather
 * that be stored and thrown later.
 */
@BTrace public class OnThrow {    
    // store current exception in a thread local
    // variable (@TLS annotation). Note that we can't
    // store it in a global variable!
    @TLS static Throwable currentException;

    // introduce probe into every constructor of java.lang.Throwable
    // class and store "this" in the thread local variable.
    @OnMethod(
        clazz="java.io.FileNotFoundException",
        method="<init>"
    )
    public static void onthrow(@Self Throwable self) {
        currentException = self;
    }

    @OnMethod(
        clazz="java.io.FileNotFoundException",
        method="<init>"
    )
    public static void onthrow1(@Self Throwable self, String s) {
        currentException = self;
    }

    @OnMethod(
        clazz="java.io.FileNotFoundException",
        method="<init>"
    )
    public static void onthrow1(@Self Throwable self, String s, Throwable cause) {
        currentException = self;
    }

    @OnMethod(
        clazz="java.io.FileNotFoundException",
        method="<init>"
    )
    public static void onthrow2(@Self Throwable self, Throwable cause) {
        currentException = self;
    }

    // when any constructor of java.lang.Throwable returns
    // print the currentException's stack trace.
    @OnMethod(
        clazz="java.io.FileNotFoundException",
        method="<init>",
        location=@Location(Kind.RETURN)
    )
    public static void onthrowreturn() {
        if (currentException != null) {
            Threads.jstack(currentException);
            println("=====================");
            currentException = null;
        }
    }
}



Since we have Java6, I had to download an old version of btrace (1.2.1 or so). I could not run the btracec and btrace scripts for shell compatibility issues, so I run directly the java commands:
/opt/pippo/java/jdk160_115/bin/java -cp /tmp/btrace-bin/build/btrace-client.jar:/opt//pippo/java/jdk160_115/lib/tools.jar com.sun.btrace.compiler.Compiler $*
/tmp/btrace-bin/bin/OnThrow


/opt/pippo/java/jdk160_115/bin/java -Dcom.sun.btrace.probeDescPath=. -Dcom.sun.btrace.dumpClasses=false -Dcom.sun.btrace.debug=false -Dcom.sun.btrace.unsafe=false -cp /tmp/btrace-bin/build/btrace-client.jar:/opt/pippo/java/jdk160_115/lib/tools.jar:/usr/share/lib/java/dtrace.jar com.sun.btrace.client.Main 23262 /tmp/btrace-bin/bin/OnThrow.class 

with 23262 being the PID of my WebLogic application server.

Btrace is the best thing after ice cream in life.



Saturday, June 8, 2013

Getting started with Btrace

User Guide: https://kenai.com/projects/btrace/pages/UserGuide

Download binaries here:
https://github.com/jbachorik/btrace/releases/tag/v1.3.3

Java class under test:
BTraceTest.java:
public class BTraceTest {
    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 1000000; i++) {
             Thread.sleep(1000);
             doSomething();
        }
    }

    public static void doSomething() {
        System.out.println("something");
    }

}





Btrace profiling class: Btrace1.java:
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
import java.lang.reflect.Field;

@BTrace public class Btrace1 {
  @OnMethod(
    clazz="BTraceTest",
    method="doSomething"
  )
  public static void onDoSomething() {
      println("got it");
  }
}



compile it:
./btracec -classpath . ./Btrace1.java
run it:
./btrace -classpath . 24160 ./Btrace1.class
where 24160 is the PID of the BTraceTest java application
It works! It's great!
A slightly more advanced example using Class parameters:

public class BTraceTest {
    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 1000000; i++) {
             Thread.sleep(1000);
    BTraceParam param = new BTraceParam();
    param.name = "hello " + i;
             doSomething(param);
        }
    }

    public static void doSomething(BTraceParam param) {
        System.out.println("something" + param.name);
    }

}



public class BTraceParam {
 String name;
}



import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.AnyType;
import java.lang.reflect.Field;

@BTrace public class Btrace1 {
  @OnMethod(
    clazz="BTraceTest",
    method="doSomething"
  )

  public static void anyDoSomething(@ProbeClassName String pcn, @ProbeMethodName String pmn, AnyType[] args) {
 println(pcn);
 println(pmn);
 printArray(args);
  }
}



this way you can print the value also of any parameter !

To print the stacktrace (very useful!) use jstack();