/// <summary> /// Creates a default 'source level step' on process with current active frame and active thread. /// </summary> /// <param name="process">non-null process </param> /// <param name="type">type of step (in, out, over)</param> /// <param name="singleStepInstructions">false to step source level, true to step single instructions</param> /// <returns></returns> public static StepperDescriptor CreateSourceLevelStep(MDbgProcess process, StepperType type, bool singleStepInstructions) { StepperDescriptor s = new StepperDescriptor(process); s.StepperType = type; // // Handle Step-out case. // if (type == StepperType.Out) { return(s); } // // Handle step-over / step-in case // bool stepInto = (type == StepperType.In); // Cache current s.Thread = process.Threads.Active.CorThread; s.Frame = s.Thread.ActiveFrame; CorDebugMappingResult mappingResult; uint ip; if (!singleStepInstructions) { // For source-level stepping, skip some interceptors. These are random, and cause // random differences in stepping across different runtimes; and user generally don't care // about interceptors. // It's actually a debatable policy about which interceptors to skip and stop on. s.InterceptMask = CorDebugIntercept.INTERCEPT_ALL & ~(CorDebugIntercept.INTERCEPT_SECURITY | CorDebugIntercept.INTERCEPT_CLASS_INIT); } s.Frame.GetIP(out ip, out mappingResult); if (singleStepInstructions || (mappingResult != CorDebugMappingResult.MAPPING_EXACT && mappingResult != CorDebugMappingResult.MAPPING_APPROXIMATE)) { // Leave step ranges null } else { // Getting the step ranges is what really makes this a source-level step. MDbgFunction f = process.Modules.LookupFunction(s.Frame.Function); COR_DEBUG_STEP_RANGE[] sr = f.GetStepRangesFromIP((int)ip); if (sr != null) { s.SetStepRanges(sr, true); } else { // Leave step ranges null. } } return(s); }
/// <summary> /// Creates a default 'source level step' on process with current active frame and active thread. /// </summary> /// <param name="process">non-null process </param> /// <param name="type">type of step (in, out, over)</param> /// <param name="singleStepInstructions">false to step source level, true to step single instructions</param> /// <returns></returns> public static StepperDescriptor CreateSourceLevelStep(MDbgProcess process, StepperType type, bool singleStepInstructions) { StepperDescriptor s = new StepperDescriptor(process); s.StepperType = type; // // Handle Step-out case. // if (type == StepperType.Out) { return s; } // // Handle step-over / step-in case // bool stepInto = (type == StepperType.In); // Cache current s.Thread = process.Threads.Active.CorThread; s.Frame = s.Thread.ActiveFrame; CorDebugMappingResult mappingResult; uint ip; if (!singleStepInstructions) { // For source-level stepping, skip some interceptors. These are random, and cause // random differences in stepping across different runtimes; and user generally don't care // about interceptors. // It's actually a debatable policy about which interceptors to skip and stop on. s.InterceptMask = CorDebugIntercept.INTERCEPT_ALL & ~(CorDebugIntercept.INTERCEPT_SECURITY | CorDebugIntercept.INTERCEPT_CLASS_INIT); } s.Frame.GetIP(out ip, out mappingResult); if (singleStepInstructions || (mappingResult != CorDebugMappingResult.MAPPING_EXACT && mappingResult != CorDebugMappingResult.MAPPING_APPROXIMATE)) { // Leave step ranges null } else { // Getting the step ranges is what really makes this a source-level step. MDbgFunction f = process.Modules.LookupFunction(s.Frame.Function); COR_DEBUG_STEP_RANGE[] sr = f.GetStepRangesFromIP((int)ip); if (sr != null) { s.SetStepRanges(sr, true); } else { // Leave step ranges null. } } return s; }