Make sure we delete the dex_pc_list vector
We were leaking memory by not destroying it before long jumping.
Test: Opened the AOSP calendar app and looked for unreachable memory
Bug: 251892250
Change-Id: Ib44613174cfe6e315fa77368a74db1005730ba51
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index b9dd3e1..eb9b471 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -219,18 +219,19 @@
}
if (GetHandlerMethod() != nullptr) {
const DexFile* dex_file = GetHandlerMethod()->GetDexFile();
- DCHECK_GE(handler_dex_pc_list_.size(), 1u);
+ DCHECK(handler_dex_pc_list_.has_value());
+ DCHECK_GE(handler_dex_pc_list_->size(), 1u);
int line_number = annotations::GetLineNumFromPC(
- dex_file, GetHandlerMethod(), handler_dex_pc_list_.front());
+ dex_file, GetHandlerMethod(), handler_dex_pc_list_->front());
// We may have an inlined method. If so, we can add some extra logging.
std::stringstream ss;
ArtMethod* maybe_inlined_method = visitor.GetMethod();
if (maybe_inlined_method != GetHandlerMethod()) {
const DexFile* inlined_dex_file = maybe_inlined_method->GetDexFile();
- DCHECK_GE(handler_dex_pc_list_.size(), 2u);
+ DCHECK_GE(handler_dex_pc_list_->size(), 2u);
int inlined_line_number = annotations::GetLineNumFromPC(
- inlined_dex_file, maybe_inlined_method, handler_dex_pc_list_.back());
+ inlined_dex_file, maybe_inlined_method, handler_dex_pc_list_->back());
ss << " which ends up calling inlined method " << maybe_inlined_method->PrettyMethod()
<< " (line: " << inlined_line_number << ")";
}
@@ -744,10 +745,13 @@
handler_method_header_ != nullptr &&
handler_method_header_->IsNterpMethodHeader()) {
// Interpreter procceses one method at a time i.e. not inlining
- DCHECK_EQ(handler_dex_pc_list_.size(), 1u) << "We shouldn't have any inlined frames.";
+ DCHECK(handler_dex_pc_list_.has_value());
+ DCHECK_EQ(handler_dex_pc_list_->size(), 1u) << "We shouldn't have any inlined frames.";
context_->SetNterpDexPC(reinterpret_cast<uintptr_t>(
- GetHandlerMethod()->DexInstructions().Insns() + handler_dex_pc_list_.front()));
+ GetHandlerMethod()->DexInstructions().Insns() + handler_dex_pc_list_->front()));
}
+ // Clear the dex_pc list so as not to leak memory.
+ handler_dex_pc_list_.reset();
context_->DoLongJump();
UNREACHABLE();
}
diff --git a/runtime/quick_exception_handler.h b/runtime/quick_exception_handler.h
index c87e38d..559c316 100644
--- a/runtime/quick_exception_handler.h
+++ b/runtime/quick_exception_handler.h
@@ -19,6 +19,7 @@
#include <android-base/logging.h>
#include <cstdint>
+#include <optional>
#include "base/array_ref.h"
#include "base/macros.h"
@@ -107,11 +108,12 @@
}
ArrayRef<const uint32_t> GetHandlerDexPcList() const {
- return ArrayRef<const uint32_t>(handler_dex_pc_list_);
+ DCHECK(handler_dex_pc_list_.has_value());
+ return ArrayRef<const uint32_t>(handler_dex_pc_list_.value());
}
void SetHandlerDexPcList(std::vector<uint32_t>&& handler_dex_pc_list) {
- handler_dex_pc_list_ = std::move(handler_dex_pc_list);
+ handler_dex_pc_list_ = handler_dex_pc_list;
}
uint32_t GetCatchStackMapRow() const {
@@ -164,7 +166,8 @@
uintptr_t handler_quick_arg0_;
// The handler's dex PC list including the inline dex_pcs. The dex_pcs are ordered from outermost
// to innermost. An empty list implies an uncaught exception.
- std::vector<uint32_t> handler_dex_pc_list_;
+ // Marked as optional so that we can make sure we destroy it before doing a long jump.
+ std::optional<std::vector<uint32_t>> handler_dex_pc_list_;
// StackMap row corresponding to the found catch.
uint32_t catch_stack_map_row_;
// Should the exception be cleared as the catch block has no move-exception?