diff --git a/renderdoc/android/jdwp.cpp b/renderdoc/android/jdwp.cpp index a64199da9..4737db3ff 100644 --- a/renderdoc/android/jdwp.cpp +++ b/renderdoc/android/jdwp.cpp @@ -309,9 +309,17 @@ bool InjectLibraries(const std::string &deviceID, Network::Socket *sock) // look up onCreate in the most derived class - since we can't guarantee that the base // application.app.onCreate() will get called. - methodID onCreate = conn.GetMethod(thisClass.RefType, "onCreate", "()V"); + // + // Note that because we're filtering on both classID and methodID, we need to return back the + // exact class in the inheritance hierarchy matching the methodID, otherwise we could filter on + // the derived class but a parent method, and have no hits. + // + // This can happen if the most derived class doesn't have an onCreate, and we have to search to a + // superclass + referenceTypeID onCreateClass = thisClass.RefType; + methodID onCreateMethod = conn.GetMethod(thisClass.RefType, "onCreate", "()V", &onCreateClass); - if(onCreate == 0) + if(onCreateMethod == 0) { RDCERR("Couldn't find this.getClass().onCreate()"); return false; @@ -321,9 +329,11 @@ bool InjectLibraries(const std::string &deviceID, Network::Socket *sock) { thread = 0; - Event evData = conn.WaitForEvent( - EventKind::MethodEntry, {{ModifierKind::ClassOnly, thisClass.RefType}}, - [onCreate](const Event &evData) { return evData.MethodEntry.location.meth == onCreate; }); + Event evData = + conn.WaitForEvent(EventKind::MethodEntry, {{ModifierKind::ClassOnly, onCreateClass}}, + [onCreateMethod](const Event &evData) { + return evData.MethodEntry.location.meth == onCreateMethod; + }); if(evData.eventKind == EventKind::MethodEntry) thread = evData.MethodEntry.thread; diff --git a/renderdoc/android/jdwp.h b/renderdoc/android/jdwp.h index 1e4343559..9b3074e49 100644 --- a/renderdoc/android/jdwp.h +++ b/renderdoc/android/jdwp.h @@ -511,8 +511,10 @@ public: value GetFieldValue(referenceTypeID type, fieldID field); // get a method handle. If signature is empty, it's ignored for matching + // The actual class for the method (possibly a parent of 'type') will be returned in methClass if + // non-NULL methodID GetMethod(referenceTypeID type, const std::string &name, - const std::string &signature = ""); + const std::string &signature = "", referenceTypeID *methClass = NULL); // get a local variable slot. If signature is empty, it's ignored for matching. Returns -1 if not // found diff --git a/renderdoc/android/jdwp_connection.cpp b/renderdoc/android/jdwp_connection.cpp index 23de52998..a9ec2cd71 100644 --- a/renderdoc/android/jdwp_connection.cpp +++ b/renderdoc/android/jdwp_connection.cpp @@ -238,7 +238,7 @@ referenceTypeID Connection::GetType(objectID obj) } methodID Connection::GetMethod(referenceTypeID type, const std::string &name, - const std::string &signature) + const std::string &signature, referenceTypeID *methClass) { referenceTypeID searchClass = type; @@ -255,7 +255,8 @@ methodID Connection::GetMethod(referenceTypeID type, const std::string &name, { if(m.name == name && (signature == "" || signature == m.signature)) { - // RDCDEBUG("Found %s (%s)!", m.name.c_str(), m.signature.c_str()); + if(methClass) + *methClass = searchClass; return m.id; } }