Who is calling my method?

This post is for those who don’t able to do debug in runtime. There are many ways to do debug,

1. From your IDE, and you are developing a desktop app.

2. From you IDE, through remote debugging if you have a server app.

3. When both are false you can still do a Thread.dumpStack(); on your code and see who all are calling the piece of code.

There is another type, I observed, on which above 3 debugging techniques won’t help at all.

Suppose you are working on a closed box, on which you won’t be able to do a IDE type of debug, remote desktop, and you want to debug a piece of coed which is inside a jar file/ or available as a library. In this particular scenario none of your debugging technique would help.

All I want to know who the hell is calling a.B() and when.

Let’s take help from JDK 5.0. JDK 5.0 onwards we have a API to get all thread stacks. The api doc says,

/**
* Returns a map of stack traces for all live threads.
* The map keys are threads and each map value is an array of
* <tt>StackTraceElement</tt> that represents the stack dump
* of the corresponding <tt>Thread</tt>.
* The returned stack traces are in the format specified for
* the {@link #getStackTrace getStackTrace} method.
*
* <p>The threads may be executing while this method is called.
* The stack trace of each thread only represents a snapshot and
* each stack trace may be obtained at different time.  A zero-length
* array will be returned in the map value if the virtual machine has
* no stack trace information about a thread.
*
* <p>If there is a security manager, then the security manager’s
* <tt>checkPermission</tt> method is called with a
* <tt>RuntimePermission(“getStackTrace”)</tt> permission as well as
* <tt>RuntimePermission(“modifyThreadGroup”)</tt> permission
* to see if it is ok to get the stack trace of all threads.
*
* @return a <tt>Map</tt> from <tt>Thread</tt> to an array of
* <tt>StackTraceElement</tt> that represents the stack trace of
* the corresponding thread.
*
* @throws SecurityException
*        if a security manager exists and its
*        <tt>checkPermission</tt> method doesn’t allow
*        getting the stack trace of thread.
* @see #getStackTrace
* @see SecurityManager#checkPermission
* @see RuntimePermission
* @see Throwable#getStackTrace
*
* @since 1.5
*/

I used this api to know when a call comes to my method, you can see the below exmple,


private static final class StackTraceThread extends Thread{

private String className;
private String methodName;

public StackTraceThread(String methodName, String className) {
this.className = className;
this.methodName = methodName;
}

@Override
public void run() {
while(true){
Runtime.getRuntime().gc();
new Thread(new Runnable() {

@Override
public void run() {
Set threadSet = Thread.getAllStackTraces().keySet();
Thread[] threadArray = (Thread[]) threadSet.toArray(new Thread[threadSet.size()]);
for (int i = 0; i < threadArray.length; i++) {
StackTraceElement[] elements = threadArray[i].getStackTrace();

if(elements.length >0 ){
if(methodName.equals(elements[0].getMethodName()) && className.equals(elements[0].getClassName())){
System.out.println("Method: " + elements[1].getMethodName());
System.out.println("Class: " + elements[1].getClassName());
System.out.println("Line: " + elements[1].getLineNumber());
}
}

}

}
}).start();

}
}
}

The above code snippet is not highly optimized (you can see the while loop), you can optimize and use it for you own app.

Here is how I called this class on load of a sample app,


public class Test {

int [] numberingsArray;

private void printString(){
while(true);
}

public static void main(String[] args) {

StackTraceThread stackTraceThread = new StackTraceThread("printString","com.test.test.Test");
stackTraceThread.start();

Test test = new Test();
test.printString();

}

}

Whenever printString() method gets called, the caller method and class gets printed on the console.

You can follow me on Twitter, add me to your circle on Google+ or like our Facebook page to keep yourself updated on all the latest from Photography, Technology, Microsoft, Google, Apple and the web.

Advertisements

3 Comments Add yours

  1. Asha says:

    Hey Abhinab,

    Good good… giving IDE and Tooling guys tough time huh :-D!

  2. Preetam says:

    Good articxle abhinaba.I have one dought.Before following code excutes
    Set threadSet = Thread.getAllStackTraces().keySet();
    if my method is poped out from stack .How do i get to know that method has called.

    1. Abhinaba Basu says:

      you can see my comment above, “The above code snippet is not highly optimized (you can see the while loop), you can optimize and use it for you own app.” This article is only to show how we can use the stack trace.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s