ART: Add GetLineNumberTable
Add support for extracting a line number table. Add output to
stack trace test.
Bug: 31684812
Test: m test-art-host-run-test-911-get-stack-trace
Change-Id: Ief6ff566c35431333b51b551d9d511c7a47a05e7
diff --git a/test/911-get-stack-trace/stack_trace.cc b/test/911-get-stack-trace/stack_trace.cc
index b5b5678..9092f2f 100644
--- a/test/911-get-stack-trace/stack_trace.cc
+++ b/test/911-get-stack-trace/stack_trace.cc
@@ -32,6 +32,23 @@
namespace art {
namespace Test911GetStackTrace {
+static jint FindLineNumber(jint line_number_count,
+ jvmtiLineNumberEntry* line_number_table,
+ jlocation location) {
+ if (line_number_table == nullptr) {
+ return -2;
+ }
+
+ jint line_number = -1;
+ for (jint i = 0; i != line_number_count; ++i) {
+ if (line_number_table[i].start_location > location) {
+ return line_number;
+ }
+ line_number = line_number_table[i].line_number;
+ }
+ return line_number;
+}
+
extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getStackTrace(
JNIEnv* env, jclass klass ATTRIBUTE_UNUSED, jthread thread, jint start, jint max) {
std::unique_ptr<jvmtiFrameInfo[]> frames(new jvmtiFrameInfo[max]);
@@ -61,6 +78,26 @@
}
}
+ jint line_number_count;
+ jvmtiLineNumberEntry* line_number_table;
+ {
+ jvmtiError line_result = jvmti_env->GetLineNumberTable(frames[method_index].method,
+ &line_number_count,
+ &line_number_table);
+ if (line_result != JVMTI_ERROR_NONE) {
+ // Accept absent info and native method errors.
+ if (line_result != JVMTI_ERROR_ABSENT_INFORMATION &&
+ line_result != JVMTI_ERROR_NATIVE_METHOD) {
+ char* err;
+ jvmti_env->GetErrorName(line_result, &err);
+ printf("Failure running GetLineNumberTable: %s\n", err);
+ return nullptr;
+ }
+ line_number_table = nullptr;
+ line_number_count = 0;
+ }
+ }
+
auto inner_callback = [&](jint component_index) -> jstring {
switch (component_index) {
case 0:
@@ -69,11 +106,17 @@
return (sig == nullptr) ? nullptr : env->NewStringUTF(sig);
case 2:
return env->NewStringUTF(StringPrintf("%" PRId64, frames[method_index].location).c_str());
+ case 3: {
+ jint line_number = FindLineNumber(line_number_count,
+ line_number_table,
+ frames[method_index].location);
+ return env->NewStringUTF(StringPrintf("%d", line_number).c_str());
+ }
}
LOG(FATAL) << "Unreachable";
UNREACHABLE();
};
- jobjectArray inner_array = CreateObjectArray(env, 3, "java/lang/String", inner_callback);
+ jobjectArray inner_array = CreateObjectArray(env, 4, "java/lang/String", inner_callback);
if (name != nullptr) {
jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(name));
@@ -84,6 +127,9 @@
if (gen != nullptr) {
jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(gen));
}
+ if (line_number_table != nullptr) {
+ jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(line_number_table));
+ }
return inner_array;
};