diff options
author | Sebastien Hertz <shertz@google.com> | 2015-04-02 16:26:48 +0200 |
---|---|---|
committer | Sebastien Hertz <shertz@google.com> | 2015-04-02 16:51:24 +0200 |
commit | 2c3e77a0b91b2225fcdd3b34d8a734b85eec0579 (patch) | |
tree | e963fb08cd1072cb78e448334582c95d37e1f95c | |
parent | c6e949a6d93fae2351fc59ed825657adee8185dc (diff) | |
download | android_art-2c3e77a0b91b2225fcdd3b34d8a734b85eec0579.tar.gz android_art-2c3e77a0b91b2225fcdd3b34d8a734b85eec0579.tar.bz2 android_art-2c3e77a0b91b2225fcdd3b34d8a734b85eec0579.zip |
JDWP: clear exception when allocation fails
Clears pending exception if an allocation (requested by the debugger)
fails and logs an error message about the failure.
Checks we never leave a pending exception after processing a JDWP
request.
Bug: 20037531
Change-Id: I63239034a3c1ab368b0e19c2f5f756d9e2ec6a29
-rw-r--r-- | runtime/debugger.cc | 49 | ||||
-rw-r--r-- | runtime/debugger.h | 6 | ||||
-rw-r--r-- | runtime/jdwp/jdwp_handler.cc | 16 |
3 files changed, 48 insertions, 23 deletions
diff --git a/runtime/debugger.cc b/runtime/debugger.cc index a767cf086f..f1f1a20436 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -1285,18 +1285,37 @@ JDWP::JdwpError Dbg::SetArrayElements(JDWP::ObjectId array_id, int offset, int c return JDWP::ERR_NONE; } -JDWP::ObjectId Dbg::CreateString(const std::string& str) { - return gRegistry->Add(mirror::String::AllocFromModifiedUtf8(Thread::Current(), str.c_str())); +JDWP::JdwpError Dbg::CreateString(const std::string& str, JDWP::ObjectId* new_string_id) { + Thread* self = Thread::Current(); + mirror::String* new_string = mirror::String::AllocFromModifiedUtf8(self, str.c_str()); + if (new_string == nullptr) { + DCHECK(self->IsExceptionPending()); + self->ClearException(); + LOG(ERROR) << "Could not allocate string"; + *new_string_id = 0; + return JDWP::ERR_OUT_OF_MEMORY; + } + *new_string_id = gRegistry->Add(new_string); + return JDWP::ERR_NONE; } -JDWP::JdwpError Dbg::CreateObject(JDWP::RefTypeId class_id, JDWP::ObjectId* new_object) { +JDWP::JdwpError Dbg::CreateObject(JDWP::RefTypeId class_id, JDWP::ObjectId* new_object_id) { JDWP::JdwpError error; mirror::Class* c = DecodeClass(class_id, &error); if (c == nullptr) { - *new_object = 0; + *new_object_id = 0; return error; } - *new_object = gRegistry->Add(c->AllocObject(Thread::Current())); + Thread* self = Thread::Current(); + mirror::Object* new_object = c->AllocObject(self); + if (new_object == nullptr) { + DCHECK(self->IsExceptionPending()); + self->ClearException(); + LOG(ERROR) << "Could not allocate object of type " << PrettyDescriptor(c); + *new_object_id = 0; + return JDWP::ERR_OUT_OF_MEMORY; + } + *new_object_id = gRegistry->Add(new_object); return JDWP::ERR_NONE; } @@ -1304,16 +1323,26 @@ JDWP::JdwpError Dbg::CreateObject(JDWP::RefTypeId class_id, JDWP::ObjectId* new_ * Used by Eclipse's "Display" view to evaluate "new byte[5]" to get "(byte[]) [0, 0, 0, 0, 0]". */ JDWP::JdwpError Dbg::CreateArrayObject(JDWP::RefTypeId array_class_id, uint32_t length, - JDWP::ObjectId* new_array) { + JDWP::ObjectId* new_array_id) { JDWP::JdwpError error; mirror::Class* c = DecodeClass(array_class_id, &error); if (c == nullptr) { - *new_array = 0; + *new_array_id = 0; return error; } - *new_array = gRegistry->Add(mirror::Array::Alloc<true>(Thread::Current(), c, length, - c->GetComponentSizeShift(), - Runtime::Current()->GetHeap()->GetCurrentAllocator())); + Thread* self = Thread::Current(); + gc::Heap* heap = Runtime::Current()->GetHeap(); + mirror::Array* new_array = mirror::Array::Alloc<true>(self, c, length, + c->GetComponentSizeShift(), + heap->GetCurrentAllocator()); + if (new_array == nullptr) { + DCHECK(self->IsExceptionPending()); + self->ClearException(); + LOG(ERROR) << "Could not allocate array of type " << PrettyDescriptor(c); + *new_array_id = 0; + return JDWP::ERR_OUT_OF_MEMORY; + } + *new_array_id = gRegistry->Add(new_array); return JDWP::ERR_NONE; } diff --git a/runtime/debugger.h b/runtime/debugger.h index 4f4a781c23..736a8ec01a 100644 --- a/runtime/debugger.h +++ b/runtime/debugger.h @@ -313,12 +313,12 @@ class Dbg { JDWP::Request* request) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - static JDWP::ObjectId CreateString(const std::string& str) + static JDWP::JdwpError CreateString(const std::string& str, JDWP::ObjectId* new_string_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - static JDWP::JdwpError CreateObject(JDWP::RefTypeId class_id, JDWP::ObjectId* new_object) + static JDWP::JdwpError CreateObject(JDWP::RefTypeId class_id, JDWP::ObjectId* new_object_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); static JDWP::JdwpError CreateArrayObject(JDWP::RefTypeId array_class_id, uint32_t length, - JDWP::ObjectId* new_array) + JDWP::ObjectId* new_array_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // diff --git a/runtime/jdwp/jdwp_handler.cc b/runtime/jdwp/jdwp_handler.cc index add1394f2d..0d161bc100 100644 --- a/runtime/jdwp/jdwp_handler.cc +++ b/runtime/jdwp/jdwp_handler.cc @@ -315,11 +315,12 @@ static JdwpError VM_Exit(JdwpState* state, Request* request, ExpandBuf*) static JdwpError VM_CreateString(JdwpState*, Request* request, ExpandBuf* pReply) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { std::string str(request->ReadUtf8String()); - ObjectId stringId = Dbg::CreateString(str); - if (stringId == 0) { - return ERR_OUT_OF_MEMORY; + ObjectId string_id; + JdwpError status = Dbg::CreateString(str, &string_id); + if (status != ERR_NONE) { + return status; } - expandBufAddObjectId(pReply, stringId); + expandBufAddObjectId(pReply, string_id); return ERR_NONE; } @@ -711,9 +712,6 @@ static JdwpError CT_NewInstance(JdwpState* state, Request* request, ExpandBuf* p if (status != ERR_NONE) { return status; } - if (object_id == 0) { - return ERR_OUT_OF_MEMORY; - } return RequestInvoke(state, request, pReply, thread_id, object_id, class_id, method_id, true); } @@ -730,9 +728,6 @@ static JdwpError AT_newInstance(JdwpState*, Request* request, ExpandBuf* pReply) if (status != ERR_NONE) { return status; } - if (object_id == 0) { - return ERR_OUT_OF_MEMORY; - } expandBufAdd1(pReply, JT_ARRAY); expandBufAddObjectId(pReply, object_id); return ERR_NONE; @@ -1657,6 +1652,7 @@ size_t JdwpState::ProcessRequest(Request* request, ExpandBuf* pReply) { if (result == ERR_NONE) { request->CheckConsumed(); } + self->AssertNoPendingException(); break; } } |