Example #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");
     }
 }
Example #2
0
        private void InnerPause(HaltArguments haltArgs)
        {
            if(PauseEvent.WaitOne(0))
            {
                // cpu is already paused
                return;
            }

            lock(pauseLock)
            {
                PauseEvent.Set();
                TlibSetPaused();

                if(Thread.CurrentThread.ManagedThreadId != cpuThread.ManagedThreadId)
                {
                    this.NoisyLog("Waiting for thread to pause.");
                    sync.Pass();
                    cpuThread.Join();
                    this.NoisyLog("Paused.");
                    cpuThread = null;
                    TlibClearPaused();
                }
                else
                {
                    pauseGuard.OrderPause();
                }
            }

            InvokeHalted(haltArgs);
        }
Example #3
0
 private void InvokeHalted(HaltArguments arguments)
 {
     var halted = Halted;
     if(halted != null)
     {
         halted(arguments);
     }
 }
Example #4
0
        public void EnterSingleStepModeSafely(HaltArguments args)
        {
            // this method should only be called from CPU thread,
            // but we should check it anyway
            CheckCpuThreadId();

            TlibSetPaused();
            InvokeInCpuThreadSafely(() =>
            {
                ExecutionMode = ExecutionMode.SingleStep;
                TlibClearPaused();
                if(args != null)
                {
                    InvokeHalted(args);
                }
            });
        }