/// <summary> /// The given thread has been created. /// </summary> protected override void OnThreadCreated(DalvikThread thread) { var dthread = (DebugThread)thread; base.OnThreadCreated(dthread); eventCallback.Send(dthread, new ThreadCreateEvent()); }
/// <summary> /// Notify listeners that we're suspended. /// </summary> protected override bool OnSuspended(SuspendReason reason, DalvikThread thread, StepRequest stepRequest) { var rc = base.OnSuspended(reason, thread, stepRequest); if (rc) { if (reason == SuspendReason.ProcessSuspend) { foreach (var threadx in ThreadManager.Threads) { eventCallback.Send(threadx, new ASyncBreakCompleteEvent()); } } if (reason == SuspendReason.SingleStep) { eventCallback.Send((DebugThread)thread, new StepCompleteEvent()); } } return(rc); }
/// <summary> /// Launch the actual debug process. /// </summary> public int LaunchSuspended(string pszServer, IDebugPort2 pPort, string pszExe, string pszArgs, string pszDir, string bstrEnv, string pszOptions, enum_LAUNCH_FLAGS dwLaunchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 pCallback, out IDebugProcess2 ppProcess) { DLog.Debug(DContext.VSDebuggerComCall, "IDebugEngine2.LaunchSuspended"); ppProcess = null; var port = pPort as DebugPort; if (pPort == null) { return(VSConstants.E_INVALIDARG); } // Create event callback eventCallback = new EngineEventCallback(this, pCallback); // Notify creation eventCallback.Send(new EngineCreateEvent(this)); // Get debugger var guid = new Guid(pszOptions); var debugger = Launcher.GetAndRemoveDebugger(guid, out stateUpdate); // Load map file var mapFilePath = Path.ChangeExtension(pszExe, ".d42map"); var mapFile = File.Exists(mapFilePath) ? new MapFile(mapFilePath) : new MapFile(); // copy exception to program now, in case it was delayed CopyExceptionMapToProgramIfDirty(); // Create new process var process = new DebugProcess(this, port, debugger, Environment.TickCount, guid, pszExe, mapFile, eventCallback); var program = process.Program; process.Terminated += (s, x) => ((IDebugEngine2)this).DestroyProgram(program); // Record process ((DebugPort)pPort).RecordProcess(process); // Return result ppProcess = process; return(VSConstants.S_OK); }
/// <summary> /// Notify visual studio of a bound breakpoint. /// </summary> internal void OnBound(DebugPendingBreakpoint pendingBreakpoint) { // Notify VS eventCallback.Send(Program, new BreakpointBoundEvent(pendingBreakpoint)); }
/// <summary> /// Launch the actual debug process. /// </summary> public int LaunchSuspended(string pszServer, IDebugPort2 pPort, string pszExe, string pszArgs, string pszDir, string bstrEnv, string pszOptions, enum_LAUNCH_FLAGS dwLaunchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 pCallback, out IDebugProcess2 ppProcess) { DLog.Debug(DContext.VSDebuggerComCall, "IDebugEngine2.LaunchSuspended"); ppProcess = null; var port = pPort as DebugPort; if (pPort == null) return VSConstants.E_INVALIDARG; // Create event callback eventCallback = new EngineEventCallback(this, pCallback); // Notify creation eventCallback.Send(new EngineCreateEvent(this)); // Get debugger var guid = new Guid(pszOptions); var debugger = Launcher.GetAndRemoveDebugger(guid, out stateUpdate); // Load map file var mapFilePath = Path.ChangeExtension(pszExe, ".d42map"); var mapFile = File.Exists(mapFilePath) ? new MapFile(mapFilePath) : new MapFile(); // Create new process var process = new DebugProcess(this, port, debugger, Environment.TickCount, guid, pszExe, mapFile, eventCallback); var program = process.Program; process.Terminated += (s, x) => ((IDebugEngine2)this).DestroyProgram(program); // Record process ((DebugPort)pPort).RecordProcess(process); // Return result ppProcess = process; return VSConstants.S_OK; }
/// <summary> /// Send the given event to VS. /// </summary> internal void Send(DebugThread thread, ExceptionEvent @event) { eventCallback.Send(thread, @event); }
/// <summary> /// Resumes process execution. /// </summary> public int ResumeProcess(IDebugProcess2 pProcess) { DLog.Debug(DContext.VSDebuggerComCall, "IDebugEngine2.ResumeProcess"); var process = pProcess as DebugProcess; if (process == null) { return(VSConstants.E_INVALIDARG); } try { var program = process.Program; ((IDebugPortNotify2)process.Port).AddProgramNode(program); // Suspend and prepare the VM var debugger = process.Debugger; var suspend = process.Debugger.VirtualMachine.SuspendAsync(); var prepare = suspend.ContinueWith(t => { t.ForwardException(); return(debugger.PrepareAsync()); }).Unwrap(); var loadThreads = prepare.ContinueWith(t => { t.ForwardException(); return(program.ThreadManager.RefreshAsync()); }).Unwrap(); loadThreads.ContinueWith(t => { t.ForwardException(); // Notify module eventCallback.Send(program, new ModuleLoadEvent(program.MainModule, "Loading module", true)); eventCallback.Send(program, new SymbolSearchEvent(program.MainModule, "Symbols loaded", enum_MODULE_INFO_FLAGS.MIF_SYMBOLS_LOADED)); var mainThread = program.ThreadManager.MainThread(); if (mainThread != null) { // Threads loaded // Load complete eventCallback.Send(mainThread, new LoadCompleteEvent()); eventCallback.Send(mainThread, new EntryPointEvent()); // Resume now debugger.VirtualMachine.ResumeAsync(); // We're fully attached now if (stateUpdate != null) { stateUpdate(LauncherStates.Attached, string.Empty); } stateUpdate = null; } else { DLog.Error(DContext.VSDebuggerLauncher, "No main thread found"); } }); return(VSConstants.S_OK); } catch (Exception ex) { DLog.Error(DContext.VSDebuggerLauncher, "ResumeProcess failed", ex); return(VSConstants.E_FAIL); } }