If a method is found in a superclass, filter on that class not a child

* This could cause a matching event to never happen, if we filtered on
  MethodEntry on the child class, but the method we wanted was on a
  superclass.
This commit is contained in:
baldurk
2018-05-04 17:36:30 +01:00
parent 4d004fe484
commit e96f290772
3 changed files with 21 additions and 8 deletions
+15 -5
View File
@@ -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;
+3 -1
View File
@@ -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
+3 -2
View File
@@ -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;
}
}