private void OnHalted(HaltArguments args) { switch (args.Reason) { case HaltReason.Breakpoint: switch (args.BreakpointType) { case BreakpointType.AccessWatchpoint: case BreakpointType.WriteWatchpoint: case BreakpointType.ReadWatchpoint: beforeCommand += cmd => { commandsCounter++; if (commandsCounter > 15) { // this is a hack! // I noticed that GDB will send `step` command after receiving // information about watchpoint being hit. // As a result cpu would execute next instruction and stop again. // To prevent this situation we wait for `step` and ignore it, but // only in small time window (15 - instructions, value choosen at random) // and only after sending watchpoint-related stop reply. this.Log(LogLevel.Error, "Expected step command after watchpoint. Further debugging might not work properly"); beforeCommand = null; commandsCounter = 0; return(false); } if ((cmd is SingleStepCommand)) { SendPacket(new Packet(PacketData.StopReply(TrapSignal))); beforeCommand = null; commandsCounter = 0; return(true); } return(false); }; goto case BreakpointType.HardwareBreakpoint; case BreakpointType.HardwareBreakpoint: case BreakpointType.MemoryBreakpoint: SendPacket(new Packet(PacketData.StopReply(args.BreakpointType.Value, args.Address))); break; } return; case HaltReason.Step: case HaltReason.Pause: SendPacket(new Packet(PacketData.StopReply(TrapSignal))); return; case HaltReason.Abort: SendPacket(new Packet(PacketData.AbortReply(AbortSignal))); return; default: throw new ArgumentException("Unexpected halt reason"); } }