/// <summary> /// Indexes the breakpoint hits. /// </summary> /// <param name="options">The options.</param> internal virtual void IndexBreakpointHits(IndexOptions options) { var end = GetEndingPosition(options); var start = GetStartingPosition(options); var curPos = TimeTravelFacade.SetPosition(start).ActualPosition; BreakpointFacade.ClearBreakpoints(); SetBreakpoints(options); while (curPos <= end) { DebugEngineProxy.RunUntilBreak(); curPos = TimeTravelFacade.GetCurrentPosition(); if (curPos <= end) UpsertCurrentPosition(options); for (int i = 0; i < options.Step; i++) { var newPosition = new Position(curPos.High, curPos.Low + 1); var posRes = TimeTravelFacade.SetPosition(newPosition); curPos = posRes.ActualPosition; if (posRes.BreakpointHit.HasValue) i = -1; if (curPos >= end) return; UpsertCurrentPosition(options); } } }
/// <summary> /// Gets the starting position. /// </summary> /// <param name="options">The options.</param> /// <returns>Position.</returns> /// <exception cref="FormatException"></exception> internal Position GetStartingPosition(IndexOptions options) { if (options == null || options.Start == null) { return(TimeTravelFacade.GetStartingPosition()); } return(options.Start); }
/// <summary> /// Gets the starting position. /// </summary> /// <param name="options">The options.</param> /// <returns>Position.</returns> /// <exception cref="FormatException"></exception> internal Position GetEndingPosition(IndexOptions options) { if (options == null || options.End == null) { return(TimeTravelFacade.GetEndingPosition()); } return(options.End); }
/// <summary> /// Processes the specified arguments. /// </summary> /// <param name="args">The arguments.</param> /// <returns>Task.</returns> public void Process(string[] args) { var options = ExtractOptions(args); var start = TimeTravelFacade.GetStartingPosition(); var end = TimeTravelFacade.GetEndingPosition(); ServerClient.InitializeProject(options.ProjectName, start, end); }
/// <summary> /// Creates the frames for upsert. /// </summary> /// <param name="positions">The positions.</param> /// <returns>List<Frame>.</returns> internal virtual List<Frame> CreateFramesForUpsert(PositionsResult positions) { var breakRecord = positions.CurrentThreadResult; var frames = positions .Where(positionRecord => positionRecord.Position == breakRecord.Position) .Select(positionRecord => TimeTravelFacade.GetCurrentFrame(positionRecord.ThreadId)) .ToList(); return frames; }
/// <summary> /// Creates the frames for upsert. /// </summary> /// <param name="positions">The positions.</param> /// <param name="breakRecord">The break record.</param> /// <param name="options">The options.</param> /// <returns>List<Frame>.</returns> internal List <Frame> CreateFramesForUpsert(PositionsResult positions, PositionsRecord breakRecord, IndexOptions options) { var frames = positions .Where(positionRecord => positionRecord.Position == breakRecord.Position) .Select(positionRecord => TimeTravelFacade.GetCurrentFrame(positionRecord.ThreadId)) .ToList(); return(frames); }
/// <summary> /// Indexes all positions in range. /// </summary> /// <param name="options">The options.</param> internal virtual void IndexAllPositionsInRange(IndexOptions options) { var end = GetEndingPosition(options); var start = GetStartingPosition(options); var curPos = TimeTravelFacade.SetPosition(start).ActualPosition; while (curPos <= end) { UpsertCurrentPosition(options); var nextPosition = new Position(curPos.High, curPos.Low + 1); curPos = TimeTravelFacade.SetPosition(nextPosition).ActualPosition; } }
/// <summary> /// Processes the internal. /// </summary> /// <param name="startingPosition">The starting position.</param> /// <param name="endingPosition">The ending position.</param> /// <param name="options">The options.</param> internal void ProcessInternal(Position startingPosition, Position endingPosition, IndexOptions options) { SetBreakpoints(options); TimeTravelFacade.SetPosition(startingPosition); // loop through all the set break points and record relevant values var frames = new List <Frame>(); Position last = null; /* * todo: PRIORITY FIX */ while (true) // todo: have better abstraction... while(!TimeTravelFacade.RunTo(endingPosition)) { DebugEngineProxy.RunUntilBreak(); var positions = TimeTravelFacade.Positions(); var breakRecord = positions.CurrentThreadResult; if (last == breakRecord.Position) { break; } var newFrames = CreateFramesForUpsert(positions, breakRecord, options); frames.AddRange(newFrames); foreach (var optionsMemoryRange in options?.MemoryRanges ?? new List <MemoryRange>()) { var bytes = DebugEngineProxy.ReadVirtualMemory(optionsMemoryRange); // todo: errors? ServerClient.AddMemoryRange(new MemoryChunk { MemoryRange = optionsMemoryRange, Bytes = bytes, Position = breakRecord.Position }); } last = breakRecord.Position; } try { ServerClient.UpsertFrames(frames); } catch (Exception e) { Log.Error($"Error persisting frames: {e.GetType().FullName} - {e.Message}"); DebugEngineProxy.WriteLine($"Error persisting frames: {e.GetType().FullName} - {e.Message}"); } }
/// <summary> /// Adds the tag. /// </summary> /// <param name="addOptions">The add options.</param> internal void AddTag(AddTagOptions addOptions) { var positions = TimeTravelFacade.Positions(); var current = positions.CurrentThreadResult; if (addOptions.IsAllThreadsAtPosition) // todo: extract methods { var threadIds = positions.Select(x => x.ThreadId); ServerClient.AddTag(current.Position, threadIds, addOptions.Text); } else { ServerClient.AddTag(current.Position, new[] { current.ThreadId }, addOptions.Text); } }
/// <summary> /// Upserts the current position. /// </summary> /// <param name="options">The options.</param> internal virtual void UpsertCurrentPosition(IndexOptions options) { var positions = TimeTravelFacade.Positions(); var frames = CreateFramesForUpsert(positions); ServerClient.UpsertFrames(frames); foreach (var optionsMemoryRange in options?.MemoryRanges ?? new List<MemoryRange>()) { var bytes = DebugEngineProxy.ReadVirtualMemory(optionsMemoryRange); // todo: errors? ServerClient.AddMemoryRange(new MemoryChunk { MemoryRange = optionsMemoryRange, Bytes = bytes, Position = positions.CurrentThreadResult.Position }); } }
/// <summary> /// Adds a tag. /// </summary> /// <param name="addOptions">The add options.</param> internal void AddTag(AddTagOptions addOptions) { var positions = TimeTravelFacade.Positions(); var current = positions.CurrentThreadResult; var tag = new Tag() { Title = addOptions.Title, Body = addOptions.Body, CreateDateUtc = DateTime.UtcNow }; if (addOptions.IsAllThreadsAtPosition) // todo: extract methods { var threadIds = positions.Select(x => x.ThreadId); ServerClient.AddTag(current.Position, threadIds, tag); } else { ServerClient.AddTag(current.Position, new[] { current.ThreadId }, tag); } }