Пример #1
0
        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");
            }
        }
Пример #2
0
        private void OnHalted(HaltArguments args)
        {
            using (var ctx = commHandler.OpenContext())
            {
                // GDB counts threads starting from `1`, while Renode counts them from `0` - hence the incrementation
                var cpuId = args.CpuId + 1;
                switch (args.Reason)
                {
                case HaltReason.Breakpoint:
                    switch (args.BreakpointType)
                    {
                    case BreakpointType.AccessWatchpoint:
                    case BreakpointType.WriteWatchpoint:
                    case BreakpointType.ReadWatchpoint:
                    case BreakpointType.HardwareBreakpoint:
                    case BreakpointType.MemoryBreakpoint:
                        foreach (var cpu in commandsManager.ManagedCpus.Values)
                        {
                            cpu.IsHalted = true;
                        }
                        if (commandsManager.Machine.SystemBus.IsMultiCore)
                        {
                            commandsManager.SelectCpuForDebugging(cpuId);
                            ctx.Send(new Packet(PacketData.StopReply(args.BreakpointType.Value, cpuId, args.Address)));
                        }
                        else
                        {
                            ctx.Send(new Packet(PacketData.StopReply(args.BreakpointType.Value, args.Address)));
                        }
                        break;
                    }
                    return;

                case HaltReason.Step:
                case HaltReason.Pause:
                    if (commandsManager.Machine.SystemBus.IsMultiCore)
                    {
                        commandsManager.SelectCpuForDebugging(cpuId);
                        ctx.Send(new Packet(PacketData.StopReply(TrapSignal, cpuId)));
                    }
                    else
                    {
                        ctx.Send(new Packet(PacketData.StopReply(TrapSignal)));
                    }
                    return;

                case HaltReason.Abort:
                    ctx.Send(new Packet(PacketData.AbortReply(AbortSignal)));
                    return;

                default:
                    throw new ArgumentException("Unexpected halt reason");
                }
            }
        }