2

How does Java generate a thread's stack trace?

Example:

Consider functionA calls functionB calls functionC calls functionD. If at any point in functionD getStackTraceElementArray is used it would give the array of functionCalls:

functionC->functionB->functionA

How does Java fill the StackTraceElement array at runtime? Assuming it fills the calling function when it reaches inside the called function, how does the JVM get the reference of the calling method inside the called method?

3
  • @Robby Cornelissen: This is not a duplicate question, it is quite different, I am not asking how to get a Stack trace, but how does Java create one internally, where is the hook in the program where it gets instantiated and populated. Commented May 18, 2016 at 4:04
  • 1
    Please reword your question then. if there is a handler to the method stack area, which can be used to mannually create or fill a StackTraceElement Array in a Java program makes it sound like you're looking for a way to get the current stack trace. Commented May 18, 2016 at 4:15
  • 1
    Reopened. Now see here. Commented May 18, 2016 at 5:26

1 Answer 1

4

In the simplest case the stack trace is obtained from... the stack! enter image description here
Each thread has a frame pointer (FP) register that points to the base address of a current stack frame. When a Java method is called, it first creates a new stack frame, i.e. it pushes a bunch of information onto the stack:

  • return address (where the method was called from);
  • current FP (which points to the caller frame);
  • method ID of the method being called;
  • pointers to the constant pool cache etc.

Then it updates FP to point to the newly created frame.

This way, you see, the frame pointers make a linked list: if I read a value pointed by FP, I get the base address of the previous frame.

Now notice that for each frame a method ID is always at the same offset from FP. So the stack walking is as easy as a while loop (written in pseudo-code):

address fp = currentThread.getFP();
while (fp != null) {
    methodID m = (methodID) read_stack_at(fp + METHOD_OFFSET);
    print_method(m);
    fp = (address) read_stack_at(fp);
}

That's how it works inside JVM for interpreted methods. Compiled methods are a bit more complicated. They do not usually save a method reference on the stack. Instead there is a structure that maps addresses of compiled code to the metadata that contains compiled method info. But the idea of stack walking is still the same.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.