summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastien Hertz <shertz@google.com>2015-04-02 16:26:48 +0200
committerSebastien Hertz <shertz@google.com>2015-04-02 16:51:24 +0200
commit2c3e77a0b91b2225fcdd3b34d8a734b85eec0579 (patch)
treee963fb08cd1072cb78e448334582c95d37e1f95c
parentc6e949a6d93fae2351fc59ed825657adee8185dc (diff)
downloadandroid_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.cc49
-rw-r--r--runtime/debugger.h6
-rw-r--r--runtime/jdwp/jdwp_handler.cc16
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;
}
}