// Does the real work for an IL step. // fStepIn - true if step in; else false for step-over. // fVerbose - true if we should print out verbose diagnostic information. public static void ILStepWorker(bool stepIn, bool isVerbose, string args) { if ((args != null) && (args.Trim().Length > 0)) { throw new MDbgShellException("no arguments expected."); } // Do an IL-level step by single-stepping native code until our IL IP changes. MDbgProcess proc = GuiExtension.Shell.Debugger.Processes.Active; CorFrame curFrame = proc.Threads.Active.CurrentFrame.CorFrame; uint ipNative; uint offsetStart; uint offsetNew; ulong oldStackStart; ulong oldStackEnd; ulong newStackStart; ulong newStackEnd; CorDebugMappingResult result; curFrame.GetIP(out offsetStart, out result); curFrame.GetStackRange(out oldStackStart, out oldStackEnd); curFrame.GetNativeIP(out ipNative); if (isVerbose) { WriteOutput(String.Format(" IL step starting at offset IL_{0:x}, N=0x{1:x}, frame=({2:x},{3:x})", offsetStart, ipNative, oldStackStart, oldStackEnd)); } // We'll just do native single-steps until our IL ip changes. while (true) { // Single step native code. if (stepIn) { proc.StepInto(true).WaitOne(); } else { proc.StepOver(true).WaitOne(); } // Since we continued the process, our old frame becomes invalid and we need to get a new one. curFrame = proc.Threads.Active.CurrentFrame.CorFrame; curFrame.GetStackRange(out newStackStart, out newStackEnd); if ((newStackStart != oldStackStart) || (newStackEnd != oldStackEnd)) { // We're in a new frame. Maybe from step-in or step-out. if (isVerbose) { WriteOutput(String.Format(" IL step stopping at new frame =({0:x},{1:x})", newStackStart, newStackEnd)); } break; } curFrame.GetIP(out offsetNew, out result); curFrame.GetNativeIP(out ipNative); if ((offsetNew == offsetStart) && (proc.StopReason.GetType() == typeof(StepCompleteStopReason))) { if (isVerbose) { WriteOutput(String.Format(" IL step continuing. N=0x{0:x}", ipNative)); } continue; } if (isVerbose) { WriteOutput(String.Format(" IL step complete at IL_{0:x}", offsetNew)); } break; } }