diff options
Diffstat (limited to 'runtime/mirror/throwable.cc')
-rw-r--r-- | runtime/mirror/throwable.cc | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/runtime/mirror/throwable.cc b/runtime/mirror/throwable.cc index 782b9c0..1c21edb 100644 --- a/runtime/mirror/throwable.cc +++ b/runtime/mirror/throwable.cc @@ -71,9 +71,18 @@ bool Throwable::IsCheckedException() { int32_t Throwable::GetStackDepth() { Object* stack_state = GetStackState(); - if (stack_state == nullptr || !stack_state->IsObjectArray()) return -1; - ObjectArray<Object>* method_trace = down_cast<ObjectArray<Object>*>(stack_state); - return method_trace->GetLength() - 1; + if (stack_state == nullptr) { + return -1; + } + if (!stack_state->IsIntArray() && !stack_state->IsLongArray()) { + return -1; + } + mirror::PointerArray* method_trace = down_cast<mirror::PointerArray*>(stack_state->AsArray()); + int32_t array_len = method_trace->GetLength(); + // The format is [method pointers][pcs] so the depth is half the length (see method + // BuildInternalStackTraceVisitor::Init). + CHECK_EQ(array_len % 2, 0); + return array_len / 2; } std::string Throwable::Dump() { @@ -86,17 +95,21 @@ std::string Throwable::Dump() { result += "\n"; Object* stack_state = GetStackState(); // check stack state isn't missing or corrupt - if (stack_state != nullptr && stack_state->IsObjectArray()) { + if (stack_state != nullptr && + (stack_state->IsIntArray() || stack_state->IsLongArray())) { // Decode the internal stack trace into the depth and method trace - ObjectArray<Object>* method_trace = down_cast<ObjectArray<Object>*>(stack_state); - int32_t depth = method_trace->GetLength() - 1; - IntArray* pc_trace = down_cast<IntArray*>(method_trace->Get(depth)); + // Format is [method pointers][pcs] + auto* method_trace = down_cast<mirror::PointerArray*>(stack_state->AsArray()); + auto array_len = method_trace->GetLength(); + CHECK_EQ(array_len % 2, 0); + const auto depth = array_len / 2; if (depth == 0) { result += "(Throwable with empty stack trace)"; } else { + auto ptr_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); for (int32_t i = 0; i < depth; ++i) { - mirror::ArtMethod* method = down_cast<ArtMethod*>(method_trace->Get(i)); - uint32_t dex_pc = pc_trace->Get(i); + ArtMethod* method = method_trace->GetElementPtrSize<ArtMethod*>(i, ptr_size); + uintptr_t dex_pc = method_trace->GetElementPtrSize<uintptr_t>(i + depth, ptr_size); int32_t line_number = method->GetLineNumFromDexPC(dex_pc); const char* source_file = method->GetDeclaringClassSourceFile(); result += StringPrintf(" at %s (%s:%d)\n", PrettyMethod(method, true).c_str(), @@ -108,8 +121,7 @@ std::string Throwable::Dump() { if (stack_trace != nullptr && stack_trace->IsObjectArray()) { CHECK_EQ(stack_trace->GetClass()->GetComponentType(), StackTraceElement::GetStackTraceElement()); - ObjectArray<StackTraceElement>* ste_array = - down_cast<ObjectArray<StackTraceElement>*>(stack_trace); + auto* ste_array = down_cast<ObjectArray<StackTraceElement>*>(stack_trace); if (ste_array->GetLength() == 0) { result += "(Throwable with empty stack trace)"; } else { |