I have the following code to get the line numbers at the current stack frame locations when an exception is thrown that works but I figured it out by experimenting rather than through a specification. I only left the relevant code.
int max_frame_count = 50;
jvmtiFrameInfo frames[max_frame_count];
jint count;
(*jvmti_env)->GetStackTrace(jvmti_env, thread, 0, max_frame_count, frames, &count);
for (int loop = 0; loop < count; loop++) {
jvmtiFrameInfo frame = frames[loop];
jmethodID currentMethod = frame.method;
(*jvmti_env)->GetMethodName(jvmti_env, currentMethod, &name_ptr, &signature_ptr, &generic_ptr);
(*jvmti_env)->GetLineNumberTable(jvmti_env, currentMethod, &entry_count_ptr, &table_ptr);
jint lineNumber = -1;
int lineNumberCount;
jlocation prevLocationId = -1;
if (frame.location != -1) {
for (int lineNumberLoop = entry_count_ptr - 1; lineNumberLoop >= 0; lineNumberLoop--) {
jvmtiLineNumberEntry lineNumberEntry = table_ptr[lineNumberLoop];
if (frame.location >= lineNumberEntry.start_location) {
lineNumber = lineNumberEntry.line_number;
break;
}
}
}
}
GetLineNumberTable
returns the line_number
and the corresponding start_location
for all lines of currentMethod
. Now here is where my confusion starts: Why can't I match frame.location
to a start_location
returned by GetLineNumberTable
? Is there any specification how these match? While my code seems to work, I can't belief that this is a solution that always works. It searches backwards for the first frame.location
that is greater or equal to lineNumberEntry.start_location
.
Thanks for any hints and pointers!