module: access-path-implementation synopsis: Functions for debugee control author: Paul Howard Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND define constant $legal-application-states = #[#"running", #"unstarted", #"stopped", #"dead", #"post-mortem"]; define method set-application-state (ap :: , state :: ) if (member? (state, $legal-application-states)) ap.state := state; else error ("Attempted to set an illegal application state."); end if end method; ///// Generic functions. define generic restart (ap :: ) => (); define generic stop (ap :: ) => (); define generic continue (ap :: ) => (); define generic continue-unhandled (ap :: ) => (); define generic suspend-thread (ap :: , thread :: ) => (); define generic resume-thread (ap :: , thread :: ) => (); define generic step (ap :: , n :: ) => (); define generic step-over (ap :: , n :: ) => (); define generic step-out (ap :: ) => (); define generic application-state-running? (ap :: ) => (_ :: ); define generic application-state-stopped? (ap :: ) => (_ :: ); define generic application-state-unstarted? (ap :: ) => (_ :: ); define generic application-state-dead? (ap :: ) => (_ :: ); define generic application-state-post-mortem? (ap :: ) => (_ :: ); define generic kill-application (ap :: , #key do-cleanups? = #f) => (); ///// RESTART // This operation is always legal. define method restart (ap :: ) => () restart-application (ap.connection); set-application-state (ap, #"running"); end method; define method restart-application (conn :: ) => () reset-runtime(conn.process); end method; ///// STOP // This operation is only legal if the application is running. This performs // an immediate "stamp on the brakes". define method stop (ap :: ) => () if (application-state-running? (ap)) stop-application (ap.connection); set-application-state (ap, #"stopped"); else error ("Attempted to stop a non-running application."); end if end method; define method stop-application (conn :: ) => () end method; ///// CONTINUE define method continue (ap :: ) => () if (application-state-stopped? (ap)) continue-application (ap.connection); do-threads(method (t :: ) t.stack := #f end method, ap); set-application-state (ap, #"running"); else error ("Attempted to continue a non-stopped application."); end if end method; define method continue-application (conn :: ) => () end method; ///// CONTINUE-UNHANDLED define method continue-unhandled (ap :: ) => () if (application-state-stopped? (ap)) continue-application (ap.connection); do-threads(method (t :: ) t.stack := #f end method, ap); set-application-state (ap, #"running"); else error ("Attempted to continue a non-stopped application."); end if end method; ///// SUSPEND-THREAD define method suspend-thread (ap :: , thread :: ) => () if (~thread-suspended? (thread)) thread-suspended?(thread) := #t; thread-state(thread) := "Suspended by debugger"; suspend-application-thread (ap.connection, thread); end if end method; define method suspend-application-thread (conn :: , thread :: ) thread.nub-descriptor.suspend-count := thread.nub-descriptor.suspend-count - 1; end method; ///// RESUME-THREAD define method resume-thread (ap :: , thread :: ) => () if (thread-suspended? (thread)) thread-suspended?(thread) := #f; thread-state(thread) := "[Can't get thread state]"; resume-application-thread (ap.connection, thread); end if end method; define method resume-application-thread (conn :: , thread :: ) thread.nub-descriptor.suspend-count := thread.nub-descriptor.suspend-count + 1; end method; ///// STEP define method step (ap :: , n :: ) => () if (application-state-stopped? (ap)) step-application (ap.connection); set-application-state (ap, #"running"); else error ("Tried to step a non-stopped application."); end if end method; define method step-application (conn :: , n :: ) => () end method; ///// STEP-OVER define method step-over (ap :: , n :: ) => () if (application-state-stopped? (ap)) step-over-application (ap.connection, n); set-application-state (ap, #"running"); else error ("Tried to step a non-stopped application."); end if end method; define method step-over-application (conn :: , n :: ) => () end method; ///// STEP-OUT define method step-out (ap :: ) => () if (application-state-stopped? (ap)) step-out-application (ap.connection); set-application-state (ap, #"running"); else error ("Tried to step a non-stopped application."); end if end method; define method step-out-application (conn :: ) => () end method; ///// APPLICATION-STATE-...? define method application-state-running? (ap :: ) => (_ :: ) ap.state == #"running" end method; define method application-state-stopped? (ap :: ) => (_ :: ) ap.state == #"stopped" end method; define method application-state-unstarted? (ap :: ) => (_ :: ) ap.state == #"unstarted" end method; define method application-state-dead? (ap :: ) => (_ :: ) ap.state == #"dead" end method; define method application-state-post-mortem? (ap :: ) => (_ :: ) ap.state == #"post-mortem" end method;