@@ -565,52 +565,129 @@ if SERVER then
565565 -- Players and corresponding entities (for the debugger)
566566 CPULib .DebuggerData = {}
567567
568- ---- --------------------------------------------------------------------------
569- -- Attach a debugger
570- function CPULib .AttachDebugger (entity ,player )
571- if entity then
572- entity .BreakpointInstructions = {}
573- entity .OnBreakpointInstruction = function (IP )
574- CPULib .SendDebugData (entity .VM ,CPULib .DebuggerData [player :UserID ()].MemPointers ,player )
568+
569+ ---- ------------------------------------------------------------------
570+ -- Detach debugger
571+ function CPULib .DetachDebugger (player )
572+ if not IsValid (player ) then return end
573+
574+ local data = CPULib .DebuggerData [player :UserID ()]
575+ if not data then return end
576+
577+ local ent = data .Entity
578+ if IsValid (ent ) and ent .VM then
579+ ent .BreakpointInstructions = nil
580+ ent .OnBreakpointInstruction = nil
581+ ent .OnVMStep = nil
582+
583+
584+ if ent .VM .BaseJump then
585+ ent .VM .Jump = ent .VM .BaseJump
586+ ent .VM .BaseJump = nil
587+ end
588+
589+ if ent .VM .BaseInterrupt then
590+ ent .VM .Interrupt = ent .VM .BaseInterrupt
591+ ent .VM .BaseInterrupt = nil
575592 end
576- entity . OnVMStep = function ()
577- if CurTime () - CPULib . DebuggerData [ player : UserID ()]. PreviousUpdateTime > 0.2 then
578- CPULib . DebuggerData [ player : UserID ()]. PreviousUpdateTime = CurTime ()
579-
580- -- Send a fake update that messes up line pointer, updates registers
581- local tempIP = entity . VM . IP
582- entity . VM . IP = INVALID_BREAKPOINT_IP
583- CPULib . SendDebugData ( entity . VM , nil , player )
584- entity . VM . IP = tempIP
593+
594+ if ent . _CPULibDebuggerHooked then
595+ ent . _CPULibDebuggerHooked = nil
596+
597+ if ent . _CPULibOriginalOnRemove then
598+ ent . OnRemove = ent . _CPULibOriginalOnRemove
599+ ent . _CPULibOriginalOnRemove = nil
600+ else
601+ ent . OnRemove = nil
585602 end
586603 end
587- if not entity .VM .BaseJump then
588- entity .VM .BaseJump = entity .VM .Jump
589- entity .VM .Jump = function (VM ,IP ,CS )
590- VM :BaseJump (IP ,CS )
591- entity .ForceLastInstruction = true
604+ end
605+
606+ CPULib .DebuggerData [player :UserID ()] = nil
607+ end
608+
609+
610+ ---- ------------------------------------------------------------------
611+ -- Attach a debugger
612+ function CPULib .AttachDebugger (entity , player )
613+ if not IsValid (player ) then return end
614+
615+ -- DETACH PATH
616+ if not entity then
617+ CPULib .DetachDebugger (player )
618+ return
619+ end
620+
621+ if not IsValid (entity ) or not entity .VM then return end
622+
623+
624+ -- // detach any existing debugger first
625+ CPULib .DetachDebugger (player )
626+
627+
628+ if not entity ._CPULibDebuggerHooked then
629+ entity ._CPULibDebuggerHooked = true
630+
631+ entity ._CPULibOriginalOnRemove = entity .OnRemove
632+
633+ entity .OnRemove = function (ent )
634+ if entity ._CPULibOriginalOnRemove then
635+ entity ._CPULibOriginalOnRemove (ent )
592636 end
593- entity .VM .BaseInterrupt = entity .VM .Interrupt
594- entity .VM .Interrupt = function (VM ,interruptNo ,interruptParameter ,isExternal ,cascadeInterrupt )
595- VM :BaseInterrupt (interruptNo ,interruptParameter ,isExternal ,cascadeInterrupt )
596- if interruptNo < 27 then
597- CPULib .DebugLogInterrupt (player ,interruptNo ,interruptParameter ,isExternal ,cascadeInterrupt )
598- CPULib .SendDebugData (entity .VM ,CPULib .DebuggerData [player :UserID ()].MemPointers ,player )
599- end
637+
638+ if IsValid (player ) then
639+ if not CPULib .DebuggerData [player :UserID ()] then return end
640+
641+ CPULib .DetachDebugger (player )
642+
643+ net .Start (" CPULib.InvalidateDebugger" )
644+ net .WriteUInt (1 , 2 ) -- // 1 = detach
645+ net .Send (player )
600646 end
601647 end
602- else
603- if CPULib .DebuggerData [player :UserID ()] then
604- if CPULib .DebuggerData [player :UserID ()].Entity and
605- CPULib .DebuggerData [player :UserID ()].Entity .VM and
606- CPULib .DebuggerData [player :UserID ()].Entity .VM .BaseInterrupt then
607-
608- CPULib .DebuggerData [player :UserID ()].Entity .BreakpointInstructions = nil
609- if CPULib .DebuggerData [player :UserID ()].Entity .VM .BaseJump then
610- CPULib .DebuggerData [player :UserID ()].Entity .VM .Jump = CPULib .DebuggerData [player :UserID ()].Entity .VM .BaseJump
611- CPULib .DebuggerData [player :UserID ()].Entity .VM .Interrupt = CPULib .DebuggerData [player :UserID ()].Entity .VM .BaseInterrupt
612- CPULib .DebuggerData [player :UserID ()].Entity .VM .BaseJump = nil
613- CPULib .DebuggerData [player :UserID ()].Entity .VM .BaseInterrupt = nil
648+ end
649+
650+ entity .BreakpointInstructions = {}
651+
652+ entity .OnBreakpointInstruction = function (IP )
653+ local data = CPULib .DebuggerData [player :UserID ()]
654+ if not data then return end
655+
656+ CPULib .SendDebugData (entity .VM , data .MemPointers , player )
657+ end
658+
659+ entity .OnVMStep = function ()
660+ local data = CPULib .DebuggerData [player :UserID ()]
661+ if not data then return end
662+
663+ if CurTime () - data .PreviousUpdateTime > 0.2 then
664+ data .PreviousUpdateTime = CurTime ()
665+
666+ -- Send a fake update that messes up line pointer, updates registers
667+ local tempIP = entity .VM .IP
668+ entity .VM .IP = INVALID_BREAKPOINT_IP
669+ CPULib .SendDebugData (entity .VM , nil , player )
670+ entity .VM .IP = tempIP
671+ end
672+ end
673+
674+ if not entity .VM .BaseJump then
675+ entity .VM .BaseJump = entity .VM .Jump
676+ entity .VM .Jump = function (VM , IP , CS )
677+ VM :BaseJump (IP , CS )
678+ entity .ForceLastInstruction = true
679+ end
680+
681+ entity .VM .BaseInterrupt = entity .VM .Interrupt
682+ entity .VM .Interrupt = function (VM , interruptNo , interruptParameter , isExternal , cascadeInterrupt )
683+ VM :BaseInterrupt (interruptNo , interruptParameter , isExternal , cascadeInterrupt )
684+
685+ if interruptNo < 27 then
686+ CPULib .DebugLogInterrupt (player , interruptNo , interruptParameter , isExternal , cascadeInterrupt )
687+
688+ local data = CPULib .DebuggerData [player :UserID ()]
689+ if data then
690+ CPULib .SendDebugData (entity .VM , data .MemPointers , player )
614691 end
615692 end
616693 end
@@ -624,6 +701,7 @@ if SERVER then
624701 }
625702 end
626703
704+
627705 -- Log debug interrupt
628706 function CPULib .DebugLogInterrupt (player ,interruptNo ,interruptParameter ,isExternal ,cascadeInterrupt )
629707 local umsgrp = RecipientFilter ()
0 commit comments