Class DebuggerSession

java.lang.Object
com.oracle.truffle.api.debug.DebuggerSession
All Implemented Interfaces:
Closeable, AutoCloseable

public final class DebuggerSession extends Object implements Closeable
Represents a single debugging session of a Debugger.

Session lifetime

  • A debugging client requests a new session from the Debugger.
  • A client uses a session to request suspension of guest language execution threads, for example by setting breakpoints or stepping.
  • When a session suspends a guest language execution thread, it passes its client a new SuspendedEvent via synchronous callback on the execution thread.
  • A suspended guest language execution thread resumes language execution only after the client callback returns.
  • Sessions that are no longer needed should be closed; a closed session has no further affect on engine execution.

Debugging requests

Session clients can manage guest language execution in several ways:

  • Install a newly created Breakpoint.
  • Request suspension of the next execution on the first thread that is encountered.
  • Request a stepping action (e.g. step into, step over, kill) on a suspended execution thread, to take effect after the client callback returns.

Event merging

A session may suspend a guest language execution thread in response to more than one request from its client. For example:

  • A stepping action may land where a breakpoint is installed.
  • Multiple installed breakpoints may apply to a particular location.
In such cases the client receives a single merged event. A call to SuspendedEvent.getBreakpoints() lists all breakpoints (possibly none) that apply to the suspended event's location.

Multiple sessions

There can be multiple sessions associated with a single engine, which are independent of one another in the following ways:

  • Breakpoints created by a session are not visible to clients of other sessions.
  • A client receives no notification when guest language execution threads are suspended by sessions other than its own.
  • Events are not merged across sessions. For example, when a guest language execution thread hits a location where two sessions have installed breakpoints, each session notifies its client with a new SuspendedEvent instance.
Because all sessions can control engine execution, some interactions are inherently possible. For example:
  • A session's client can kill an execution at just about any time.
  • A session's client can starve execution by not returning from the synchronous callback on the guest language execution thread.

Usage example:

try (DebuggerSession session = Debugger.find(instrumentEnv).
                startSession(new SuspendedCallback() {
    public void onSuspend(SuspendedEvent event) {
        // step into the next event
        event.prepareStepInto(1);
    }
})) {
    Source someCode = Source.newBuilder("...",
                    "...", "example").build();

    // install line breakpoint
    session.install(Breakpoint.newBuilder(someCode).lineIs(3).build());
}
Since:
0.17
  • Method Details

    • toString

      public String toString()
      Overrides:
      toString in class Object
      Since:
      0.17
    • getDebugger

      public Debugger getDebugger()
      Returns the debugger instance that this session is associated with. Can be used also after the session has already been closed.
      Since:
      0.17
    • getTopScope

      public DebugScope getTopScope(String languageId) throws DebugException
      Returns a language top scope. The top scopes have global validity and unlike DebugStackFrame.getScope() have no relation to the suspended location.
      Throws:
      DebugException - when guest language code throws an exception
      Since:
      0.30
    • getExportedSymbols

      public Map<String,? extends DebugValue> getExportedSymbols()
      Returns a polyglot scope - symbols explicitly exported by languages.
      Since:
      0.30
    • setShowHostStackFrames

      public void setShowHostStackFrames(boolean showHostStackFrames)
      Set to provide host information in stack traces. When true, host frames and host trace elements are provided, when available.
      Since:
      20.3
      See Also:
    • setSteppingFilter

      public void setSteppingFilter(SuspensionFilter steppingFilter)
      Set a stepping suspension filter. Prepared steps skip code that does not match this filter.
      Since:
      0.26
    • suspendNextExecution

      public void suspendNextExecution()
      Suspends the next execution on the first thread that is encountered. After the first thread was suspended no further executions are suspended unless suspendNextExecution() is called again. If multiple threads are executing at the same time then there are no guarantees on which thread is going to be suspended. Will throw an IllegalStateException if the session is already closed.
      Since:
      0.17
    • suspendHere

      public boolean suspendHere(Node node)
      Suspend immediately at the current location of the current execution thread. A Node argument can be provided as an exact current location, if known. This method can be called on the guest execution thread only.

      This method calls SuspendedCallback.onSuspend(SuspendedEvent) synchronously, with SuspendedEvent created at the actual location of the current thread. This method can not be called from an existing callback.

      Parameters:
      node - the top Node of the execution, or null
      Returns:
      true when there is a guest code execution on the current thread and SuspendedCallback was called, false otherwise.
      Throws:
      IllegalStateException - when the current thread is suspended already
      IllegalArgumentException - when a node with no RootNode is provided, or it's root node does not match the current execution root, or the node does not match the current call node, if known.
      Since:
      20.3
    • suspend

      public void suspend(Thread t)
      Suspends the current or the next execution of a given thread. Will throw an IllegalStateException if the session is already closed.
      Since:
      20.0
    • suspendAll

      public void suspendAll()
      Suspends the current or the next execution on all threads. All new executing threads will start suspended until resumeAll() is called or the session is closed. Will throw an IllegalStateException if the session is already closed.
      Since:
      20.0
    • resumeAll

      public void resumeAll()
      Resumes all suspended executions that have not yet been notified.
      Since:
      0.17
    • resume

      public void resume(Thread t)
      Resumes the execution on a given thread if it has not been suspended yet.
      Parameters:
      t - the thread to resume
      Since:
      20.0
    • createPrimitiveValue

      public DebugValue createPrimitiveValue(Object primitiveValue, LanguageInfo language) throws IllegalArgumentException
      Creates a DebugValue object that wraps a primitive value. Strings and boxed Java primitive types are considered primitive. Throws IllegalArgumentException if the value is not primitive.
      Parameters:
      primitiveValue - a primitive value
      language - guest language this value is value is associated with. Some value attributes depend on the language, like DebugValue.getMetaObject(). Can be null.
      Returns:
      a DebugValue that wraps the primitive value.
      Throws:
      IllegalArgumentException - if the value is not a boxed Java primitive or a String.
      Since:
      21.2
    • close

      public void close()
      Closes the current debugging session and disposes all installed breakpoints.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Since:
      0.17
    • getBreakpoints

      public List<Breakpoint> getBreakpoints()
      Returns all breakpoints installed in this session, in the install order. The returned list contains a current snapshot of breakpoints, those that were disposed, or installed on Debugger are not included.
      Since:
      0.17
      See Also:
    • setBreakpointsActive

      @Deprecated(since="19.0") public void setBreakpointsActive(boolean active)
      Set whether breakpoints are active in this session. This has no effect on breakpoints enabled/disabled state. Breakpoints need to be active to actually break the execution. The breakpoints are active by default.
      Parameters:
      active - true to make all breakpoints active, false to make all breakpoints inactive.
      Since:
      0.24
    • setBreakpointsActive

      public void setBreakpointsActive(Breakpoint.Kind breakpointKind, boolean active)
      Set whether breakpoints of the given kind are active in this session. This has no effect on breakpoints enabled/disabled state. Breakpoints need to be active to actually break the execution. The breakpoints are active by default.
      Parameters:
      breakpointKind - the kind of breakpoints to activate/deactivate
      active - true to make breakpoints active, false to make breakpoints inactive.
      Since:
      19.0
    • isBreakpointsActive

      @Deprecated(since="19.0") public boolean isBreakpointsActive()
      Deprecated.
      Test whether breakpoints are active in this session. Breakpoints do not break execution when not active.
      Since:
      0.24
    • isBreakpointsActive

      public boolean isBreakpointsActive(Breakpoint.Kind breakpointKind)
      Test whether breakpoints of the given kind are active in this session. Breakpoints do not break execution when not active.
      Parameters:
      breakpointKind - the kind of breakpoints to test
      Since:
      19.0
    • install

      public Breakpoint install(Breakpoint breakpoint)
      Adds a new breakpoint to this session and makes it capable of suspending execution.

      The breakpoint suspends execution by making a callback to this session, together with an event description that includes which breakpoint(s) were hit.

      Parameters:
      breakpoint - a new breakpoint
      Returns:
      the installed breakpoint
      Throws:
      IllegalStateException - if the session has been closed
      Since:
      0.17
    • setAsynchronousStackDepth

      public void setAsynchronousStackDepth(int depth)
      Request for languages to provide stack frames of scheduled asynchronous execution. Languages might not provide asynchronous stack frames by default for performance reasons. At most depth asynchronous stack frames are asked for. When multiple debugger sessions or other instruments call this method, the languages get a maximum depth of these calls and may therefore provide longer asynchronous stacks than requested. Also, languages may provide asynchronous stacks if it's of no performance penalty, or if requested by other options.

      Asynchronous stacks can then be accessed via SuspendedEvent.getAsynchronousStacks(), or DebugException.getDebugAsynchronousStacks().

      Parameters:
      depth - the requested stack depth, 0 means no asynchronous stack frames are required.
      Since:
      20.1.0
      See Also:
    • setContextsListener

      public void setContextsListener(DebugContextsListener listener, boolean includeActiveContexts)
      Set a listener to be notified about changes in contexts in guest language application. One listener can be set at a time, call with null to remove the current listener.
      Parameters:
      listener - a listener to receive the context events, or null to reset it
      includeActiveContexts - whether or not this listener should be notified for present active contexts
      Since:
      0.30
    • setThreadsListener

      public void setThreadsListener(DebugThreadsListener listener, boolean includeInitializedThreads)
      Set a listener to be notified about changes in threads in guest language application. One listener can be set at a time, call with null to remove the current listener.
      Parameters:
      listener - a listener to receive the context events
      includeInitializedThreads - whether or not this listener should be notified for present initialized threads
      Since:
      0.30
    • setSourcePath

      public void setSourcePath(Iterable<URI> uris)
      Set a list of source path roots that are used to resolve relative source URIs. All debugger methods that provide Source object, resolve relative sources with respect to this source-path. When the resolution does not succeed (the relative path does not exist under any of the supplied source-path elements), the original relative Source is provided.
      Parameters:
      uris - a list of absolute URIs
      Throws:
      IllegalArgumentException - when an URI is not absolute
      Since:
      19.0
      See Also:
    • resolveSource

      public Source resolveSource(Source source)
      Resolve the source with respect to the actual source path. Sources with relative URI are subject to resolution to an existing absolute location. The first source-path URI that resolves to an existing location is used.
      Parameters:
      source - the source to resolve
      Returns:
      the provided source if no resolution is necessary, or the resolved source, or null when it's not possible to resolve the provided source
      Since:
      19.0