/// <nodoc /> internal DebugLogsAnalyzer(AnalysisInput input, int port, bool enableCaching, bool ensureOrdering) : base(input) { m_port = port; EnableEvalCaching = enableCaching; EnsureOrdering = ensureOrdering; XlgState = new XlgDebuggerState(this); m_dirData = new MultiValueDictionary <AbsolutePath, DirectoryMembershipHashedEventData>(); m_criticalPathAnalyzer = new CriticalPathAnalyzer(input, outputFilePath: null); m_lazyCriticalPath = Lazy.Create(() => { m_criticalPathAnalyzer.Analyze(); return(m_criticalPathAnalyzer.criticalPathData); }); m_state = new DebuggerState(PathTable, LoggingContext, XlgState.Render, XlgState); m_lazyPipPerfDict = new Lazy <Dictionary <PipId, PipExecutionPerformance> >(() => { return(m_writeExecutionEntries.ToDictionary(e => e.PipId, e => e.ExecutionPerformance)); }); m_lazyPipsBySemiStableHash = new Lazy <Dictionary <long, PipId> >(() => { var result = new Dictionary <long, PipId>(); foreach (var pipId in PipTable.Keys) { result[PipTable.GetPipSemiStableHash(pipId)] = pipId; } return(result); }); }
/// <summary> /// /// </summary> private void UpdateMenuState(DebuggerState state) { if (StateChangedEvent != null) { StateChangedEvent(this, state); } }
public static void Write(FileInfo file) { var state = new DebuggerState { WorkingDirectory = WorkingDirectory, Arguments = Arguments, EnvironmentVariables = EnvironmentVariables, Watches = Watches, NextWatchId = _nextWatchId, Breakpoints = Breakpoints.ToDictionary(x => x.Key, x => Tuple.Create(x.Value, BreakEvents.Contains(x.Value))), NextBreakpointId = _nextBreakpointId, Catchpoints = BreakEvents.GetCatchpoints(), Aliases = Aliases, }; try { using (var stream = file.Open(FileMode.Create, FileAccess.Write)) new BinaryFormatter().Serialize(stream, state); } catch (Exception ex) { Log.Error("Could not write database file '{0}':", file); Log.Error(ex.ToString()); } }
private static void RenderSavedStateFileBrowser(IntPtr surface, DebuggerState state, string inputString, List <string> fileList, PacManPCB pcb) { var title = state == DebuggerState.LoadState ? $"{COLOR_BRIGHT_RED}LOAD STATE" : $"{COLOR_BRIGHT_GREEN}SAVE STATE"; FontRenderer.RenderString(surface, $"{COLOR_BRIGHT_WHITE}------------------------------[{title}{COLOR_BRIGHT_WHITE}]--------------------------------------", 0, 0 * ROW_HEIGHT); for (var i = 0; i < fileList.Count && i < 50; i++) { var file = fileList[i]; var selected = file == inputString; var color = selected ? $"{COLOR_BRIGHT_BLUE}" : $"{COLOR_WHITE}"; FontRenderer.RenderString(surface, $"{color}{(selected ? "--->" : " ")} {file}", 0, (i + 2) * ROW_HEIGHT); } if (pcb.BreakAtAddresses.Count >= 50) { FontRenderer.RenderString(surface, $" {COLOR_YELLOW}(only showing the first 50 of {fileList.Count} files)", 0, (50 + 2) * ROW_HEIGHT); } FontRenderer.RenderString(surface, $"{COLOR_BRIGHT_WHITE}--------------------------------------------------------------------------------", 0, (50 + 3) * ROW_HEIGHT); FontRenderer.RenderString(surface, $"{COLOR_WHITE}Enter a file name or use the arrows to select and then", 0, (50 + 4) * ROW_HEIGHT); FontRenderer.RenderString(surface, $"{COLOR_WHITE}press {COLOR_BRIGHT_GREEN}[ENTER] {COLOR_WHITE}to {title}{COLOR_WHITE}.", 0, (50 + 5) * ROW_HEIGHT); FontRenderer.RenderString(surface, $"> {inputString}", 0, (50 + 7) * ROW_HEIGHT); FontRenderer.RenderString(surface, $"{COLOR_BRIGHT_WHITE}--------------------------------------------------------------------------------", 0, (50 + 9) * ROW_HEIGHT); }
/// <summary> If we still have a socket try to send an exit message /// Doesn't seem to work ?!? /// </summary> internal virtual void exitSession() { PluginMain.settingObject.BreakOnThrowChanged -= settingObject_BreakOnThrowChanged; // clear out our watchpoint list and displays // keep breakpoints around so that we can try to reapply them if we reconnect if (m_Session != null) { if (m_RequestDetach) { m_Session.unbind(); } else { m_Session.terminate(); } m_Session = null; } if (runningIsolates != null) { runningIsolates.Clear(); } SessionManager mgr = Bootstrap.sessionManager(); if (mgr != null && mgr.isListening()) { mgr.stopListening(); } m_CurrentState = DebuggerState.Stopped; clearBreakpoints(); }
private void UpdateStatusDisplay(DebuggerState state) { Invoke(() => { StatusLabel.Text = $@"State: {state}"; switch (state) { case DebuggerState.Idle: StartGameButton.Enabled = true; StopGameButton.Enabled = false; break; case DebuggerState.Waiting: case DebuggerState.Attached: case DebuggerState.Suspended: StartGameButton.Enabled = false; StopGameButton.Enabled = true; break; default: StartGameButton.Enabled = false; StopGameButton.Enabled = false; break; } UpdateDebuggerControls(state); }); }
public void Initialise() { StoppedEventIsEnabled = true; asyncModeEnabled = false; responseReceived = new SemaphoreSlim(0, 1); currentState = DebuggerState.NotRunning; }
private bool InternalStepOver() { if (breakLines.Contains(Runtime.NextLineToExecute)) { if (!IgnoreNextBreakpoint) { //BreakpointEncountered?.Invoke(this, Runtime.NextLineToExecute); State = DebuggerState.Breaked; return(false); } } IgnoreNextBreakpoint = false; Result = Runtime.Step(); if (Runtime.HasEnded || Result.IsAbort()) { State = DebuggerState.CompletedOK; } if (Runtime.LastError != null) { State = DebuggerState.CompletedWithError; } if (State >= DebuggerState.CompletedOK) { // Runtime.WriteRunCompleteMessage(watch, Result); //ExecutionComplete?.Invoke(this); } return(State < DebuggerState.CompletedOK); }
/// <summary> /// Construct a stack frame for the given state with the given locals (both early and late bound). /// </summary> /// <param name="state">state for this stackframe</param> /// <param name="locals">collection of all locals (both early and late) for this frame. May be null.</param> internal VirtualStackFrame(DebuggerState state, IDictionary <string, object> locals) { ErrorUtilities.VerifyThrowInternalNull(state, "state"); State = state; Locals = locals; }
/// <nodoc /> internal DebugLogsAnalyzer(AnalysisInput input, int port) : base(input) { XlgState = new XlgDebuggerState(this); m_criticalPathAnalyzer = new CriticalPathAnalyzer(input, outputFilePath: null); m_lazyCriticalPath = Lazy.Create(() => { m_criticalPathAnalyzer.Analyze(); return(m_criticalPathAnalyzer.criticalPathData); }); m_port = port; m_state = new DebuggerState(PathTable, LoggingContext, XlgState.Render, XlgState); m_lazyPipPerfDict = new Lazy <Dictionary <PipId, PipExecutionPerformance> >(() => { return(m_writeExecutionEntries.ToDictionary(e => e.PipId, e => e.ExecutionPerformance)); }); m_lazyPipsBySemiStableHash = new Lazy <Dictionary <long, PipId> >(() => { var result = new Dictionary <long, PipId>(); foreach (var pipId in PipTable.Keys) { result[PipTable.GetPipSemiStableHash(pipId)] = pipId; } return(result); }); }
public void Break() { if (State == DebuggerState.Running) { State = DebuggerState.Break; } }
private void StepDebugger() { if (shouldReset) { if (!this.ResetDebugger()) { return; } } int oldLine = currentLine; RemoveCurrentHighlight(); do { debugState = debugger.Step(); UpdateState(); if (shouldReset) { return; } } while (currentLine <= 0 || oldLine == currentLine); UpdateStackPanel(); UpdateGasCost(); var targetLine = TextArea.Lines[currentLine]; targetLine.EnsureVisible(); targetLine.MarkerAdd(STEP_BG); var firstVisible = TextArea.FirstVisibleLine; var lastVisible = firstVisible + TextArea.LinesOnScreen; if (lastVisible > TextArea.Lines.Count) { lastVisible = TextArea.Lines.Count; } if (oldLine < 0) { targetLine.Goto(); } else if (currentLine == oldLine + 1) { if (currentLine >= lastVisible) { TextArea.LineScroll(1, 0); } } else { targetLine.Goto(); } }
/// <summary> If we still have a socket try to send an exit message /// Doesn't seem to work ?!? /// </summary> internal virtual void exitSession() { // clear out our watchpoint list and displays // keep breakpoints around so that we can try to reapply them if we reconnect if (m_Session != null) { if (m_RequestDetach) { m_Session.unbind(); } else { m_Session.terminate(); } m_Session = null; } SessionManager mgr = Bootstrap.sessionManager(); if (mgr.Listening) { mgr.stopListening(); } m_CurrentState = DebuggerState.Stopped; }
internal void RecvMsg(MessageEventArgs args) { Native_StartDataAccess(); // ring buffer on native side, so might get two chunks of data Native_GetDataForRead(out var ptr1, out var size1); Native_GetDataForRead(out var ptr2, out var size2); byte[] data = new byte[size1 + size2]; Marshal.Copy(ptr1, data, 0, (int)size1); if (size2 > 0) { Marshal.Copy(ptr2, data, (int)size1, (int)size2); } Native_EndDataAccess(); #if !UNITY_EDITOR PlayerConnection.instance.Send(kPlayerToEditorSendDebuggerOutput, data); #else DebuggerState.OnMessageEvent(new MessageEventArgs() { playerId = 0, data = data }); #endif }
public void SetState(DebuggerState p_State) { State = p_State; Update(); Program.SetStatus($"Process {ProcessInfo.ProcessId}:{ProcessInfo.ProcessName} - {p_State.ToString()}."); }
public void Stop() { InDebug = false; _state = DebuggerState.Stopping; _commandsWorker.CancelAsync(); _receiverWorker.CancelAsync(); _transport.Disconnect(); _state = DebuggerState.NotConnected; }
private void HandleDebuggerEventForEditBreakpointsState(SDL.SDL_Event sdlEvent) { HandleDebuggerInputText(sdlEvent); if (sdlEvent.type != SDL.SDL_EventType.SDL_KEYDOWN) { return; } var keycode = sdlEvent.key.keysym.sym; switch (keycode) { case SDL.SDL_Keycode.SDLK_RETURN: // Return/Enter = Finish input and toggle breakpoint { UInt16 address = 0; var input = _debuggerInputString; _debuggerInputString = String.Empty; if (input.ToLower() == "clear") { _debuggerPcb.BreakAtAddresses.Clear(); } else if (!String.IsNullOrWhiteSpace(input)) { try { address = Convert.ToUInt16(input, 16); if (_debuggerPcb.BreakAtAddresses.Contains(address)) { _debuggerPcb.BreakAtAddresses.Remove(address); } else { _debuggerPcb.BreakAtAddresses.Add(address); } } catch (Exception exception) { Console.WriteLine("Error parsing address in breakpoint editor.", exception); SDL2.SDL.SDL_ShowSimpleMessageBox(SDL.SDL_MessageBoxFlags.SDL_MESSAGEBOX_ERROR, "Breakpoint Editor", $"Error parsing address; enter a hexidecimal address in the format: 0x1234 or 1234.", _debugWindow); } } SignalDebuggerNeedsRendering(); break; } case SDL.SDL_Keycode.SDLK_ESCAPE: // Escape = Cancel editing breakpoints _debuggerInputString = String.Empty; _debuggerState = DebuggerState.Breakpoint; SignalDebuggerNeedsRendering(); break; } }
public void Run() { if (_resetFlag) { Reset(); } _state = _emulator.Run(); UpdateState(); }
public void BeginAwaitingInput() { if (state == DebuggerState.AwaitingInput) { throw new InvalidOperationException("Already awaiting input"); } priorState = state; ChangeState(DebuggerState.AwaitingInput); }
public void OnStopped() { DummyDelegate del = delegate { this.State = DebuggerState.Detached; this.OnStateChanged(); }; this.Window.Invoke(del); }
/// <summary> /// /// </summary> public void UpdateMenuState(object sender, DebuggerState state) { if ((PluginBase.MainForm as Form).InvokeRequired) { (PluginBase.MainForm as Form).BeginInvoke((MethodInvoker) delegate() { UpdateMenuState(sender, state); }); return; } if (state == DebuggerState.Initializing || state == DebuggerState.Stopped) { StartContinueButton.Text = StartContinueMenu.Text = TextHelper.GetString("Label.Start"); } else { StartContinueButton.Text = StartContinueMenu.Text = TextHelper.GetString("Label.Continue"); } StopButton.Enabled = StopMenu.Enabled = (state != DebuggerState.Initializing && state != DebuggerState.Stopped); PauseButton.Enabled = PauseMenu.Enabled = (state == DebuggerState.Running); if (state == DebuggerState.Initializing || state == DebuggerState.Stopped || state == DebuggerState.BreakHalt || state == DebuggerState.ExceptionHalt || state == DebuggerState.PauseHalt) { StartContinueButton.Enabled = StartContinueMenu.Enabled = true; } else { StartContinueButton.Enabled = StartContinueMenu.Enabled = false; } CurrentButton.Enabled = CurrentMenu.Enabled = RunToCursorButton.Enabled = RunToCursorMenu.Enabled = StepButton.Enabled = StepMenu.Enabled = NextButton.Enabled = NextMenu.Enabled = FinishButton.Enabled = FinishMenu.Enabled = (state == DebuggerState.BreakHalt || state == DebuggerState.PauseHalt); if (state == DebuggerState.Running) { PanelsHelper.pluginUI.TreeControl.Nodes.Clear(); PanelsHelper.stackframeUI.ClearItem(); } PluginBase.MainForm.BreakpointsEnabled = ToggleBreakPointMenu.Enabled = ToggleBreakPointEnableMenu.Enabled = DeleteAllBreakPointsMenu.Enabled = DisableAllBreakPointsMenu.Enabled = EnableAllBreakPointsMenu.Enabled = PanelsHelper.breakPointUI.Enabled = (state != DebuggerState.Running); PluginBase.MainForm.RefreshUI(); }
public bool ConnectToEmulator(bool IsCartridge) { if (State != DebuggerState.NOT_CONNECTED) { return(false); } m_IsCartridge = IsCartridge; m_State = DebuggerState.RUNNING; return(true); }
private void UpdateDebuggerControls(DebuggerState state) { bool isRunning = state == DebuggerState.Attached; bool isSuspended = state == DebuggerState.Suspended; PauseButton.Enabled = isRunning; ResumeButton.Enabled = isSuspended; StepInButton.Enabled = isSuspended; StepOverButton.Enabled = isSuspended; StepOutButton.Enabled = isSuspended; }
public void Step() { if (_resetFlag) { Reset(); } //STEP _state = Emulator.Step(); UpdateState(); }
public void Run() { if (State == DebuggerState.Idle) Reset(); if (State == DebuggerState.Break) { State = DebuggerState.Running; Task.Run(Evaluate); } }
/// <summary> /// Posts an Enter instruction to the island thread. /// Called by debugger manager thread /// </summary> internal void EnterState(DebuggerState state, IDictionary <string, object> locals) { _debugAction = DebugAction.Enter; _virtualStack.Push(new VirtualStackFrame(state, locals)); _workToDoEvent.Set(); // Block until Island executes NOP, // giving BPs a chance to be hit. // Must block here if the island is stopped at a breakpoint. _workDoneEvent.WaitOne(); }
public void ShowDebuggerState(DebuggerState newState) { if (invokee.InvokeRequired) { invokee.Invoke(ShowDebuggerStateMethod, new object[] { newState }); } else { ShowDebuggerStateMethod(newState); } }
public void Run() { if (State == DebuggerState.Idle) { Reset(); } if (State == DebuggerState.Break) { State = DebuggerState.Running; Task.Run(Evaluate); } }
public void Break() { StepOver(); RefreshRegistersAndWatches(); RefreshMemory(m_LastRequestedMemoryStartAddress, m_LastRequestedMemorySize, m_LastRequestedMemorySource); m_State = DebuggerState.PAUSED; /* * if ( SendCommand( "break" ) ) * { * m_State = DebuggerState.PAUSED; * }*/ }
public void Stop() { if (State == DebuggerState.Idle) return; State = DebuggerState.Idle; nodes.Clear(); tasks.Clear(); foreach (NodeInfo nodeInfo in FlowInfo.Flow.GetAllNodes().Select(n => NodeInfo.From(FlowInfo, n))) nodeInfo.Status = NodeStatus.Idle; }
private void HandleDebuggerEventForInstructionHistory(SDL.SDL_Event sdlEvent) { if (sdlEvent.type != SDL.SDL_EventType.SDL_KEYDOWN) { return; } if (sdlEvent.key.keysym.sym == SDL.SDL_Keycode.SDLK_ESCAPE) { _debuggerState = DebuggerState.Breakpoint; SignalDebuggerNeedsRendering(); } }
public InprocDebugger(Host host) { this.Host = host; this.DebugHost = host.Debugger; this.Window = new DebuggerWindow(this); this.Tools = new List <DebuggerTool>(); this.State = DebuggerState.Idle; this.Breakpoints = new BreakpointManager(this); this.CodeCache = new CodeCache(this); this.UserData = new UserDataStore(); this.SetupNavigation(); // Initialize tools... // ... this.CallstackTool = new CallstackTool(this); this.Tools.Add(this.CallstackTool); this.CodeTool = new CodeTool(this); this.Tools.Add(this.CodeTool); this.LogTool = new LogTool(this); this.Tools.Add(this.LogTool); this.MemoryTool = new MemoryTool(this); this.Tools.Add(this.MemoryTool); this.StatisticsTool = new StatisticsTool(this); this.Tools.Add(this.StatisticsTool); this.ThreadsTool = new ThreadsTool(this); this.Tools.Add(this.ThreadsTool); // ... this.Window.Show(); this.CodeTool.Show(this.Window.DockPanel); this.LogTool.Show(this.Window.DockPanel); this.ThreadsTool.Show(this.Window.DockPanel); WeifenLuo.WinFormsUI.Docking.DockPane dp; dp = this.Window.DockPanel.DockPaneFactory.CreateDockPane(this.CodeTool, WeifenLuo.WinFormsUI.Docking.DockState.Document, true); this.StatisticsTool.Show(dp, WeifenLuo.WinFormsUI.Docking.DockAlignment.Right, 0.45); dp = this.Window.DockPanel.DockPaneFactory.CreateDockPane(this.LogTool, WeifenLuo.WinFormsUI.Docking.DockState.DockBottom, true); this.CallstackTool.Show(dp, WeifenLuo.WinFormsUI.Docking.DockAlignment.Right, 0.24); this.MemoryTool.Show(this.StatisticsTool.DockHandler.Pane, this.StatisticsTool); this.Host.Debugger.Activate(this, Environment.MachineName, Environment.UserName, "InprocDebugger 1.0"); foreach (DebuggerTool tool in this.Tools) { tool.OnAttached(); } }
public InprocDebugger( Host host ) { this.Host = host; this.DebugHost = host.Debugger; this.Window = new DebuggerWindow( this ); this.Tools = new List<DebuggerTool>(); this.State = DebuggerState.Idle; this.Breakpoints = new BreakpointManager( this ); this.CodeCache = new CodeCache( this ); this.UserData = new UserDataStore(); this.SetupNavigation(); // Initialize tools... // ... this.CallstackTool = new CallstackTool( this ); this.Tools.Add( this.CallstackTool ); this.CodeTool = new CodeTool( this ); this.Tools.Add( this.CodeTool ); this.LogTool = new LogTool( this ); this.Tools.Add( this.LogTool ); this.MemoryTool = new MemoryTool( this ); this.Tools.Add( this.MemoryTool ); this.StatisticsTool = new StatisticsTool( this ); this.Tools.Add( this.StatisticsTool ); this.ThreadsTool = new ThreadsTool( this ); this.Tools.Add( this.ThreadsTool ); // ... this.Window.Show(); this.CodeTool.Show( this.Window.DockPanel ); this.LogTool.Show( this.Window.DockPanel ); this.ThreadsTool.Show( this.Window.DockPanel ); WeifenLuo.WinFormsUI.Docking.DockPane dp; dp = this.Window.DockPanel.DockPaneFactory.CreateDockPane( this.CodeTool, WeifenLuo.WinFormsUI.Docking.DockState.Document, true ); this.StatisticsTool.Show( dp, WeifenLuo.WinFormsUI.Docking.DockAlignment.Right, 0.45 ); dp = this.Window.DockPanel.DockPaneFactory.CreateDockPane( this.LogTool, WeifenLuo.WinFormsUI.Docking.DockState.DockBottom, true ); this.CallstackTool.Show( dp, WeifenLuo.WinFormsUI.Docking.DockAlignment.Right, 0.24 ); this.MemoryTool.Show( this.StatisticsTool.DockHandler.Pane, this.StatisticsTool ); this.Host.Debugger.Activate( this, Environment.MachineName, Environment.UserName, "InprocDebugger 1.0" ); foreach( DebuggerTool tool in this.Tools ) tool.OnAttached(); }
public void Break() { if (State == DebuggerState.Running) State = DebuggerState.Break; }
/// <summary> If we still have a socket try to send an exit message /// Doesn't seem to work ?!? /// </summary> internal virtual void exitSession() { // clear out our watchpoint list and displays // keep breakpoints around so that we can try to reapply them if we reconnect if (m_Session != null) { if (m_RequestDetach) { m_Session.unbind(); } else { m_Session.terminate(); } m_Session = null; } SessionManager mgr = Bootstrap.sessionManager(); if (mgr.Listening) mgr.stopListening(); m_CurrentState = DebuggerState.Stopped; }
public void OnStarted( GameInformation game, Stream bootStream ) { // Need to marshal all UI calls to the proper thread DummyDelegate del = delegate { this.State = DebuggerState.Running; this.OnStateChanged(); foreach( DebuggerTool tool in this.Tools ) tool.OnStarted(); }; this.Window.Invoke( del ); }
/// <summary> /// /// </summary> private void UpdateMenuState(DebuggerState state) { if (StateChangedEvent != null) StateChangedEvent(this, state); }
/// <summary> /// Main loop /// </summary> public void Start() { m_CurrentState = DebuggerState.Starting; m_activeSession = 1; SessionManager mgr = Bootstrap.sessionManager(); //mgr.setDebuggerCallbacks(new FlashDebuggerCallbacks()); // obsoleted mgr.setPreference(SessionManager_.PREF_GETVAR_RESPONSE_TIMEOUT, 5000); m_RequestDetach = false; mgr.startListening(); try { m_Session = mgr.accept(this); if (mgr.isListening()) mgr.stopListening(); TraceManager.AddAsync("[Starting debug session with FDB]", -1); if (m_Session == null) { m_CurrentState = DebuggerState.Stopped; throw new Exception(TextHelper.GetString("Info.UnableToStartDebugger")); } initSession(); m_CurrentState = DebuggerState.Running; if (StartedEvent != null) { StartedEvent(this); } try { waitTilHalted(); } catch (Exception){} try { waitForMetaData(); } catch (Exception){} m_CurrentState = DebuggerState.Running; m_Session.breakOnCaughtExceptions(PluginMain.settingObject.BreakOnThrow); // now poke to see if the player is good enough try { if (m_Session.getPreference(SessionManager_.PLAYER_SUPPORTS_GET) == 0) { TraceManager.AddAsync(TextHelper.GetString("Info.WarningNotAllCommandsSupported")); } } catch (Exception){} m_SuspendWaiting = false; bool stop = false; while (!stop) { if (m_Session != null && m_Session.getEventCount() > 0) m_SuspendWaiting = false; processEvents(); // not there, not connected if (m_RequestStop || m_RequestDetach || !haveConnection()) { stop = true; if (m_RequestResume) { // resume before we disconnect, this is in case of ExceptionHalt m_Session.resume(); // just throw for now if (ThreadsEvent != null) ThreadsEvent(this); } continue; } if (m_RequestResume) { // resume execution (request fulfilled) try { if (m_StepResume) { m_Session.stepContinue(); } else { m_Session.resume(); } if (ThreadsEvent != null) ThreadsEvent(this); } catch (NotSuspendedException) { TraceManager.AddAsync(TextHelper.GetString("Info.PlayerAlreadyRunning")); } catch (NoResponseException) { TraceManager.AddAsync(TextHelper.GetString("Info.ProcessNotResponding")); } m_RequestResume = false; m_RequestPause = false; m_StepResume = false; m_CurrentState = DebuggerState.Running; continue; } if (m_Session.isSuspended()) { /* * We have stopped for some reason. * Now before we do this see, if we have a valid break reason, since * we could be still receiving incoming messages, even though we have halted. * This is definately the case with loading of multiple SWFs. After the load * we get info on the swf. */ int tries = 3; while (tries-- > 0 && m_Session.suspendReason() == SuspendReason_.Unknown) { try { Thread.Sleep(100); processEvents(); } catch (ThreadInterruptedException){} } m_SuspendWait.Reset(); switch (m_SuspendWaiting ? -1 : suspendReason) { case 1://SuspendReason_.Breakpoint: m_CurrentState = DebuggerState.BreakHalt; if (BreakpointEvent != null) { m_RequestPause = true; // trigger only for main worker here (if we are main worker, or if we are not and are not suspended) if (ActiveSession == 1 || !isDebuggerSuspended) { Frame[] frames = m_Session.getFrames(); Location loc = null; if (frames.Length > 0) { loc = frames[0].getLocation(); } if (loc != null && m_BreakPointManager.ShouldBreak(loc.getFile(), loc.getLine(), frames[0])) { ActiveSession = 1; BreakpointEvent(this); } else { m_RequestResume = true; m_StepResume = true; } } else { if (ThreadsEvent != null) { ThreadsEvent(this); } } } else { m_RequestResume = true; } break; case 3://SuspendReason_.Fault: m_CurrentState = DebuggerState.ExceptionHalt; if (FaultEvent != null) { FaultEvent(this); } else { m_RequestResume = true; } break; case 7://SuspendReason_.ScriptLoaded: try { waitForMetaData(); } catch (InProgressException) {} m_CurrentState = DebuggerState.PauseHalt; // refresh breakpoints clearBreakpoints(); UpdateBreakpoints(m_BreakPointManager.BreakPoints); if (ScriptLoadedEvent != null) { ScriptLoadedEvent(this); } else { m_RequestResume = true; } break; case 5://SuspendReason_.Step: m_CurrentState = DebuggerState.BreakHalt; if (StepEvent != null) { StepEvent(this); } else { m_RequestResume = true; } break; case 4://SuspendReason_.StopRequest: m_CurrentState = DebuggerState.PauseHalt; if (PauseEvent != null) { PauseEvent(this); } else { m_RequestResume = true; } break; case 2://SuspendReason_.Watch: m_CurrentState = DebuggerState.BreakHalt; if (WatchpointEvent != null) { WatchpointEvent(this); } else { m_RequestResume = true; } break; case -1: // waiting for susped to end, do nothing break; default: m_CurrentState = DebuggerState.BreakHalt; if (UnknownHaltEvent != null) { UnknownHaltEvent(this); } else { m_RequestResume = true; } break; } if (!(m_RequestResume || m_RequestDetach)) { m_SuspendWaiting = !m_SuspendWait.WaitOne(500, false); } } else { if (m_RequestPause) { try { m_CurrentState = DebuggerState.Pausing; try { m_Session.suspend(); } catch { } // No crash here please... if (!haveConnection()) // no connection => dump state and end { stop = true; continue; } else if (!m_Session.isSuspended()) { m_RequestPause = false; m_CurrentState = DebuggerState.Running; TraceManager.AddAsync(TextHelper.GetString("Info.CouldNotHalt")); if (PauseFailedEvent != null) { PauseFailedEvent(this); } } } catch (ArgumentException) { TraceManager.AddAsync(TextHelper.GetString("Info.EscapingFromDebuggerPendingLoop")); stop = true; } catch (IOException io) { IDictionary args = new Hashtable(); args["error"] = io.Message; //$NON-NLS-1$ TraceManager.AddAsync(replaceInlineReferences(TextHelper.GetString("Info.ContinuingDueToError"), args)); } catch (SuspendedException) { // lucky us, already paused } } } // sleep for a bit, then process our events. // process isolates foreach (var kv in runningIsolates) { if (kv.Value.requestPause) { try { kv.Value.i_Session.suspend(); } catch (Exception e) { TraceManager.AddAsync("Isolate suspend exception: " + e.ToString()); } } kv.Value.requestPause = false; } try { Thread.Sleep(m_UpdateDelay); } catch {} } } catch (SocketException ex) { // No errors if requested if (!m_RequestStop) throw ex; } catch (SocketTimeoutException ex) { if (m_CurrentState != DebuggerState.Starting) throw ex; TraceManager.AddAsync("[No debug Flash player connection request]", -1); } finally { if (DisconnectedEvent != null) { DisconnectedEvent(this); } exitSession(); } }
private void ShowSourceView( uint address ) { ShowSourceViewDelegate del = delegate { this.Code.BringToFront(); this.Code.Activate(); this.Code.Show( this.View.DockPanel ); // Jump in code this.Code.SetAddress( address ); if( this.CallStacksEnabled == true ) { Frame[] stack = this.GetCallstack(); this.CallStack.SetCallstack( stack ); } this.State = DebuggerState.Broken; this.OnStateChanged(); }; this.View.Invoke( del, address ); }
/// <summary> /// Declare a new state associated with the given source location. /// States should (probably) have disjoint source locations. /// Define as many states as possible using this method before calling Bake(). /// Location must map to a unique state within the type in which it is baked. /// Name of the state will showup in the callstack as if it was a method name. Must be unique within the type in which it is baked. /// Early-bound locals are arbitrary types whose values will be supplied on EnterState. May be null. /// </summary> internal static void DefineState(ElementLocation location, string name, ICollection<DebuggerLocalType> earlyLocals) { ErrorUtilities.VerifyThrow(s_initialized, "Not initialized"); ErrorUtilities.VerifyThrow(DebuggingEnabled, "Debugging not enabled"); // Special case: elements added by editing, such as in a solution wrapper project, // do not have line numbers. Such files cannot be debugged, so we special case // such locations by doing nothing. if (location.Line == 0) { return; } ErrorUtilities.VerifyThrow(!s_unbakedStates.ContainsKey(name), "Need unique debug state name, already seen '{0}'", name); DebuggerState state = new DebuggerState(location, name, earlyLocals); s_unbakedStates.Add(name, state); }
private async Task Evaluate() { NodeInfo[] stepNodes; lock (nodes) { if (nodes.Count == 0) return; stepNodes = nodes.ToArray(); nodes.Clear(); } foreach (NodeInfo nodeInfo in stepNodes) { //TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext(); //CancellationToken token = new CancellationToken(false); //Task task = await Task.Factory.StartNew(() => Evaluate(nodeInfo), token, TaskCreationOptions.LongRunning, scheduler); Task task = Task.Run(() => Evaluate(nodeInfo)); lock (tasks) tasks.Add(task); task.ContinueWith(t => { lock (tasks) { tasks.Remove(t); if (tasks.Count == 0 && nodes.Count == 0) State = DebuggerState.Idle; } if (State == DebuggerState.Running) Task.Run(Evaluate); }); } }
private void Reset() { FlowInfo.Flow.Reset(); nodes.Clear(); nodes = FlowInfo.Flow.Origins .Select(n => NodeInfo.From(FlowInfo, n)) .ToList(); foreach (NodeInfo nodeInfo in nodes) nodeInfo.Status = NodeStatus.Paused; State = DebuggerState.Break; }
/// <summary> /// Create the representation of a single state, known as an "island". /// It is implemented as a small method in the type being baked into the dynamic module. /// Returns the name of the method. /// </summary> private static string CreateIsland(TypeBuilder typeBuilder, DebuggerState state) { // Parameters to the islands: // 1. Island thread // 2 ... N. list of early bound locals. Type[] parameterTypes = new Type[1 + state.EarlyLocalsTypes.Count]; parameterTypes[0] = typeof(IslandThread); int i = 1; foreach (DebuggerLocalType local in state.EarlyLocalsTypes) { parameterTypes[i] = local.Type; i++; } MethodBuilder method = typeBuilder.DefineMethod ( state.Name /* method name */, MethodAttributes.Static | MethodAttributes.Public, typeof(void) /* return type */, parameterTypes ); // Define the parameter names. // Do not define a parameter for the first parameter, as this is an // implementation detail and we want to hide it from VS. // Parameter 0 is the return type. int j = 2; foreach (DebuggerLocalType local in state.EarlyLocalsTypes) { method.DefineParameter(j, ParameterAttributes.None, local.Name); j++; } // Note that the locals are ignored by the method, they are only for the debugger to display; // only the thread parameter is passed on. // void MethodName(IslandThread thread, ... early locals ... ) // { // .line // nop // call Worker(thread) // ret; // } ILGenerator generator = method.GetILGenerator(); ISymbolDocumentWriter source; if (!s_sources.TryGetValue(state.Location.File, out source)) { source = s_dynamicModule.DefineDocument(state.Location.File, Guid.Empty, Guid.Empty, Guid.Empty); s_sources.Add(state.Location.File, source); } // Lines may not be zero, columns may be zero int line = (state.Location.Line == 0) ? 1 : state.Location.Line; generator.MarkSequencePoint(source, line, state.Location.Column, line, Int32.MaxValue); // mapping to source file generator.Emit(OpCodes.Nop); // Can help with setting a breakpoint generator.Emit(OpCodes.Ldarg_0); // Load argument 0 that went to this method back onto the stack to pass to the call generator.EmitCall(OpCodes.Call, s_islandCallback /* method */, null /* no opt params */); generator.Emit(OpCodes.Ret); // Return from state return method.Name; }
public FlashInterface() { m_HaltTimeout = 7000; m_UpdateDelay = 25; m_CurrentState = DebuggerState.Stopped; }
public void OnStopped() { DummyDelegate del = delegate { this.Log.OnStopped(); this.Statistics.OnStopped(); this.State = DebuggerState.Detached; this.OnStateChanged(); }; this.View.Invoke( del ); }
/// <summary> If we still have a socket try to send an exit message /// Doesn't seem to work ?!? /// </summary> internal virtual void exitSession() { PluginMain.settingObject.BreakOnThrowChanged -= settingObject_BreakOnThrowChanged; // clear out our watchpoint list and displays // keep breakpoints around so that we can try to reapply them if we reconnect if (m_Session != null) { if (m_RequestDetach) { m_Session.unbind(); } else { m_Session.terminate(); } m_Session = null; } if (runningIsolates != null) runningIsolates.Clear(); SessionManager mgr = Bootstrap.sessionManager(); if (mgr != null && mgr.isListening()) mgr.stopListening(); m_CurrentState = DebuggerState.Stopped; clearBreakpoints(); }
public void UpdateMenuState(object sender, DebuggerState state) { if ((PluginBase.MainForm as Form).InvokeRequired) { (PluginBase.MainForm as Form).BeginInvoke((MethodInvoker)delegate() { UpdateMenuState(sender, state); }); return; } Boolean hasChanged = CurrentState != state; CurrentState = state; // Set current now... if (state == DebuggerState.Initializing || state == DebuggerState.Stopped) { if (PluginMain.settingObject.StartDebuggerOnTestMovie) StartContinueButton.Text = StartContinueMenu.Text = TextHelper.GetString("Label.Continue"); else StartContinueButton.Text = StartContinueMenu.Text = TextHelper.GetString("Label.Start"); } else StartContinueButton.Text = StartContinueMenu.Text = TextHelper.GetString("Label.Continue"); PluginBase.MainForm.ApplySecondaryShortcut(StartContinueButton); // StopButton.Enabled = StopMenu.Enabled = (state != DebuggerState.Initializing && state != DebuggerState.Stopped); PauseButton.Enabled = PauseMenu.Enabled = (state == DebuggerState.Running); // if (state == DebuggerState.Initializing || state == DebuggerState.Stopped) { if (PluginMain.settingObject.StartDebuggerOnTestMovie) StartContinueButton.Enabled = StartContinueMenu.Enabled = false; else StartContinueButton.Enabled = StartContinueMenu.Enabled = true; } else if (state == DebuggerState.BreakHalt || state == DebuggerState.ExceptionHalt || state == DebuggerState.PauseHalt) { StartContinueButton.Enabled = StartContinueMenu.Enabled = true; } else StartContinueButton.Enabled = StartContinueMenu.Enabled = false; // Boolean enabled = (state == DebuggerState.BreakHalt || state == DebuggerState.PauseHalt); CurrentButton.Enabled = CurrentMenu.Enabled = RunToCursorButton.Enabled = enabled; NextButton.Enabled = NextMenu.Enabled = FinishButton.Enabled = FinishMenu.Enabled = enabled; RunToCursorMenu.Enabled = StepButton.Enabled = StepMenu.Enabled = enabled; if (state == DebuggerState.Running && (!PluginMain.debugManager.FlashInterface.isDebuggerStarted || !PluginMain.debugManager.FlashInterface.isDebuggerSuspended)) { PanelsHelper.localsUI.TreeControl.Nodes.Clear(); PanelsHelper.stackframeUI.ClearItem(); } enabled = GetLanguageIsValid(); ToggleBreakPointMenu.Enabled = ToggleBreakPointEnableMenu.Enabled = enabled; DeleteAllBreakPointsMenu.Enabled = DisableAllBreakPointsMenu.Enabled = enabled; EnableAllBreakPointsMenu.Enabled = PanelsHelper.breakPointUI.Enabled = enabled; StartRemoteDebuggingMenu.Enabled = (state == DebuggerState.Initializing || state == DebuggerState.Stopped); // Boolean hideButtons = state == DebuggerState.Initializing || state == DebuggerState.Stopped; StartContinueButton.Visible = StartContinueButton.Enabled; PauseButton.Visible = StopButton.Visible = CurrentButton.Visible = NextButton.Visible = RunToCursorButton.Visible = StepButton.Visible = FinishButton.Visible = !hideButtons; m_ToolStripSeparator.Visible = StartContinueButton.Visible; m_ToolStripSeparator2.Visible = !hideButtons; // Notify plugins of main states when state changes... if (hasChanged && (state == DebuggerState.Running || state == DebuggerState.Stopped)) { DataEvent de = new DataEvent(EventType.Command, "FlashDebugger." + state.ToString(), null); EventManager.DispatchEvent(this, de); } PluginBase.MainForm.RefreshUI(); }
public void OnStopped() { DummyDelegate del = delegate { this.State = DebuggerState.Detached; this.OnStateChanged(); }; this.Window.Invoke( del ); }
public void OnStarted( GameInformation game, Stream bootStream ) { // Need to marshal all UI calls to the proper thread DummyDelegate del = delegate { this.Log.OnStarted(); this.Statistics.OnStarted(); this.View.SetStatusText( Verbosity.Normal, "Connection to emulator {0} established.", this.Host.HostString ); this.State = DebuggerState.Running; this.OnStateChanged(); }; this.View.Invoke( del ); // TEST Breakpoint bp = new Breakpoint( this.AllocateID(), BreakpointType.CodeExecute, 0x08900334 ); //this.Breakpoints.Add( bp ); }
/// <summary> /// /// </summary> private void UpdateUI(DebuggerState state) { if ((PluginBase.MainForm as Form).InvokeRequired) { (PluginBase.MainForm as Form).BeginInvoke((MethodInvoker)delegate() { UpdateUI(state); }); return; } CurrentLocation = FlashInterface.getCurrentLocation(); UpdateStackUI(); UpdateLocalsUI(); UpdateMenuState(state); (PluginBase.MainForm as Form).Activate(); }
private void DebuggerStateChanged(DebuggerState newState) { switch (newState) { case DebuggerState.DebuggeeRunning: runButton.Enabled = false; buttonCommand34.Enabled = false; pauseButton.Enabled = true; stopButton.Enabled = true; runToCursorButton.Enabled = true; stepOverButtonCommand.Enabled = false; stepIntoButtonCommand.Enabled = false; stepOutButtonCommand.Enabled = false; uiStatusBar1.Panels[2].Text = attach ? "Attached" : "Process Running"; break; case DebuggerState.DebuggeeStopped: ShowDebuggeeStoppedState(); uiStatusBar1.Panels[2].Text = detach ? "Detached" : "Process Stopped"; //doNotStopButton.Enabled = false; //doNotStopHereButton.Enabled = false; //CloseDynamicModuleDocuments(); break; case DebuggerState.DebuggeePaused: case DebuggerState.DebuggeeSuspended: runButton.Enabled = true; buttonCommand34.Enabled = true; pauseButton.Enabled = false; stopButton.Enabled = true; runToCursorButton.Enabled = true; stepOverButtonCommand.Enabled = true; stepIntoButtonCommand.Enabled = true; stepOutButtonCommand.Enabled = true; uiStatusBar1.Panels[2].Text = "Process Suspended"; break; case DebuggerState.EvaluatingExpression: runButton.Enabled = false; buttonCommand34.Enabled = false; pauseButton.Enabled = false; stopButton.Enabled = false; runToCursorButton.Enabled = false; stepOverButtonCommand.Enabled = false; stepIntoButtonCommand.Enabled = false; stepOutButtonCommand.Enabled = false; uiStatusBar1.Panels[2].Text = attach ? "Attached" : "Process Running"; //objectViewerMenu.Enabled = false; break; case DebuggerState.DebuggeeThrewException: runButton.Enabled = true; buttonCommand34.Enabled = true; pauseButton.Enabled = false; stopButton.Enabled = true; runToCursorButton.Enabled = true; stepOverButtonCommand.Enabled = true; stepIntoButtonCommand.Enabled = true; stepOutButtonCommand.Enabled = true; uiStatusBar1.Panels[2].Text = "Exception"; break; } }
public void ShowDebuggerState(DebuggerState newState) { switch (newState) { case DebuggerState.DebuggeeRunning: runButton.Enabled = false; pauseButton.Enabled = true; stopButton.Enabled = true; detachButton.Enabled = true; doNotStopButton.Enabled = false; doNotStopHereButton.Enabled = false; attachToProcessMenu.Enabled = false; runDebuggeeMenu.Enabled = false; pauseDebuggeeMenu.Enabled = true; stopDebuggeeMenu.Enabled = true; detachMenu.Enabled = true; runToCursorMenu.Enabled = true; stepMenu.Enabled = false; stepIntoMenu.Enabled = false; stepOutMenu.Enabled = false; objectViewerMenu.Enabled = false; break; case DebuggerState.DebuggeeStopped: ShowDebuggeeStoppedState(); doNotStopButton.Enabled = false; doNotStopHereButton.Enabled = false; CloseDynamicModuleDocuments(); break; case DebuggerState.DebuggeePaused: case DebuggerState.DebuggeeSuspended: runButton.Enabled = true; pauseButton.Enabled = false; stopButton.Enabled = true; detachButton.Enabled = true; doNotStopButton.Enabled = false; doNotStopHereButton.Enabled = false; attachToProcessMenu.Enabled = false; runDebuggeeMenu.Enabled = true; pauseDebuggeeMenu.Enabled = false; stopDebuggeeMenu.Enabled = true; detachMenu.Enabled = true; runToCursorMenu.Enabled = true; stepMenu.Enabled = true; stepIntoMenu.Enabled = true; stepOutMenu.Enabled = true; objectViewerMenu.Enabled = true; break; case DebuggerState.EvaluatingExpression: runButton.Enabled = false; pauseButton.Enabled = false; stopButton.Enabled = false; detachButton.Enabled = false; doNotStopButton.Enabled = false; doNotStopHereButton.Enabled = false; attachToProcessMenu.Enabled = false; runDebuggeeMenu.Enabled = false; pauseDebuggeeMenu.Enabled = false; stopDebuggeeMenu.Enabled = false; detachMenu.Enabled = false; runToCursorMenu.Enabled = false; stepMenu.Enabled = false; stepIntoMenu.Enabled = false; stepOutMenu.Enabled = false; objectViewerMenu.Enabled = false; break; case DebuggerState.DebuggeeThrewException: runButton.Enabled = true; pauseButton.Enabled = false; stopButton.Enabled = true; detachButton.Enabled = true; doNotStopButton.Enabled = true; doNotStopHereButton.Enabled = true; attachToProcessMenu.Enabled = false; runDebuggeeMenu.Enabled = true; pauseDebuggeeMenu.Enabled = false; stopDebuggeeMenu.Enabled = true; detachMenu.Enabled = true; runToCursorMenu.Enabled = true; stepMenu.Enabled = true; stepIntoMenu.Enabled = true; stepOutMenu.Enabled = true; objectViewerMenu.Enabled = true; break; } }
/// <summary> /// Construct a stack frame for the given state with the given locals (both early and late bound). /// </summary> /// <param name="state">state for this stackframe</param> /// <param name="locals">collection of all locals (both early and late) for this frame. May be null.</param> internal VirtualStackFrame(DebuggerState state, IDictionary<string, object> locals) { ErrorUtilities.VerifyThrowInternalNull(state, "state"); State = state; Locals = locals; }
private void DebugEventHandler_StateChanged(DebuggerState oldState, DebuggerState newState) { UIHandler.Instance.ShowDebuggerState(newState); }
public void UpdateMenuState(object sender, DebuggerState state) { if ((PluginBase.MainForm as Form).InvokeRequired) { (PluginBase.MainForm as Form).BeginInvoke((MethodInvoker)delegate() { UpdateMenuState(sender, state); }); return; } CurrentState = state; // Set current now... if (state == DebuggerState.Initializing || state == DebuggerState.Stopped) { if (PluginMain.settingObject.StartDebuggerOnTestMovie) StartContinueButton.Text = StartContinueMenu.Text = TextHelper.GetString("Label.Continue"); else StartContinueButton.Text = StartContinueMenu.Text = TextHelper.GetString("Label.Start"); } else StartContinueButton.Text = StartContinueMenu.Text = TextHelper.GetString("Label.Continue"); // StopButton.Enabled = StopMenu.Enabled = (state != DebuggerState.Initializing && state != DebuggerState.Stopped); PauseButton.Enabled = PauseMenu.Enabled = (state == DebuggerState.Running); // if (state == DebuggerState.Initializing || state == DebuggerState.Stopped) { if (PluginMain.settingObject.StartDebuggerOnTestMovie) StartContinueButton.Enabled = StartContinueMenu.Enabled = false; else StartContinueButton.Enabled = StartContinueMenu.Enabled = true; } else if (state == DebuggerState.BreakHalt || state == DebuggerState.ExceptionHalt || state == DebuggerState.PauseHalt) { StartContinueButton.Enabled = StartContinueMenu.Enabled = true; } else StartContinueButton.Enabled = StartContinueMenu.Enabled = false; // Boolean enabled = (state == DebuggerState.BreakHalt || state == DebuggerState.PauseHalt); CurrentButton.Enabled = CurrentMenu.Enabled = RunToCursorButton.Enabled = enabled; NextButton.Enabled = NextMenu.Enabled = FinishButton.Enabled = FinishMenu.Enabled = enabled; RunToCursorMenu.Enabled = StepButton.Enabled = StepMenu.Enabled = enabled; if (state == DebuggerState.Running) { PanelsHelper.pluginUI.TreeControl.Clear(); PanelsHelper.stackframeUI.ClearItem(); } enabled = /*(state != DebuggerState.Running) &&*/ GetLanguageIsValid(); ToggleBreakPointMenu.Enabled = ToggleBreakPointEnableMenu.Enabled = enabled; DeleteAllBreakPointsMenu.Enabled = DisableAllBreakPointsMenu.Enabled = enabled; EnableAllBreakPointsMenu.Enabled = PanelsHelper.breakPointUI.Enabled = enabled; StartRemoteDebuggingMenu.Enabled = (state == DebuggerState.Initializing || state == DebuggerState.Stopped); PluginBase.MainForm.RefreshUI(); }
public void OnContinue( bool steppingForward ) { DummyDelegate del = delegate { if( steppingForward == false ) this.Code.Disable(); this.State = DebuggerState.Running; this.OnStateChanged(); }; this.View.Invoke( del ); }
public void RaiseUpdateDebugInformation(FrameRefresher activeFrameRefresher, FrameWrapper activeFrame, DebuggerState newState) { Activate(); if (UpdateDebugInformation != null) { UpdateDebugInformation(activeFrameRefresher, activeFrame); } ShowDebuggerState(DebugEventHandler.Instance.State); }
/// <summary> /// /// </summary> private void UpdateUI(DebuggerState state) { if ((PluginBase.MainForm as Form).InvokeRequired) { (PluginBase.MainForm as Form).BeginInvoke((MethodInvoker)delegate() { UpdateUI(state); }); return; } try { CurrentLocation = FlashInterface.getCurrentLocation(); UpdateStackUI(); UpdateLocalsUI(); UpdateMenuState(state); UpdateThreadsUI(); (PluginBase.MainForm as Form).Activate(); } catch (PlayerDebugException ex) { ErrorManager.ShowError("Internal Debugger Exception", ex); } }
/// <summary> /// Posts an Enter instruction to the island thread. /// Called by debugger manager thread /// </summary> internal void EnterState(DebuggerState state, IDictionary<string, object> locals) { _debugAction = DebugAction.Enter; _virtualStack.Push(new VirtualStackFrame(state, locals)); _workToDoEvent.Set(); // Block until Island executes NOP, // giving BPs a chance to be hit. // Must block here if the island is stopped at a breakpoint. _workDoneEvent.WaitOne(); }