**************************** The DEBUGGER-MANAGER library **************************** .. current-library:: debugger-manager .. current-module:: debugger-manager The original version of this document was written by Paul Howard and Tony Mann in March 1997. Introduction ============ The Debugger Manager (DM) is quite a high-level component of the debugger architecture. It sits between the access path interface and the debugger UI. The DM provides abstractions over the debug operations described by the access path interface, as well as providing dylan-specific debugging functionality. .. glossary:: DM Debugger Manager. The component of the debugger described by this document. RTM Runtime Manager. The DM in conjunction with other internal support for the tether/interactivity: the access-path and interactive downloader. UI User Interface (of the debugging tool). Client of the DM. DevelDBG A simple Dylan debugger with a command-line interface. Some implementation details of DevelDBG require specific functionality from the Debugger Manager. These have been kept to a minimum and are flagged in this document by "DevelDBG only". For DevelDBG, the debugger UI will probably import most of the access path functionality as well as debugger manager functionality. It is doubtful that this model will be adopted for the final debugger. Certainly _some_ access path definitions will need to be exposed (stop-reasons being a good example), but exposing application control functions like "stop" and "continue" potentially allows the UI to interfere with the DM's management of the running app. Model of the Debugger Manager ============================= The general model of the debugging tool can be reduced to two concurrent loops: a loop processing user input in the UI, and a loop receiving stop reasons from the running application. The DM takes charge of the latter, but synchronizes with the UI by operating a callback system, calling on UI routines when important events are received from the running application. Callbacks are invoked under the following circumstances: #. The application stopped because a debug event or exception occurred (an "internal" stop), or because some event in the debugger UI signaled that the application should stop (an "external" stop). #. The application hit a breakpoint/watchpoint. At the low level, a breakpoint/watchpoint hit is just another variety of internal stop. However, the DM provides a separate mechanism of callbacks for them, since they are the vehicle for many higher-level debugging facilities such as tracing. #. The application is ready to continue. This means that the application had previously stopped for some reason (which may have involved the invocation of other callbacks), but the DM is now capable of allowing it to resume. The following sections describe how and when these callbacks are registered, and the precise form they must take. Debug Targets ============= A "debug target" represents whatever is being debugged. In most cases, this will be a newly created application. Basically, a debug target is very similar to an access path, and has a one-to-one correspondence with an :class:`` instance. The main difference is that the :class:`` is a sealed description of the connection to the debugger nub, whereas the :class:`` can be subclassed to hold any information that clients of the DM wish to store. .. class:: :open: :abstract: :superclasses: :drm:`` :keyword application-object: An instance of :drm:``. :keyword compilation-context: An instance of :drm:``. :keyword top-level-component-name: An instance of :drm:``, or ``#f``. Describes an application being debugged. Users of the DM are allowed to create appropriate concrete subclasses of :class:`` with slots specific to their own purposes. It is always possible to map between a and its corresponding :class:``. When a :class:`` is made, an :class:`` of the appropriate type is made automatically. The DM will also install the :class:`` as the :func:`access-path-abstract-handle` slot of the access path. This class is specified to take the same init-keywords as :class:``. (They will just be passed on when the :class:`` instance is made.) Example: .. code-block:: dylan define class () end class; define variable my-app = make (, application: "spam", arguments: "spam"); .. generic-function:: debug-target-access-path :signature: debug-target-access-path (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :class:``. It's not clear that we need to export this function at all from the DM. (Exporting it is advantageous for DevelDBG since it allows us to use all the access-path functionality as well, such as :func:`access-path-arguments`). See the note in the `Introduction`_. .. generic-function:: debug-target-symbol-table :signature: debug-target-symbol-table (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :class:``. .. generic-function:: debug-target-compilation-context :signature: debug-target-compilation-context (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :drm:``. .. generic-function:: debug-target-compilation-context-setter :signature: debug-target-compilation-context-setter (value object) => (value) :parameter value: An instance of :drm:``. :parameter object: An instance of :class:``. :value value: An instance of :drm:``. .. generic-function:: find-library-called :signature: find-library-called (application core-name) => (maybe-lib) :parameter application: An instance of :class:``. :parameter core-name: An instance of :drm:``. :value maybe-lib: An instance of :class:``. Attempts to find a :class:`` whose name matches the supplied string. Returns ``#f`` if no matching library is found. .. generic-function:: obtain-component-name :open: :signature: obtain-component-name (application libname) => (name) :parameter application: An instance of :class:``. :parameter libname: An instance of :drm:``. :value name: An instance of :drm:``. A name context contains the name of a dylan library. Often, this needs to be mapped to the name of a shared object (or DLL), which should be performed via this function. .. method:: obtain-component-name :specializer: , .. class:: :superclasses: :class:`` :keyword required application-state: An instance of :drm:``. :keyword required result-spec: An instance of :drm:``. .. generic-function:: interaction-request-application-state :open: :signature: interaction-request-application-state (interaction-transaction-id) => (application-state) :parameter interaction-transaction-id: An instance of :drm:``. :value application-state: An instance of :drm:``. .. method:: interaction-request-application-state :specializer: .. generic-function:: interaction-request-application-state-setter :open: :signature: interaction-request-application-state-setter (application-state interaction-transaction-id) => (application-state) :parameter application-state: An instance of :drm:``. :parameter interaction-transaction-id: An instance of :drm:``. :value application-state: An instance of :drm:``. .. method:: interaction-request-application-state-setter :specializer: , Debugger Transaction Caching Utilities ====================================== .. class:: :open: :abstract: :superclasses: :drm:`` :keyword required debug-target: An instance of :class:``. A class used to store remote dylan objects in fast-lookup form. The values in the table can be arbitrary information that needs to be obtained from the key. .. class:: :open: :abstract: :superclasses: :drm:`` .. generic-function:: add-object :open: :signature: add-object (table instance entry) => () :parameter table: An instance of :class:``. :parameter instance: An instance of :const:``. :parameter entry: An instance of :class:``. .. method:: add-object :specializer: , , .. generic-function:: enquire-object :open: :signature: enquire-object (table instance) => (entry) :parameter table: An instance of :class:``. :parameter instance: An instance of :const:``. :value entry: An instance of :class:``, or ``#f``. Checks to see whether a dylan object is present in a table. If so, returns the description that was supplied to :func:`add-object` when the object was put into the table, otherwise returns ``#f``. .. method:: enquire-object :specializer: , .. generic-function:: remove-object :open: :signature: remove-object (table instance) => () :parameter table: An instance of :class:``. :parameter instance: An instance of :const:``. .. method:: remove-object :specializer: , .. generic-function:: invalidate-page-relative-object-table :open: :signature: invalidate-page-relative-object-table (table) => () :parameter table: An instance of :class:``. .. method:: invalidate-page-relative-object-table :specializer: Stop Reasons ============ The :lib:`access-path` library exports the open abstract class :class:`` (as a subclass of :class:``). The DM expands on this open branch of the hierarchy. .. generic-function:: stop-reason-debug-points :signature: stop-reason-debug-points (application sr) => (interested-debug-points) :parameter application: An instance of :class:``. :parameter sr: An instance of :class:``. :value interested-debug-points: An instance of :drm:``. Returns the sequence of :class:`` objects that caused the stop reason. The sequence will only contain those debug-points whose callbacks returned ``#t`` (see `Registering Debug Points`_). .. class:: :open: :abstract: :superclasses: :class:`` :keyword client-data: An instance of :drm:``. A subclass of :class:``. A stop reason indicating that the application was stopped by some action on the part of the UI. .. generic-function:: stop-reason-client-data :signature: stop-reason-client-data (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :drm:``. .. class:: :superclasses: :class:`` A subclass of :class:``. The stop reason generated when the UI calls :func:`stop-application` (see `Managing Application Control`_) for some reason. The access-path also supports an open subclass of :class:`` called :class:``. This is so that the DM can, having examined the dynamic state of the application, present more informative stop-reasons. Here are the subclasses defined by the DM, along with various specific accessors. .. class:: :superclasses: :class:`` A subclass of :class:``. A stop-reason indicating that an unhandled Dylan condition resulted in a Dylan-level invocation of the debugger. .. generic-function:: dylan-error-message-string :signature: dylan-error-message-string (sr) => (str) :parameter sr: An instance of :class:``. :value str: An instance of :drm:``. Returns the error message that resulted in the condition. .. class:: :superclasses: :class:`` A subclass of :class:``. A stop-reason indicating that the application called a dylan-level debug utility to generate a formatted debugging message. .. generic-function:: dylan-debug-message-string :signature: dylan-debug-message-string (sr) => (str) :parameter sr: An instance of :class:``. :value str: An instance of :drm:``. Builds up and returns the formatted string that was generated by the :func:`debug-message` call. .. class:: :superclasses: :class:`` .. class:: :superclasses: :class:`` :keyword required transaction-id: An instance of :drm:``. A subclass of . A stop-reason indicating that the execution of an interactive form has just returned, and that its results are available. .. class:: :superclasses: :class:`` :keyword required name: An instance of :drm:``. .. generic-function:: interactive-thread-name :signature: interactive-thread-name (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :drm:``. .. generic-function:: interactor-transaction-id :signature: interactor-transaction-id (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :drm:``. All interactive evaluations have a transaction-id associated with them. This accessor returns the id that was associated with the evaluation that just returned, generating the stop reason. This transaction-id will be :func:`\==` to the transaction-id that was returned when the interactor called execute-source (see gz's CSI document). .. generic-function:: interactor-return-values :signature: interactor-return-values (sr) => (vals) :parameter sr: An instance of :class:``. :value vals: An instance of :drm:``. Returns a vector of :type:``\ s corresponding to the sequence of return values generated by the interactive evaluation. .. generic-function:: setup-interactor :signature: setup-interactor (application thread symbolic-c-entry-point symbolic-dll return-spec #rest args) => (transaction-id) :parameter application: An instance of :class:``. :parameter thread: An instance of :class:``. :parameter symbolic-c-entry-point: An instance of :drm:``. :parameter symbolic-dll: An instance of :drm:``, or ``#f``. :parameter return-spec: An instance of :drm:``. :parameter #rest args: An instance of :drm:``. :value transaction-id: An instance of :drm:``. .. generic-function:: handle-interactor-return :open: :signature: handle-interactor-return (application thread transaction-id #rest return-values) => (stop?) :parameter application: An instance of :class:``. :parameter thread: An instance of :class:``. :parameter transaction-id: An instance of :drm:``. :parameter #rest return-values: An instance of :drm:``. :value stop?: An instance of :drm:``. .. method:: handle-interactor-return :specializer: , , .. class:: :superclasses: :class:`` :keyword required class: An instance of :const:``. :keyword required size: An instance of :drm:``. .. generic-function:: class-breakpoint-class :signature: class-breakpoint-class (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :const:``. .. generic-function:: class-breakpoint-size :signature: class-breakpoint-size (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :drm:``. Managing Application Control ============================ The DM takes responsibility for most aspects of application control. There are no explicit functions to wait for stop-reasons or to continue execution — the DM performs these tasks on demand during an indefinite loop. Within this loop, the DM invokes various callbacks that can be registered by the UI. .. generic-function:: stop-application :signature: stop-application (application #key stop-reason) => () :parameter application: An instance of :class:``. :parameter #key stop-reason: An instance of :drm:``. Suspends the application with immediate effect. .. generic-function:: kill-application :signature: kill-application (application) => () :parameter application: An instance of :class:``. Terminates the application regardless of its state. .. generic-function:: restart-application :signature: restart-application (application) => () :parameter application: An instance of :class:``. Restarts the application from the beginning. .. generic-function:: manage-running-application :signature: manage-running-application (application #key stop-reason-callback poll-for-stop-callback ready-to-continue-callback) => () :parameter application: An instance of :class:``. :parameter #key stop-reason-callback: An instance of :drm:``. :parameter #key poll-for-stop-callback: An instance of :drm:``. :parameter #key ready-to-continue-callback: An instance of :drm:``. Starts up the application via its access path and enters an indefinite loop. Within this loop, the DM receives stop-reasons through the access-path and invokes the appropriate registered callback. This function does not return until the running application exits or is killed. A number of callbacks can be specified up-front as keyword parameters. The UI will almost certainly want to specify all of these, though defaults are provided. ``stop-reason-callback`` A function of two arguments, a :class:`` and a :class:``, which returns a boolean. The DM invokes this callback whenever a stop-reason is received from the application. Note that breakpoint exceptions are a special case (see `Registering Debug Points`_). If the callback returns ``#f``, the application is silently resumed. If it returns true, the application remains suspended, and the ``ready-to-continue-callback`` is invoked with an instance of . The return value of true, therefore, indicates an "interest" in this stop reason, whereas ``#f`` effectively filters it out. The application is known to be frozen during the entire execution of this callback. ``poll-for-stop-callback`` A function of one argument, a :class:``. In a single-threaded environment (which DevelDBG is), this function is needed to give the UI a chance to stop the application. The DevelDBG UI, for instance, has a "stop button" whose status can be checked during this periodic callback. During execution of this callback, the UI may call :func:`stop-application`. This will result in the ``ready-to-continue-callback`` being invoked with an instance of :class:``. But note that this will not happen until the ``poll-for-stop-callback`` returns. The DM undertakes to call this function at frequent intervals. The default callback does nothing (and hence does *not* call stop-application). For a multi-threaded GUI debugging tool, this callback will not be required. The application may be running during the execution of this callback. ``ready-to-continue-callback`` A function of two arguments, a :class:`` and a :class:``. This callback is invoked whenever the debugger manager is ready to continue the application. If the application stopped of its own accord (an internal stop), then other callbacks will already have had the chance to do their own processing (such as the handling of debug-points). Reaching the ``ready-to-continue-callback`` means that *all* of this processing has been done, but the internal stop was still interesting enough for control to be passed to the UI before continuing. This callback may call the function :func:`kill-application`. In this case, the application will no longer be running, and :func:`manage-running-application` will return. This callback may also call the function :func:`restart-application`, in which case the app will be re-run from the beginning, but will continue to be managed in the same loop. (That is, :func:`manage-running-application` will not return). If the callback returns without having called :func:`kill-application` or :func:`restart-application`, the application will be resumed from the point where it stopped. The default callback does nothing. The application is known to be frozen during the entire execution of this callback. In a multi-threaded UI environment, this callback will probably block on some resource which can be freed by a "continue" gesture in the GUI. .. generic-function:: application-stopped? :signature: application-stopped? (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :drm:``. .. generic-function:: application-stopped?-setter :signature: application-stopped?-setter (value object) => (value) :parameter value: An instance of :drm:``. :parameter object: An instance of :class:``. :value value: An instance of :drm:``. Registering Debug Points ======================== The DM allows any number of debug points to be positioned on any one address (obviously, the first such debug point results in actually setting a breakpoint or watchpoint in the application, but the DM takes care of this implicitly). In the DM, a debug point is described by an address paired with a callback. Debug Point callbacks take three arguments, a :class:``, a :class:``, and a :class:`` (the thread that signaled the debug point exception), and return a boolean. A true return value indicates that the application should stop as a result of this debug point (ie, the UI is interested in it, given the current context). ``#f`` implies that the callback has done all of the necessary processing and the application may continue. Debug point callbacks have slightly different semantics than those callbacks described thus far. They are not functions that are immediately called when a debug-point is encountered. Instead, they are functions which *can* be called if the context is relevant. This is further described below. .. class:: :open: :abstract: :superclasses: :class:`` :keyword required address: An instance of :const:``. :keyword required callback: An instance of :drm:``. This is NOT the same as :class:`` as defined in the :lib:`access-path` library. Requires the following init-keywords: ``address:`` A :type:`` — the location at which this debug point is to be registered. ``callback:`` A :drm:`` — the callback to be invoked when the debug-point is hit. Should accept a :class:``, a :class:`` and a :class:`` as arguments, and return a boolean (as described above). Note that the DM does not *directly* invoke this callback. Instead, it calls the open generic function :func:`handle-debug-point-event` (see below), which may or may not subsequently invoke the callback. .. class:: :open: :abstract: :superclasses: :class:`` .. class:: :open: :abstract: :superclasses: :class:`` .. class:: :abstract: :instantiable: :superclasses: :class:`` All debug-points to do with function tracing are a subclass of :class:``. Calling :drm:`make` on this class returns an instance of :class:``. .. class:: :open: :abstract: :superclasses: :class:`` :keyword required return-callback: An instance of :class:``. This requires a further init-keyword ``return-callback:`` (of the same specification as the ``callback:`` keyword argument). The default :gf:`handle-debug-point-event` method for :class:`` calls the registered callback as well as setting a :class:`` on the return address via a protocol described below. This :class:`` will have, as its registered callback, the function that was supplied as the return-callback. Entry tracepoints can only be set at the very start of functions. The DM will refuse to register an :class:`` whose ``address:`` keyword does not correspond to the first address of a function definition. A :class:`` will be signaled if this condition is not met. (Maybe another error class should be defined for this specific case...?) Valid addresses are therefore those which are known in advance to be the addresses of functions. Addresses obtained via :func:`dylan-method-iep`, for example, will be valid. The address of a :class:`` will only be valid if the symbol denotes a function. .. class:: :open: :abstract: :instantiable: :superclasses: :class:`` :keyword required entry: An instance of :class:``. :keyword required frame: An instance of :const:``. :keyword required thread: An instance of :class:``. It is not intended that clients of the DM should create and register objects except via the special mechanism that the DM provides (see the functions below). The default :gf:`handle-debug-point-event` method for :class:`` will invoke the registered callback if (and only if) the thread and stack contexts are the same as when the corresponding :class:`` was encountered. In this case, the :class:`` will also deregister itself. .. generic-function:: make-return-tracepoint :open: :signature: make-return-tracepoint (app bp thr #rest keys #key #all-keys) => (return-point) :parameter app: An instance of :class:``. :parameter bp: An instance of :class:``. :parameter thr: An instance of :class:``. :parameter #rest keys: An instance of :drm:``. :value return-point: An instance of :class:``. When the DM encounters a debug-point of type :class:``, there is the need to set a :class:`` on the corresponding return address. The DM calls this open generic function in order to create it. This is required since :class:`` is an open class. The default method simply returns an instance of :class:``. .. method:: make-return-tracepoint :specializer: , , .. method:: make-return-tracepoint :specializer: , , .. generic-function:: initialize-return-tracepoint :open: :signature: initialize-return-tracepoint (app bp thr #key #all-keys) => () :parameter app: An instance of :class:``. :parameter bp: An instance of :class:``. :parameter thr: An instance of :class:``. After calling :gf:`make-return-tracepoint`, the DM also calls this open generic function with the newly created return-tracepoint. This allows the client to perform any other specialized initialization behaviour. The default method actually registers the return-tracepoint, so clients defining methods on this function should make sure that they call ``next-method()`` at some point. .. method:: initialize-return-tracepoint :specializer: , , .. generic-function:: corresponding-entry-tracepoint :signature: corresponding-entry-tracepoint (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :class:``. Given a return-tracepoint, returns the registered entry-tracepoint that created it. .. generic-function:: dylan-trace-entry-arguments :signature: dylan-trace-entry-arguments (application thread function-signature) => (required-arguments rest-vector keyword-arguments) :parameter application: An instance of :class:``. :parameter thread: An instance of :class:``. :parameter function-signature: An instance of :const:``. :value required-arguments: An instance of :drm:``. :value rest-vector: An instance of :class:``, or ``#f``. :value keyword-arguments: An instance of :drm:``, or ``#f``. .. generic-function:: dylan-trace-return-values :signature: dylan-trace-return-values (application thread) => (return-vals) :parameter application: An instance of :class:``. :parameter thread: An instance of :class:``. :value return-vals: An instance of :drm:``. .. generic-function:: handle-debug-point-event :open: :signature: handle-debug-point-event (application debug-point thr) => (register-interest?) :parameter application: An instance of :class:``. :parameter debug-point: An instance of :class:``. :parameter thr: An instance of :class:``. :value register-interest?: An instance of :drm:``. When a debug-point is encountered at address X, the DM selects all debug-points that were registered at X and calls this GF with each debug-point in turn. If any one of these calls returns true, the application will remain suspended, and the ``ready-to-continue-callback`` will be invoked with a :class:``. If *all* calls return ``#f``, the application will be silently allowed to continue. Note that a true return value does not short-circuit this process — all selected debug-points still get handled. Clients of the DM can add methods to this function to specialize the behaviour of their own debug-point subclasses. The default method on this GF just invokes the registered callback for this debug-point, passing it the same arguments, and returning its return value. This default behaviour can be reached by calls to ``next-method()``. Example: .. code-block:: dylan define class () end class; ... define method handle-debug-point-event (app :: , x :: , t :: ) => (_ :: ) if (wind-blowing-in-the-right-direction()) #f // Don't invoke the registered callback, and // don't signal any interest in this breakpoint. else next-method() end if end method; .. generic-function:: register-debug-point :signature: register-debug-point (application debug-point) => () :parameter application: An instance of :class:``. :parameter debug-point: An instance of :class:``. Registers the :class:`` with the DM. It is added to any others that have already been registered at the same address. (If there are no others, then this call will actually set a low-level breakpoint). .. generic-function:: deregister-debug-point :signature: deregister-debug-point (application debug-point) => () :parameter application: An instance of :class:``. :parameter debug-point: An instance of :class:``. De-registers the :class:``. .. class:: :superclasses: :drm:`` A condition of this type will be signaled by :func:`register-debug-point` or :func:`deregister-debug-point` if either operation fails for some reason. This might occur, for example, if an address in the application's code was not mapped and so a breakpoint instruction could not be poked in. .. generic-function:: application-running-on-code-entry? :signature: application-running-on-code-entry? (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :drm:``. .. generic-function:: application-running-on-code-entry?-setter :signature: application-running-on-code-entry?-setter (value object) => (value) :parameter value: An instance of :drm:``. :parameter object: An instance of :class:``. :value value: An instance of :drm:``. .. generic-function:: application-just-interacted? :signature: application-just-interacted? (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :drm:``. .. generic-function:: application-just-interacted?-setter :signature: application-just-interacted?-setter (value object) => (value) :parameter value: An instance of :drm:``. :parameter object: An instance of :class:``. :value value: An instance of :drm:``. .. generic-function:: interactor-deferred-id-table :signature: interactor-deferred-id-table (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :class:``. Example - simple function tracing --------------------------------- .. code-block:: dylan define class () slot traced-function :: , required-init-keyword: symbol:; end class; define class () slot traced-function :: , required-init-keyword: symbol:; end class; define method print-entry-data (app :: , bp :: , thr :: ) => (_ :: ) format-out ("Entered %s in thread %s\n", bp.traced-function.remote-symbol-name, thr.thread-name); #f; end method; define method print-return-data (app :: , bp :: , thr :: ) => (_ :: ) format-out ("Returned from %s in thread %s\n", bp.traced-function.remote-symbol-name, thr.thread-name); #f; end method; define method make-return-tracepoint (app :: , bp :: , thr :: , #rest keys, #key, #all-keys) => (_ :: ) apply (make, , symbol: bp.traced-function, keys) end method; // Just for completeness of the example... define method initialize-return-tracepoint (app :: , bp :: , thr :: , #key) => () next-method () end method; . . . register-debug-point (my-application, make (, address: some-remote-value, symbol: some-remote-symbol, callback: print-entry-data, return-callback: print-return-data)) . . Dylan Name Context ================== In order to resolve Dylan names, they need to be mangled by the debugger in the same way that they were mangled by the compiler. In order to do this, the debugger must know the "context" (the library name and module name) to mangle into. For example, if the context specifies the dylan library and the internal module, then `*pants*` mangles to ``TpantsTYinternalVdylan``. .. class:: :superclasses: :drm:`` :keyword library: An instance of :drm:``. :keyword module: An instance of :drm:``. Specifies a context for name mangling. Calling make on this class returns a context specifying the dylan library and the internal module, but these can be overridden by supplying keyword arguments ``library:`` and ``module:``, both with strings. .. generic-function:: context-library :signature: context-library (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :drm:``. Returns the name of the library in this context as a string. .. generic-function:: context-library-setter :signature: context-library-setter (value object) => (value) :parameter value: An instance of :drm:``. :parameter object: An instance of :class:``. :value value: An instance of :drm:``. Sets the name of the library for this context. .. generic-function:: context-module :signature: context-module (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :drm:``. Returns the name of the module in this context. .. generic-function:: context-module-setter :signature: context-module-setter (value object) => (value) :parameter value: An instance of :drm:``. :parameter object: An instance of :class:``. :value value: An instance of :drm:``. Sets the name of the module for this context. .. generic-function:: demangle-dylan-name :signature: demangle-dylan-name (full-mangled-name) => (name-part module-part library-part method-name? method-iep? method-library-part method-number-part) :parameter full-mangled-name: An instance of :drm:``. :value name-part: An instance of :drm:``. :value module-part: An instance of :drm:``. :value library-part: An instance of :drm:``. :value method-name?: An instance of :drm:``. :value method-iep?: An instance of :drm:``. :value method-library-part: An instance of :drm:``, or ``#f``. :value method-number-part: An instance of :drm:``, or ``#f``. .. generic-function:: demangle-local-dylan-name :signature: demangle-local-dylan-name (full-mangled-name) => (demang) :parameter full-mangled-name: An instance of :drm:``. :value demang: An instance of :drm:``. .. generic-function:: mangle-local-dylan-name :signature: mangle-local-dylan-name (s) => (mangled) :parameter s: An instance of :drm:``. :value mangled: An instance of :drm:``. .. generic-function:: mangle-in-context :signature: mangle-in-context (s cxt #key as-wrapper? as-static-object? as-entry-point?) => (mangled) :parameter s: An instance of :drm:``. :parameter cxt: An instance of :class:``. :parameter #key as-wrapper?: An instance of :drm:``. :parameter #key as-static-object?: An instance of :drm:``. :parameter #key as-entry-point?: An instance of :drm:``. :value mangled: An instance of :drm:``. Transactions on dylan values ============================ .. generic-function:: read-dylan-value :signature: read-dylan-value (ap address) => (v ok) :parameter ap: An instance of :class:``. :parameter address: An instance of :const:``. :value v: An instance of :const:``. :value ok: An instance of :drm:``. .. generic-function:: write-dylan-value :signature: write-dylan-value (ap address value) => (v ok) :parameter ap: An instance of :class:``. :parameter address: An instance of :const:``. :parameter value: An instance of :const:``. :value v: An instance of :const:``. :value ok: An instance of :drm:``. .. generic-function:: read-instance-slot-element :signature: read-instance-slot-element (ap object i) => (v ok) :parameter ap: An instance of :class:``. :parameter object: An instance of :const:``. :parameter i: An instance of :drm:``. :value v: An instance of :const:``. :value ok: An instance of :drm:``. Printing and Inspecting Dylan Objects ===================================== .. generic-function:: print-dylan-object :signature: print-dylan-object (application instance #key length level decorate? format) => (rep) :parameter application: An instance of :class:``. :parameter instance: An instance of :const:``. :parameter #key length: An instance of :drm:``. :parameter #key level: An instance of :drm:``. :parameter #key decorate?: An instance of :drm:``. :parameter #key format: An instance of :drm:``, or ``#f``. :value rep: An instance of :drm:``. Attempts to interpret the remote-value as a dylan object and generates a string representation of it. Immediates and "standard" objects (such as strings and simple-object-vectors) will be given direct representations. General instances might just be represented as `[]`. The DM will have special knowledge of (possibly a subset of) condition objects, and will print their formatted messages if possible. Printable representations of collection objects (and other instances whose representations are structured) can expand to an inappropriately large size unless some limitations are specified. If ``length:`` is supplied, it should be an integer specifying the maximum number of components that should be printed for structured instances. (For example, the maximum number of elements of a collection. Collections with more than 'length' elements would be printed with the excess elements replaced by an ellipsis). If ``level:`` is supplied, it should be an integer specifying the level of depth to which structured printing should proceed. Again, deeper levels are abbreviated with an ellipsis. For example, ``#[1, 2, 3, #[1, 2], 4, 5]`` would be printed as such if ``level:`` were greater than 0. With ``level:`` equal to 0, the representation would be ``#[1, 2, 3, #[...], 4, 5]``. If the :type:`` corresponds to a condition object in the runtime, the DM will attempt to generate the genuine formatted string by interpreting the condition's format-string and format-args. The DM only guarantees this for instances of :drm:``, :drm:`` and :drm:``. .. generic-function:: describe-dylan-object :signature: describe-dylan-object (application instance) => (class-name slots slot-values repeats repeated-slot-name repeated-slot-values) :parameter application: An instance of :class:``. :parameter instance: An instance of :const:``. :value class-name: An instance of :drm:``. :value slots: An instance of :drm:``. :value slot-values: An instance of :drm:``. :value repeats: An instance of :drm:``, or ``#f``. :value repeated-slot-name: An instance of :drm:``, or ``#f``. :value repeated-slot-values: An instance of :drm:``, or ``#f``. .. generic-function:: get-inspector-values :signature: get-inspector-values (application instance) => (instance-class instance-slots slot-getters slot-setters repeats rept-slot rept-getter rept-setter nonword-repeats nonword-repeat-vector) :parameter application: An instance of :class:``. :parameter instance: An instance of :const:``. :value instance-class: An instance of :const:``. :value instance-slots: An instance of :drm:``. :value slot-getters: An instance of :drm:``. :value slot-setters: An instance of :drm:``. :value repeats: An instance of :drm:``, or ``#f``. :value rept-slot: An instance of :class:``, or ``#f``. :value rept-getter: An instance of :drm:``, or ``#f``. :value rept-setter: An instance of :drm:``, or ``#f``. :value nonword-repeats: An instance of :drm:``, or ``#f``. :value nonword-repeat-vector: An instance of :drm:``, or ``#f``. A lower-level function similar in behaviour to describe-dylan-object, but with return values as follows: *class* A :type:`` representing the :drm:`` that describes this Dylan object. *slots* A sequence of :type:``\ s representing the slot descriptors for the class. *getters* A sequence of functions (closures) capable of reading the value from the corresponding slot. Each function takes no arguments and returns a :type:``. *setters* Another sequence of functions capable of setting the value of the corresponding slot. Each function takes a single :class:`` (and also returns it), with the side-effect of inserting that into the slot. The three sequences are parallel, so ``getters[0]`` returns the value of ``slots[0]``, and ``setters[0]`` sets that slot, and so forth. *repeats* If the instance has no repeated slot, this value will be ``#f``. Otherwise, it will be an integer specifying the number of repeated elements. (Note that this integer can still be zero, thus distinguishing between an instance that has no repeated slot, and an instance that does have one except there are currently no elements). *repeated-slot* Unless *repeats* is ``#f``, this will be a :type:`` giving the slot descriptor for the repeated slot. *repeated-getter* Unless *repeats* is ``#f``, this will be a function of one integer argument (*i*) that returns a :type:``. When called with some value *i* (where ``0 <= i <`` *repeats*), it returns the *i*\ th repeated element in the instance. If *i* is not in the specified range, this function will return ``#f``. *repeated-setter* Unless *repeats* is ``#f``, this will be a function of two arguments, an :drm:`` and a :type:``. When called with some integer *i* (where ``0 <= i <`` *repeats*), and some remote-value *v*, sets the *i*\ th repeated element in the instance to *v*. If *i* is not in the specified range, this function will return ``#f``. .. generic-function:: dylan-class-browser-information :signature: dylan-class-browser-information (application class-instance #key use-incarnation) => (slots navigation repeat count-offset element-size element-offset class-slot-count) :parameter application: An instance of :class:``. :parameter class-instance: An instance of :const:``. :parameter #key use-incarnation: An instance of :drm:``. :value slots: An instance of :drm:``. :value navigation: An instance of :class:``. :value repeat: An instance of :drm:``, or ``#f``. :value count-offset: An instance of :drm:``, or ``#f``. :value element-size: An instance of :drm:``, or ``#f``. :value element-offset: An instance of :drm:``, or ``#f``. :value class-slot-count: An instance of :drm:``. .. generic-function:: dylan-class-slot-storage :signature: dylan-class-slot-storage (application class-instance #key use-incarnation) => (basic-names descriptors vals) :parameter application: An instance of :class:``. :parameter class-instance: An instance of :const:``. :parameter #key use-incarnation: An instance of :drm:``. :value basic-names: An instance of :drm:``. :value descriptors: An instance of :drm:``. :value vals: An instance of :drm:``. .. generic-function:: dylan-object? :signature: dylan-object? (ap instance #key address?) => (val) :parameter ap: An instance of :class:``. :parameter instance: An instance of :const:``. :parameter #key address?: An instance of :drm:``. :value val: An instance of :drm:``. Probes the object represented by remote-value and tries to deduce whether it is a valid Dylan object. Returns true if the remote-value is (apparently) a Dylan object, otherwise returns ``#f``. .. generic-function:: dylan-object-size :signature: dylan-object-size (application instance) => (byte-size-of-whole-object number-of-fixed-fields number-of-repeated-elements) :parameter application: An instance of :class:``. :parameter instance: An instance of :const:``. :value byte-size-of-whole-object: An instance of :drm:``. :value number-of-fixed-fields: An instance of :drm:``. :value number-of-repeated-elements: An instance of :drm:``. Mapping Between Symbolic Names and Objects ========================================== .. generic-function:: resolve-dylan-name :signature: resolve-dylan-name (application name context #key indirect? library) => (val address) :parameter application: An instance of :class:``. :parameter name: An instance of :drm:``. :parameter context: An instance of :class:``. :parameter #key indirect?: An instance of :drm:``. :parameter #key library: An instance of :drm:``. :value val: An instance of :class:``, or ``#f``. :value address: An instance of :class:``, or ``#f``. Mangles *string* according to the supplied name context and performs a symbol search for the mangled name. Two values are returned: the value associated with the name, and the address associated with the name. If the lookup fails, both return values will be ``#f``. Otherwise, the second return value is guaranteed to be a valid :type:``, though the first may still be ``#f``. If ``indirect?:`` is true, the DM will attempt to resolve the dylan name to a symbol. If the symbol is found, the DM will read a value from the symbol's address. The value and the address that was indirected through are both returned. Note that the if the DM, for whatever reason, cannot read the value from the address, it will return ``#f`` as the value (although it will still return the address). If ``indirect?:`` is ``#f``, the DM will attempt to resolve the dylan name to an address. It also assumes this address to be the value, and does not perform an indirection. If the symbol is found, it just returns the address twice. If you are not interested in the address of a symbol, you can ignore the second return value. .. note:: The console debugger needs the second 'address' return value in order to set variables with values. .. generic-function:: resolve-dylan-keyword :signature: resolve-dylan-keyword (application sym) => (addr) :parameter application: An instance of :class:``. :parameter sym: An instance of :drm:``. :value addr: An instance of :class:``, or ``#f``. Finds the address of a keyword (:drm:`` object) in the runtime. The string is the name of the keyword, without any syntactic baggage (ie, ``spam`` rather than ``spam:`` or ``#"spam"``). The DM will canonicalize any mixture of character case in the string, and search for the address of the keyword given the current state of the runtime's symbol dictionary. This function will return ``#f`` if the keyword is not found. .. generic-function:: dylan-keyword-name :signature: dylan-keyword-name (application sym) => (str) :parameter application: An instance of :class:``. :parameter sym: An instance of :const:``. :value str: An instance of :drm:``. .. generic-function:: find-dylan-name :signature: find-dylan-name (application address #key disambiguate-methods?) => (name context precise? constant?) :parameter application: An instance of :class:``. :parameter address: An instance of :const:``. :parameter #key disambiguate-methods?: An instance of :drm:``. :value name: An instance of :drm:``. :value context: An instance of :class:``. :value precise?: An instance of :drm:``. :value constant?: An instance of :drm:``. Searches for a symbol whose definition is at (or close to) the given :type:``. Return values: *name* The demangled name of the symbol that was found. *context* A :class:`` giving the name's library and module. (This will have been generated from the stripped-off qualifiers during demangling). *precise?* Will be true if the symbol's address exactly matched the remote-value, otherwise #f. *constant?* Will be true if the name represents a constant value. .. generic-function:: find-closest-symbolic-name :signature: find-closest-symbolic-name (application instance) => (maybe-name precise?) :parameter application: An instance of :class:``. :parameter instance: An instance of :const:``. :value maybe-name: An instance of :class:``, or ``#f``. :value precise?: An instance of :drm:``. Given a :type:`` instance, attempts to locate the :type:`` object whose definition is at or close to that address. The first return value will be that symbol, or ``#f`` if no symbol could be found. The second return value will be true if the symbol's definition precisely matches the supplied address, and ``#f`` otherwise. Note the use of the term *symbolic* rather than *mangled* in this function. There is no guarantee that the remote-value supplied is even a Dylan object, or that the symbol that defines it is a Dylan-emitted symbol. If any symbolic definition can be found, it will be returned. The source of symbolic information will be the access-path, in combination with whatever mechanism we implement for describing interactively (re-)defined symbols. .. generic-function:: resolve-symbolic-name :signature: resolve-symbolic-name (application symbolic-name #key library) => (definition-address) :parameter application: An instance of :class:``. :parameter symbolic-name: An instance of :drm:``. :parameter #key library: An instance of :drm:``. :value definition-address: An instance of :class:``, or ``#f``. Attempts to match the supplied name against symbolic information in the runtime. If a match is made, the address of the name's definition is returned as the result. ``#f`` will be returned if no matching symbol can be found. Again, the source of information will be the access-path, in combination with whatever mechanism we implement for describing interactively (re-)defined symbols. Convenience Interfaces for Dylan Objects ======================================== The general inspector interface can be used to look up all attributes of any arbitrary Dylan object. However, the DM has special knowledge of the Dylan runtime, and is able to deduce information about certain "standard" objects, saving clients the trouble of calculating with the inspector values. Function and class objects are good examples, though we may introduce more and more of these convenience accessors as time goes on. .. generic-function:: dylan-generic-function-methods :signature: dylan-generic-function-methods (application gf-object) => (methods) :parameter application: An instance of :class:``. :parameter gf-object: An instance of :const:``. :value methods: An instance of :drm:``. Given that *gf-object* is a remote instance of a generic function, returns a sequence of :type:``\ s that are remote instances of the methods of that generic function. .. generic-function:: dylan-method-iep :signature: dylan-method-iep (application method-object) => (meth-iep) :parameter application: An instance of :class:``. :parameter method-object: An instance of :const:``. :value meth-iep: An instance of :const:``. Given that *method-object* is a remote instance of a method object (perhaps obtained by a call to :func:`dylan-generic-function-methods`), returns a :type:`` that holds the IEP of that method. .. generic-function:: dylan-method-specializers :signature: dylan-method-specializers (application method-object) => (specializers) :parameter application: An instance of :class:``. :parameter method-object: An instance of :const:``. :value specializers: An instance of :drm:``. Given that remote-value is a remote instance of a method object, returns a sequence of :type:``\ s that are remote instances of :drm:``. .. generic-function:: dylan-slot-descriptor-getter :signature: dylan-slot-descriptor-getter (application descriptor) => (getter) :parameter application: An instance of :class:``. :parameter descriptor: An instance of :const:``. :value getter: An instance of :const:``. Given that *descriptor* is any remote instance of a slot descriptor, this function returns the getter (a remote instance of :drm:``) as a :type:``. (Slot descriptors are returned from a call to :type:`get-inspector-values`. The "name" of a slot is effectively the name of its getter, obtained via this function. The getter can be passed to :func:`find-dylan-name` for a name). .. generic-function:: remote-instance? :signature: remote-instance? (application instance class-instance) => (answer) :parameter application: An instance of :class:``. :parameter instance: An instance of :const:``. :parameter class-instance: An instance of :const:``. :value answer: An instance of :drm:``. Returns true if both :type:``\ s are Dylan objects, and the first is an instance of the second. Any :type:``\ s corresponding to statically-built objects can be used as valid arguments to this function. However, if a :type:`` is *not* known to be statically built, the DM client is required to have that object registered, and to lookup the tracked value before calling this function. The implementation of this function may involve the execution of code in the runtime. However, calling it does not end a debugger transaction. .. generic-function:: dylan-value-unbound? :signature: dylan-value-unbound? (application instance) => (answer) :parameter application: An instance of :class:``. :parameter instance: An instance of :const:``. :value answer: An instance of :drm:``. Returns true if the supplied :type:`` corresponds to the runtime's canonical UNBOUND marker. Otherwise, returns ``#f``. .. generic-function:: dylan-object-immediate-value :signature: dylan-object-immediate-value (application instance) => (replica success?) :parameter application: An instance of :class:``. :parameter instance: An instance of :const:``. :value replica: An instance of :drm:``. :value success?: An instance of :drm:``. If the supplied :type:`` is an "uploadable immediate", such as a tagged integer or character, this function returns an environment-side replica of the runtime value. Note the second :drm:`` return value. We cannot just use ``#f`` as a failure value in this case, since it's conceivable that ``#f`` could be an uploaded immediate, if booleans were tagged. Hence, the second return value flags whether the replica was successfully generated. Note that, even if the object can be uploaded to a replica, there is no guarantee that the precise type of the uploaded object will correspond to the type of the runtime object. For example, an :drm:`` in the runtime might get uploaded to an :class:`` in the environment. Debugger Transactions and Remote Object Registration ==================================================== More could be said about debugger transactions and remote object registration. For now, suffice it to say that a debugger transaction is in effect from the instant the application stops (for any reason) until the instant that it resumes. During this period, any :type:``\ s collected from the application remain valid. Between debugger transactions, objects can be relocated, so there is no guarantee that a :type:`` that pointed to object X before still points to object X. In terms of the DM interface described thus far, :type:``\ s remain valid up until an activation of the ``ready-to-continue-callback`` terminates. This callback is therefore a good place to register them as remote objects via the mechanism described below. In order for a handle on an object to persist between debugger transactions, it must be "registered". This is a facility that is provided by the Spy, with an interface to it being provided by the DM. .. class:: :abstract: :superclasses: :class:`` :keyword required debug-target: An instance of :class:``. Represents a persistent handle on an object within the running application. Unlike instances of :type:``, instances of :class:`` remain valid between debugger transactions. .. generic-function:: register-remote-object :signature: register-remote-object (application value #key finalize weak thread) => (robj) :parameter application: An instance of :class:``. :parameter value: An instance of :const:``. :parameter #key finalize: An instance of :drm:``. :parameter #key weak: An instance of :drm:``. :parameter #key thread: An instance of :drm:``. :value robj: An instance of :class:``. Informs the Spy that the debugger now requires the object specified by *value* is to be tracked. The return value is an instance of :type:`` which can be used to obtain the object's value even if it is relocated. This mechanism is implemented by creating a new reference to the object within the application (so that it will be kept current by the garbage collector) using functionality provided by the Spy. If ``finalize`` is true (the default), then the reference will be implicitly freed by finalization when the development environment reclaims the remote object handle. If ``finalize`` is ``#f``, the overhead for registration may be lower, but a memory leak will result unless the UI explicitly frees the handle (via :func:`free-remote-object`). Normally, while a remote value is registered, the remote garbage collector will be prevented from condemning the remote value in any way that causes the object to be "lost". However, if ``weak`` is true, then the implementation is permitted to reference the remote value weakly, and to garbage collect it if there are no references within the running application itself. If the weakly registered object does get collected, subsequent calls to :func:`remote-object-value` will return ``#f``. .. generic-function:: free-remote-object :signature: free-remote-object (application robj) => (#rest results) :parameter application: An instance of :drm:``. :parameter robj: An instance of :drm:``. :value #rest results: An instance of :drm:``. Informs the Spy that the debugger no longer needs this :class:`` to be tracked. Instances of :class:`` become invalid once passed to this function. .. generic-function:: remote-object-value :signature: remote-object-value (application robj) => (#rest results) :parameter application: An instance of :class:``. :parameter robj: An instance of :drm:``. :value value: An instance of :class:``, or ``#f``. Maps a remote-object onto its remote-value. .. class:: :superclasses: :drm:`` An instance of this may be signaled by :func:`register-remote-object` if, for instance, the Spy does not support remote object registration. .. generic-function:: object-requires-registration? :signature: object-requires-registration? (application instance) => (answer) :parameter application: An instance of :class:``. :parameter instance: An instance of :const:``. :value answer: An instance of :drm:``. .. generic-function:: call-debugger-function :open: :signature: call-debugger-function (application function #rest arguments) => (#rest vals) :parameter application: An instance of :class:``. :parameter function: An instance of :class:``. :parameter #rest arguments: An instance of :drm:``. :value #rest vals: An instance of :drm:``. .. method:: call-debugger-function :specializer: , Stack Backtracing ================= Provides functionality for modeling the stack in a running Dylan application. .. class:: :abstract: :superclasses: :drm:`` :keyword required generic-fp: An instance of :const:``. :keyword newer: An instance of :class:``, or ``#f``. :keyword older: An instance of :class:``, or ``#f``. :keyword required thread: An instance of :class:``. Represents a stack frame of any kind within the application. (In the future, we might want to consider making this an open class so that clients of the DM can describe their own weird and wonderful stack frames.) .. generic-function:: first-stack-frame :signature: first-stack-frame (application thread) => (top-frame) :parameter application: An instance of :class:``. :parameter thread: An instance of :class:``. :value top-frame: An instance of :class:``. Returns the frame at the top of the stack in the running application, regardless of its type. .. generic-function:: next-stack-frame :signature: next-stack-frame (application f) => (maybe-frame) :parameter application: An instance of :class:``. :parameter f: An instance of :class:``. :value maybe-frame: An instance of :class:``, or ``#f``. Given a stack frame, returns the next most recent stack frame, regardless of its type. Returns ``#f`` if there is no next frame. .. generic-function:: previous-stack-frame :signature: previous-stack-frame (application f) => (maybe-frame) :parameter application: An instance of :class:``. :parameter f: An instance of :class:``. :value maybe-frame: An instance of :class:``, or ``#f``. Given a stack frame, returns the next oldest stack frame, regardless of its type. Returns ``#f`` if there is no previous frame. .. class:: :abstract: :superclasses: :drm:`` This is a superclass of any Dylan stack frame. .. note:: Possibly obsolescent. .. class:: :superclasses: :class:`` :keyword required fp: An instance of :const:``. :keyword function-symbol: An instance of :class:``, or ``#f``. :keyword required ip: An instance of :const:``. :keyword linked-to: An instance of :class:``, or ``#f``. :keyword required ret: An instance of :const:``. This is a stack frame that corresponds to a function call. .. generic-function:: call-frame-description :signature: call-frame-description (application frame) => (ap-frame) :parameter application: An instance of :class:``. :parameter frame: An instance of :class:``. :value ap-frame: An instance of :class:``. .. generic-function:: call-frame-return-address :signature: call-frame-return-address (application f) => (top-frame) :parameter application: An instance of :class:``. :parameter f: An instance of :class:``. :value return-address: An instance of :type:``. Returns the call-frame's return address as a :type:``. .. generic-function:: call-frame-frame-pointer :signature: call-frame-frame-pointer (application f) => (top-frame) :parameter application: An instance of :class:``. :parameter f: An instance of :class:``. :value fp: An instance of :type:``. Returns the call-frame's frame pointer as a :type:``. .. generic-function:: call-frame-frame-pointer :signature: call-frame-frame-pointer (application f) => (top-frame) :parameter application: An instance of :class:``. :parameter f: An instance of :class:``. :value ip: An instance of :type:``. Returns the call-frame's instruction pointer (PC) as a :type:``. .. generic-function:: call-frame-nearest-source-locator :signature: call-frame-nearest-source-locator (application call-frame) => (maybe-locator) :parameter application: An instance of :class:``. :parameter call-frame: An instance of :class:``. :value maybe-locator: An instance of :class:``, or ``#f``. If possible, returns the nearest known source location to the instruction pointer for the given call frame. If the frame is not precisely aligned at a source locator, this function can be used by the UI to find the nearest relevant piece of source to indicate as being "current". .. generic-function:: call-frame-aligned-at-source-locator? :signature: call-frame-aligned-at-source-locator? (application call-frame) => (maybe-locator) :parameter application: An instance of :class:``. :parameter call-frame: An instance of :class:``. :value maybe-locator: An instance of :class:``, or ``#f``. If the program counter for this call frame corresponds exactly to a known source code location, then this function returns the locator. If this function returns #f, then the instruction pointer is not at a known source code location. The function :func:`align-thread-to-source-location` can be used to attempt alignment. If alignment succeeds, it is not guaranteed that the destination source locator will be the same as that returned beforehand by :func:`call-frame-nearest-source-locator`. .. generic-function:: call-frame-function :signature: call-frame-function (application frame) => (func-sym func-obj gf-obj) :parameter application: An instance of :class:``. :parameter frame: An instance of :class:``. :value func-sym: An instance of :class:``, or ``#f``. :value func-obj: An instance of :class:``, or ``#f``. :value gf-obj: An instance of :class:``, or ``#f``. Returns a :class:`` that describes the function being called in this frame. This function might return ``#f`` if, for example, there is not sufficient symbolic debugging information. The second return value will be ``#f`` for any non-Dylan frame, and also for Dylan frames where the called function has no current model in the compiler (e.g., it's a closure, or a function from another project). Otherwise, the second return value will be a compiler model for the lambda being called in this frame. This model will have stored the correct (non-mangled) name for the function, as well as further information such as specializers. .. generic-function:: number-of-lexical-variables :signature: number-of-lexical-variables (application dm-frame #key arguments-only?) => (i) :parameter application: An instance of :class:``. :parameter dm-frame: An instance of :class:``. :parameter #key arguments-only?: An instance of :drm:``. :value i: An instance of :drm:``. Returns the number of lexical variables active inside the call frame. Performance note: this function scans for the existence of live lexical variables without reading in names/addresses over the tether. If it turns out that performance is not affected too much by reading names and addresses straight away, we can ditch this function. .. note:: This has nothing to do with Dylan. The integer returned will be the same as the number of elements in the sequence(s) returned by :func:`live-frame-lexical-variables` NOT :func:`active-dylan-lexical-variables`. .. generic-function:: active-dylan-lexical-variables :signature: active-dylan-lexical-variables (application dm-frame #key arguments-only?) => (names types models vals locations) :parameter application: An instance of :class:``. :parameter dm-frame: An instance of :class:``. :parameter #key arguments-only?: An instance of :drm:``. :value names: An instance of :drm:``. :value types: An instance of :drm:``. :value models: An instance of :drm:``. :value vals: An instance of :drm:``. :value locations: An instance of :drm:``. Presents the compiler's view of the set of live lexicals for the given :type:``. The first return value is a sequence of lexical variable model objects. The fourth return value is a sequence parallel to the first. Each element either contains a :type:`` — the value of the corresponding variable (in the first sequence), or ``#f`` - meaning that this variable is not live. By "not live" we mean not live according to the debug information dump. It's entirely possible that dylan variables may be lexically in-scope, while not having obtainable values in the runtime. (For example, their stack space may have been optimized away, or used for something else). .. generic-function:: live-frame-lexical-variables :signature: live-frame-lexical-variables (application dm-frame #key arguments-only?) => (vars vals) :parameter application: An instance of :class:``. :parameter dm-frame: An instance of :class:``. :parameter #key arguments-only?: An instance of :drm:``. :value vars: An instance of :drm:``. :value vals: An instance of :drm:``. Presents the runtime's view of the set of live lexicals for the given :class:``. The first return value is a sequence of :class:`` objects representing the lexical variables that are "live" in the given call frame. This information comes ultimately from the dumped debugging information. The second return value is a parallel sequence of :class:`` objects giving the values of the variables. This is basically just a lower-level API than :func:`active-dylan-lexical-variables`, assumed to be useful for frames running foreign code, and also frames running dylan code outside of the current project. .. class:: :superclasses: :class:``, :class:`` Represents a frame corresponding to the activation of a Dylan function. .. note:: Possibly obsolescent. .. generic-function:: dylan-call-frame? :signature: dylan-call-frame? (application f) => (answer) :parameter application: An instance of :class:``. :parameter f: An instance of :class:``. :value answer: An instance of :drm:``. .. class:: :abstract: :superclasses: :class:``, :class:`` Represents a "special" Dylan stack frame (not a call frame). .. class:: :superclasses: :class:`` A subclass of . A frame corresponding to the Dylan ``block (exit) ... end`` construct. .. class:: :superclasses: :class:`` :keyword required call-frame-pointer: An instance of :const:``. :keyword required cleanup-address: An instance of :const:``. Corresponds to a block construct with a cleanup. Restarts ======== This section documents the APIs by which the debugger can determine which restarts are available, and also signal a restart on a thread. .. class:: :superclasses: :drm:`` :keyword abort?: An instance of :drm:``. :keyword description: An instance of :drm:``. :keyword format-args: An instance of :drm:``, or ``#f``. :keyword format-string: An instance of :class:``, or ``#f``. :keyword formatted?: An instance of :drm:``. :keyword required function: An instance of :const:``. :keyword required index: An instance of :drm:``. :keyword required init-args: An instance of :drm:``. :keyword required target: An instance of :class:``. :keyword required test: An instance of :const:``. :keyword required type: An instance of :const:``. A debugger-level abstract handle onto a restart. This is the object used to model restarts in the runtime. .. generic-function:: remote-restart-description :signature: remote-restart-description (remote-restart) => (str) :parameter remote-restart: An instance of :class:``. :value str: An instance of :drm:``. Returns a string describing the expected behaviour of the restart. .. generic-function:: available-restarts-for-thread :signature: available-restarts-for-thread (application thread) => (restarts) :parameter application: An instance of :class:``. :parameter thread: An instance of :class:``. :value restarts: An instance of :drm:``. Examines the dynamic environment of the thread in order to generate a sequence of available restarts. Each member of the returned sequence is an instance of :class:``. .. generic-function:: signal-restart-on-thread :signature: signal-restart-on-thread (application thread rst) => () :parameter application: An instance of :class:``. :parameter thread: An instance of :class:``. :parameter rst: An instance of :class:``. Instructs the DM that the specified thread should, upon completion of the current debugger transaction, continue by signalling the specified restart (a :class:``). Source-Level Stepping ===================== These functions may only be called during a debugger transaction, and they do not cause the application to immediately run. In each case, the step operation occurs on the specified thread as soon as that thread resumes. All of these functions register specialized breakpoints. They may also do some substantial low-level examination of the runtime, even down to machine code instructions. The breakpoints will be signalled later, when the thread reaches the destination source location. Upon calling one of these functions, the DM attempts to calculate the destination :class:`` for the step. There may be several possibilities (for example, the entry points of all methods when a generic function is being called). If the DM fails to calculate any possible destination, it will return ``#f`` as the success code from these functions. Otherwise, true is returned. (The most likely cause of failure would be a lack of line number information in the debug info format). Clients of DM should not expect any specialized breakpoints to be signalled following a ``#f`` result from one of these functions. However, these functions may work even in the absence of debug information - just don't rely on obtaining a :class:`` for the destination when the thread arrives there! (Step-out, for example, can break the frame's return address regardless of whether that address is a known source location). These functions should be considered analogous to register-debug-point (since that is what they end up doing!), hence the need for the callback argument. The callbacks should be of the same signature as those passed to :func:`register-debug-point`. .. generic-function:: instruct-thread-to-step-over :signature: instruct-thread-to-step-over (application thread #key call-frame) => (success?) :parameter application: An instance of :class:``. :parameter thread: An instance of :class:``. :parameter #key call-frame: An instance of :drm:``. :value success?: An instance of :drm:``. Arranges for the thread to step to the next source location within the execution of this function frame (e.g., stepping over function invocations). If the thread does not reach another source location within the execution of this function, then this will behave like a step-out operation instead. .. generic-function:: instruct-thread-to-step-into :signature: instruct-thread-to-step-into (application thread #key call-frame precomputed-addresses) => (success?) :parameter application: An instance of :class:``. :parameter thread: An instance of :class:``. :parameter #key call-frame: An instance of :drm:``. :parameter #key precomputed-addresses: An instance of :drm:``. :value success?: An instance of :drm:``. Arranges for the thread to step into a function. If the thread is not positioned exactly at a function call, this will behave like a step-over operation instead. .. generic-function:: instruct-thread-to-step-out :signature: instruct-thread-to-step-out (application thread #key call-frame) => (success?) :parameter application: An instance of :class:``. :parameter thread: An instance of :class:``. :parameter #key call-frame: An instance of :drm:``. :value success?: An instance of :drm:``. Arranges for the thread to step out of its current function frame. .. generic-function:: align-thread-to-source-location :signature: align-thread-to-source-location (application thread #key interactive?) => (success?) :parameter application: An instance of :class:``. :parameter thread: An instance of :class:``. :parameter #key interactive?: An instance of :drm:``. :value success?: An instance of :drm:``. Attempts to align the program counter of this thread to a known source location. These functions should work in foreign code as well, provided that sufficient debugging information is available for the source locators. FIXME dropped a section here (about the relationship between tracing and stepping) which might not be valid anymore. Mappings Between Addresses and Source Locators ============================================== This is a high-level abstraction for mapping locations in source code to instruction addresses in the runtime, for the purpose of inspecting local variables, or setting breakpoints etc. These functions are defined to work from whatever information is available to the DM, either from the Dylan compiler (if applicable), or from source location information within the runtime (if available). These two APIs represent a unified interface to these two sources of information. .. generic-function:: remote-address-source-location :signature: remote-address-source-location (application address #key line-only? interactive-only? exact-only?) => (source-location exact?) :parameter application: An instance of :class:``. :parameter address: An instance of :const:``. :parameter #key line-only?: An instance of :drm:``. :parameter #key interactive-only?: An instance of :drm:``. :parameter #key exact-only?: An instance of :drm:``. :value source-location: An instance of :class:``, or ``#f``. :value exact?: An instance of :drm:``. Attempts to map an instruction address in the runtime to a location in source code. .. generic-function:: source-location-remote-address :signature: source-location-remote-address (application source-location #key line-only? interactive-only? entry-point-only? compilation-context) => (address) :parameter application: An instance of :class:``. :parameter source-location: An instance of :class:``. :parameter #key line-only?: An instance of :drm:``. :parameter #key interactive-only?: An instance of :drm:``. :parameter #key entry-point-only?: An instance of :drm:``. :parameter #key compilation-context: An instance of :drm:``. :value address: An instance of :class:``, or ``#f``. Attempts to map a location in source code to an instruction address in the runtime. The keyword arguments are interpreted as follows for both mappings: ``line-only?`` Only use the max-one-per-line set of recorded source location points for the mapping. ``interactive-only?:`` Only use the set of recorded "interactive" source location points for the mapping. All source-locators are described using the canonical class in the :lib:`source-records` library. Note that :class:`` objects may be stored persistently. If the environment wishes to remember the locations of breakpoints between runs of the application, then it should keep a set of :class:`` objects. These can be mapped as breakpoints via the DM when the application is started. The DM makes the following guarantees: #. It will map source locations via the compiler in preference to via the runtime. #. The mapping via the compiler uses the same set of source-locations as is available via the API between the compiler and the environment. The implication of these two guarantees is that the DM will always find an exact mapping for any source-location retrieved via :func:`definition-code-locations`, given the same values of 'line-only?' and 'interactive-only?' .. note:: This doesn't appear to be correct, and :func:`definition-code-locations` is an unimplemented stub. Further Points: #. Source locations obtained from runtime data will be standard :class:``\ s in standard source records. This will require extending the source record protocol to handle random (foreign) files. #. Source locations obtained from runtime data are necessarily not considered to be interactive. Foreign Code Debugging ====================== This chapter will be fleshed out when we have a solid story for debugging foreign code. At the moment: .. generic-function:: foreign-object-type :signature: foreign-object-type (application foreign-instance) => (remote-type-description) :parameter application: An instance of :class:``. :parameter foreign-instance: An instance of :const:``. :value remote-type-description: An instance of :drm:``. Returns, if possible, a :type:`` (defined in access-path) that describes the supplied object. This function cannot guarantee to return a :type:``, and will return ``#f`` if no type description can be obtained. .. note:: This is not implemented yet, and will just return #f. Runtime Context =============== .. class:: :abstract: :superclasses: :drm:`` :keyword scoped-variables: An instance of :drm:``. :keyword stack-frame: An instance of :class:``, or ``#f``. :keyword required target: An instance of :class:``. :keyword required thread: An instance of :class:``. The DM is capable of allocating this object for any specified thread during a debugger transaction. Only the DM and the interactive downloader need to unpick this object. .. generic-function:: runtime-context-debug-target :signature: runtime-context-debug-target (context) => (value) :parameter context: An instance of :class:``. :value value: An instance of :class:``. .. generic-function:: runtime-context-frame :signature: runtime-context-frame (context) => (value) :parameter context: An instance of :class:``. :value value: An instance of :class:``, or ``#f``. .. generic-function:: runtime-context-thread :signature: runtime-context-thread (context) => (value) :parameter context: An instance of :class:``. :value value: An instance of :class:``. .. method:: active-lexical-variables :specializer: A method on the open GF exported by :mod:`dfmc-interactive-execution` in the :lib:`dfmc-browser-support` library. .. generic-function:: runtime-context-lexical-variable-value :signature: runtime-context-lexical-variable-value (context, index) => (value) :parameter context: An instance of :class:``. :parameter index: An instance of :drm:``. :value value: An instance of :class:``. Returns the actual value of a lexical variable whose index was provided by active-lexical-variables. .. generic-function:: current-runtime-context :signature: current-runtime-context (application thread #key stack-frame) => (context) :parameter application: An instance of :class:``. :parameter thread: An instance of :class:``. :parameter #key stack-frame: An instance of :class:``, or ``#f``. :value context: An instance of :class:``. Creates and returns the runtime-context for a thread in an application. Profiling ========= The Profiler Manager is used to collect profiling data from a running application. It allows a client to control when profiling information is to be collected and some limited control over what data is collected. The profiler manager API is closely associated with the Debugger Manager and is exported from the debugger-manager module in the debugger-manager library. Controlling the Profiler Manager -------------------------------- Profiling is started by a call to :func:`start-profiling` and is stopped by a call to :func:`stop-profiling`, or when the target application exits. Profiling may be turned on and off any number of times and does not have to be in the same state when the application exits as it was when the application started. The Profiler Manager gathers data by stopping the application at regular intervals and taking a "snapshot" of each thread's stack. It's possible to specify the interval between application stops and which threads you are interested in profiling. The volume of data collected can be further reduced by specifying a maximum stack depth to which stacks are examined during snapshots. The profiler manager maintains a complete history of the snapshots it has collected, but allows this to be reset by a client library. The profiler manager returns all the data in its history to the client on request. .. generic-function:: application-profiling? :signature: application-profiling? (application) => (profiling?) :parameter application: An instance of :class:``. :value profiling?: An instance of :drm:``. .. generic-function:: control-profiling :signature: control-profiling (application #key reset? snapshot-limit interval class-profiling? stack-depth threads) => () :parameter application: An instance of :class:``. :parameter #key reset?: An instance of :drm:``. If supplied with a boolean value of ``#t`` tells the profiler manager to reset its history i.e. throw away all the data it has collected so far. The default value is ``#f``. :parameter #key snapshot-limit: An instance of :drm:``. :parameter #key interval: An instance of :drm:``, or ``#f``. Specifies the regular interval in millisecs after which the application will be stopped and data collected. There is no guarantee that the application will be stopped precisely on this interval, but it will not be stopped before the interval is up. Not all threads will necessarily have had the same amount of cpu-time during the interval, so the profiler provides a weight for each thread based on the amount of cpu-time it has had. :parameter #key class-profiling?: An instance of :drm:``. :parameter #key stack-depth: An instance of :drm:``. The maximum depth to which the profiler should trace stack frames. Stacks deeper than this are still traced, but only to the depth specified. The limit applies for each snapshot taken and to all threads which are being profiled. ``#f`` (the default) indicates no limit and the entire stack is traced. :parameter #key threads: An instance of :drm:``. A collection of :class:`` objects which restricts the profiler to collecting data from the specified thread(s). ``#f`` (the default) indicates that data is to be collected from all threads. If one of the threads being profiled exits, the profiler manager stops collecting data for the thread, but keeps whatever data it has collected for it since the last reset in its history. Can be called at any time during a debugger transaction irrespective of whether profiling is on or not. It may also be called before the target application is running. .. generic-function:: start-profiling :signature: start-profiling (application #key reset? snapshot-limit interval class-profiling? stack-depth threads) => () :parameter application: An instance of :class:``. :parameter #key reset?: An instance of :drm:``. :parameter #key snapshot-limit: An instance of :drm:``. :parameter #key interval: An instance of :drm:``, or ``#f``. :parameter #key class-profiling?: An instance of :drm:``. :parameter #key stack-depth: An instance of :drm:``. :parameter #key threads: An instance of :drm:``. Turns on profiling for the target application. If supplied, the keyword arguments override the properties set by any earlier :func:`control-profiling` call. In effect :func:`control-profiling` is called with the keyword arguments before profiling is switched on. .. generic-function:: stop-profiling :signature: stop-profiling (application) => () :parameter application: An instance of :class:``. Stops the profiling of the target application. This may only be called during a debugger transaction. .. generic-function:: profile-data :signature: profile-data (object) => (#rest results) :parameter object: An instance of :drm:``. :value #rest results: An instance of :drm:``. Returns all the profiling data collected since the last reset. See the next section for a description of the structure of the returned data. .. method:: profile-data :specializer: .. method:: profile-data :specializer: .. generic-function:: reset-profile-data :signature: reset-profile-data (application) => () :parameter application: An instance of :class:``. Extracting the data ------------------- The data returned by the profiler comprises a series of snapshots for each thread that was profiled. During a snapshot, the profiler manager steps through the function call frames on the stack (to a maximum depth if one has been specified) collecting an instruction pointer for each frame. The instruction pointer is the address of the next instruction to execute for the frame. .. class:: :superclasses: :drm:`` :keyword application-snapshots: An instance of :class:``. :keyword profile-threads: An instance of :class:``. .. generic-function:: application-snapshot-skip :signature: application-snapshot-skip (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :drm:``. .. generic-function:: application-snapshots :signature: application-snapshots (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :class:``. .. generic-function:: application-profile-threads :signature: application-profile-threads (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :class:``. .. class:: :superclasses: :drm:`` :keyword required page-faults-increment: An instance of :drm:``. :keyword required thread-snapshots: An instance of :drm:``. :keyword required wall-time-increment: An instance of :drm:``. .. generic-function:: application-thread-snapshot :signature: application-thread-snapshot (snapshot thread) => (thread-snapshot) :parameter snapshot: An instance of :class:``. :parameter thread: An instance of :class:``. :value thread-snapshot: An instance of :class:``, or ``#f``. .. generic-function:: wall-time-increment :signature: wall-time-increment (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :drm:``. .. generic-function:: page-faults-increment :signature: page-faults-increment (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :drm:``. .. generic-function:: thread-snapshots :signature: thread-snapshots (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :drm:``. .. class:: :superclasses: :drm:`` :keyword required allocated-class: An instance of :class:``, or ``#f``. :keyword required allocation-increment: An instance of :drm:``. :keyword required cpu-time-increment: An instance of :drm:``. :keyword required instruction-pointers: An instance of :const:``. :keyword required thread: An instance of :class:``. Includes a for the thread and an indication of which thread the data was collected from. This describes the data collected from a thread during a "snapshot". It includes the sequence of instruction pointers associated with the stack frames on the thread's stack at the time of the snapshot (to a maximum depth, if one was specified) and a weight for this data. .. type:: .. generic-function:: profile-thread :signature: profile-thread (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :class:``. Returns the :class:`` object associated with the thread from which the data was collected. .. generic-function:: cpu-time-increment :signature: cpu-time-increment (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :drm:``. .. generic-function:: allocation-increment :signature: allocation-increment (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :drm:``. .. generic-function:: allocated-class :signature: allocated-class (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :class:``, or ``#f``. .. generic-function:: instruction-pointers :signature: instruction-pointers (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :const:``. Returns a sequence of instruction pointers associated with each stack frame on the thread's stack. Each instruction pointer is the address of the next instruction to execute for the frame as a :type:``. The instruction pointers are ordered with those from the most recently created stack frames (top of stack) appearing first. .. generic-function:: set-application-class-breakpoint :signature: set-application-class-breakpoint (application thread class) => (transaction) :parameter application: An instance of :class:``. :parameter thread: An instance of :class:``. :parameter class: An instance of :class:``, or ``#f``. :value transaction: An instance of :drm:``. .. generic-function:: clear-application-class-breakpoint :signature: clear-application-class-breakpoint (application thread class #key stop-profile?) => (transaction) :parameter application: An instance of :class:``. :parameter thread: An instance of :class:``. :parameter class: An instance of :class:``, or ``#f``. :parameter #key stop-profile?: An instance of :drm:``. :value transaction: An instance of :drm:``. Clears a remote class breakpoint. .. generic-function:: clear-application-class-breakpoints :signature: clear-application-class-breakpoints (application thread) => (transaction) :parameter application: An instance of :class:``. :parameter thread: An instance of :class:``. :value transaction: An instance of :drm:``. Clears all remote class breakpoints. Extension Interfaces ==================== .. generic-function:: load-runtime-component :signature: load-runtime-component (application name) => (success?) :parameter application: An instance of :class:``. :parameter name: An instance of :drm:``. :value success?: An instance of :drm:``. Attempts to dynamically load a runtime component (DLL). .. macro:: spy-function-definer .. class:: :superclasses: :class:`` :keyword entry-point: An instance of :class:``, or ``#f``. Describes a spy function that must be called with C calling conventions. .. generic-function:: spy-function-runtime-name :signature: spy-function-runtime-name (sf) => (name) :parameter sf: An instance of :class:``. :value name: An instance of :drm:``. Returns the name of the spy function. .. generic-function:: spy-function-runtime-component :signature: spy-function-runtime-component (sf) => (name) :parameter sf: An instance of :class:``. :value name: An instance of :drm:``. Returns the component name of the spy function .. generic-function:: call-spy :signature: call-spy (spy-function application #rest arguments) => (result) :parameter spy-function: An instance of :class:``. :parameter application: An instance of :class:``. :parameter #rest arguments: An instance of :drm:``. :value result: An instance of :const:``. .. generic-function:: call-spy-on-thread :signature: call-spy-on-thread (spy-function application thread #rest arguments) => (result) :parameter spy-function: An instance of :class:``. :parameter application: An instance of :class:``. :parameter thread: An instance of :class:``. :parameter #rest arguments: An instance of :drm:``. :value result: An instance of :const:``. .. class:: :abstract: :superclasses: :drm:`` :keyword required arguments: An instance of :drm:``. :keyword required debug-target: An instance of :class:``. :keyword required function-descriptor: An instance of :class:``. The common superclass of all exceptions that can occur when attempting to call a spy function. .. generic-function:: spy-call-function-descriptor :signature: spy-call-function-descriptor (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :class:``. .. generic-function:: spy-call-debug-target :signature: spy-call-debug-target (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :class:``. .. generic-function:: spy-call-arguments :signature: spy-call-arguments (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :drm:``. .. class:: :superclasses: :class:`` .. class:: :superclasses: :class:`` .. class:: :superclasses: :class:`` .. class:: :superclasses: :class:`` :keyword required selected-thread: An instance of :class:``. An attempt was made to call a spy function on a specific thread, but the thread could not be used. .. generic-function:: spy-call-selected-thread :signature: spy-call-selected-thread (object) => (value) :parameter object: An instance of :class:``. :value value: An instance of :class:``.