/// <summary> /// Remove the given handler from the list of handlers for class prepare events. /// </summary> internal void Remove(DalvikClassPrepareCookie cookie) { lock (dataLock) { classPrepareHandlers.Remove(cookie); } }
/// <summary> /// Register a handler for class prepare events. /// </summary> internal DalvikClassPrepareCookie RegisterClassPrepareHandler(string signature, Action <ClassPrepare> handler) { var cookie = Interlocked.Increment(ref lastClassPrepareCookie); var result = new DalvikClassPrepareCookie(cookie, Tuple.Create(signature, handler)); lock (dataLock) { classPrepareHandlers.Add(result); } return(result); }
/// <summary> /// Try to bind this breakpoint to an actual breakpoint in the VM. /// This method is blocking, so make sure to call accordingly. /// </summary> internal override void TryBind(DalvikProcess process) { if (IsBound) { return; } // Lookup classid & methodid var pos = documentPosition; var signature = typeEntry.DexSignature; var referenceTypeManager = process.ReferenceTypeManager; // Register a callback for when the class is prepared. if (classPrepareCookie == null) { classPrepareCookie = referenceTypeManager.RegisterClassPrepareHandler(signature, evt => TryBind(process)); } // Now try to find the type var refType = referenceTypeManager.FindBySignature(signature); if (refType == null) { // Not possible yet return; } // We've found the type, we're no longer interested in class prepare events if (classPrepareCookie != null) { referenceTypeManager.Remove(classPrepareCookie); } var refTypeMethods = refType.GetMethodsAsync().Await(DalvikProcess.VmTimeout); var dmethod = refTypeMethods.FirstOrDefault(x => x.IsMatch(methodEntry)); if (dmethod == null) { throw new ArgumentException(string.Format("Cannot find method {0}", methodEntry.Name)); } // Now set breakpoint var location = new Location(refType.Id, dmethod.Id, (ulong)pos.MethodOffset); var setTask = process.Debugger.EventRequest.SetAsync(Jdwp.EventKind.BreakPoint, Jdwp.SuspendPolicy.All, new LocationOnlyModifier(location)); var requestId = setTask.Await(DalvikProcess.VmTimeout); // Store request ID and notify listeners that we're now bound. OnBound(requestId, process.BreakpointManager); // Process any events that came before we got a chance to record property. process.BreakpointManager.ProcessPendingEvents(this); }
private Location TryGetLocation(DalvikProcess process) { if (location != null) { return(location); } // Lookup classid & methodid var signature = typeEntry.DexSignature; var referenceTypeManager = process.ReferenceTypeManager; // Register a callback for when the class is prepared. if (classPrepareCookie == null) { classPrepareCookie = referenceTypeManager.RegisterClassPrepareHandler(signature, evt => TryBind(process)); } // Now try to find the type var refType = referenceTypeManager.FindBySignature(signature); if (refType == null) { // Not possible yet return(null); } // We've found the type, we're no longer interested in class prepare events if (classPrepareCookie != null) { referenceTypeManager.Remove(classPrepareCookie); } var refTypeMethods = refType.GetMethodsAsync().Await(DalvikProcess.VmTimeout); var dmethod = refTypeMethods.FirstOrDefault(x => x.IsMatch(methodEntry)); if (dmethod == null) { throw new ArgumentException(string.Format("Cannot find method {0}", methodEntry.Name)); } // return location. var pos = SourceCodePosition; location = new Location(refType.Id, dmethod.Id, (ulong)pos.Position.MethodOffset); documentLocation = new DocumentLocation(location, pos, refType, dmethod, typeEntry, methodEntry); return(location); }