Skip to content

Allow stepping through disassembly#831

Open
danthe1st wants to merge 2 commits intoeclipse-jdt:masterfrom
danthe1st:debug-disassembly
Open

Allow stepping through disassembly#831
danthe1st wants to merge 2 commits intoeclipse-jdt:masterfrom
danthe1st:debug-disassembly

Conversation

@danthe1st
Copy link

@danthe1st danthe1st commented Dec 22, 2025

What it does

This PR allows stepping through the bytecode of disassembled classes in the class file editor.

This is just an unfinished prototype but I wanted to create a (draft) PR early to be able to get feedback and show the basic approach.

This depends on another PR in jdt.ui (eclipse-jdt/eclipse.jdt.ui#2708)

image image

@SougandhS Since you have worked on similar things recently, I think you might be interested in that.

How to test

  • Start Eclipse with this change as well as this patch
  • Step through some code that steps into libraries without a source attachment
  • It automatically jumps to the relevant bytecode instruction(s) corresponding to the stack frame
  • Stepping through normal (non-library) classes and library classes with source attachments should still work

Author checklist

@SougandhS
Copy link
Member

Thanks for the feature @danthe1st, looks great on feature wise

Would it be possible to change highlight color for dark theme ? its bit hard to read

image

@SougandhS SougandhS added the enhancement New feature or request label Jan 1, 2026
@eclipse-jdt-bot
Copy link
Contributor

This pull request changes some projects for the first time in this development cycle.
Therefore the following files need a version increment:

org.eclipse.jdt.debug/META-INF/MANIFEST.MF

An additional commit containing all the necessary changes was pushed to the top of this PR's branch. To obtain these changes (for example if you want to push more changes) either fetch from your fork or apply the git patch.

Git patch
From 0fc0c7499e1927da534bae46cee3001370717b67 Mon Sep 17 00:00:00 2001
From: Eclipse JDT Bot <jdt-bot@eclipse.org>
Date: Thu, 1 Jan 2026 05:20:08 +0000
Subject: [PATCH] Version bump(s) for 4.39 stream


diff --git a/org.eclipse.jdt.debug/META-INF/MANIFEST.MF b/org.eclipse.jdt.debug/META-INF/MANIFEST.MF
index 9afbed70f..bef1c1bbb 100644
--- a/org.eclipse.jdt.debug/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.debug/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.debug; singleton:=true
-Bundle-Version: 3.25.0.qualifier
+Bundle-Version: 3.25.100.qualifier
 Bundle-ClassPath: jdimodel.jar
 Bundle-Activator: org.eclipse.jdt.internal.debug.core.JDIDebugPlugin
 Bundle-Vendor: %providerName
-- 
2.52.0

Further information are available in Common Build Issues - Missing version increments.

@danthe1st danthe1st force-pushed the debug-disassembly branch 4 times, most recently from a53115b to 191da85 Compare January 5, 2026 10:57
@danthe1st
Copy link
Author

@SougandhS I updated this to use the current instruction pointer background color (see the updated screenshots).

Do you know whether there is a way to detect when the stack current stack frame is no longer there/when the highlighting should be removed (e.g. when resuming or stepping into a different file)?

@SougandhS
Copy link
Member

@SougandhS I updated this to use the current instruction pointer background color (see the updated screenshots).

Thanks, much better now

Do you know whether there is a way to detect when the stack current stack frame is no longer there/when the highlighting should be removed (e.g. when resuming or stepping into a different file)?

You can achieve this by registering an IDebugContextListener and check that stackframe's status accordingly

@danthe1st danthe1st force-pushed the debug-disassembly branch 4 times, most recently from 86a12ff to 86d25a3 Compare January 10, 2026 15:22
@danthe1st danthe1st marked this pull request as ready for review January 10, 2026 15:31
@danthe1st
Copy link
Author

@SougandhS Hi. Now that I was able to write a test for this as well, I think eclipse-jdt/eclipse.jdt.ui#2708 and this are ready for review.

Note that this won't be able to build successfully without eclipse-jdt/eclipse.jdt.ui#2708.
Also, as you probably see, I am not that experienced with the tests here ;).

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds prototype support for stepping through and highlighting bytecode instructions in the Class File Editor when debugging into libraries without source attachments (disassembly view).

Changes:

  • Add JDIStackFrame.getCodeIndex() to expose the current bytecode index for the active stack frame.
  • Introduce a new JavaStackFrameSourceDisplayAdapter to highlight the corresponding disassembly instruction in ClassFileEditor (and absorb prior lambda-selection behavior).
  • Add a new UI test to verify disassembly highlighting updates when stepping, and bump bundle/plugin versions.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIStackFrame.java Exposes bytecode codeIndex() via new accessor for UI highlighting.
org.eclipse.jdt.debug/META-INF/MANIFEST.MF Bumps core debug bundle version.
org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/sourcelookup/LambdaStackFrameSourceDisplayAdapter.java Removes the old lambda-only source display adapter (logic moved/merged).
org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/sourcelookup/JavaStackFrameSourceDisplayAdapter.java New unified source display adapter: highlights disassembly instructions and handles lambda selection.
org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/sourcelookup/JavaDebugShowInAdapterFactory.java Routes stack frames to the new adapter (and reuses a single instance).
org.eclipse.jdt.debug.ui/pom.xml Bumps UI plugin Maven version.
org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF Bumps UI bundle version.
org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/sourcelookup/ClassFileEditorHighlightingTest.java Adds regression test covering disassembly instruction highlighting while stepping.
org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java Registers the new test in the automated suite.
Comments suppressed due to low confidence (5)

org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIStackFrame.java:1762

  • getCodeIndex() reads fLocation without the same synchronized (fThread) guard used by other fLocation accessors (e.g., getLineNumber). To avoid races with bind(...) updates, please synchronize similarly and consider returning a sentinel (e.g., -1) when the frame is invalid/not suspended rather than always dereferencing fLocation.
	public long getCodeIndex() {
		return fLocation.codeIndex();
	}

org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/sourcelookup/ClassFileEditorHighlightingTest.java:40

  • The test method name test123 is not descriptive and doesn’t follow the naming style used in neighboring tests (e.g., testFindDuplicatesBug565462). Please rename it to something that reflects the behavior under test (e.g., highlighting the current bytecode instruction in the class file editor).
	public void test123() throws Exception {
		IJavaProject javaProject = getProjectContext();
		createLineBreakpoint(21, CLASS_NAME);

org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/sourcelookup/JavaStackFrameSourceDisplayAdapter.java:113

  • handleLambda connects the document provider to editorInput but never disconnects it. This can leak provider connections and keep resources pinned; follow the pattern used elsewhere (e.g., connect in a try/finally and always disconnect).
		IDocumentProvider provider = JavaUI.getDocumentProvider();
		IEditorInput editorInput = sourceRes.getEditorInput();
		provider.connect(editorInput);
		IDocument document = provider.getDocument(editorInput);
		IRegion region = document.getLineInformation(jdiFrame.getLineNumber() - 1);

org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/sourcelookup/JavaStackFrameSourceDisplayAdapter.java:94

  • ensureListenerRegistered(page) is invoked both in displaySource (after handleClassFile returns true) and again inside handleClassFile. This duplication makes the control flow harder to follow; please keep the call in only one place (preferably the caller) so listener registration is centralized.
			if (sourceRes.getEditorInput() instanceof IClassFileEditorInput input) {
				if (handleClassFile(page, jdiFrame, input)) {
					ensureListenerRegistered(page);
					return;
				}

org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/sourcelookup/JavaDebugShowInAdapterFactory.java:31

  • The adapter factory now reuses a single JavaStackFrameSourceDisplayAdapter instance across all stack frames/pages. Since the adapter stores mutable state (currentClassFileEditor/currentClassFileFrame and a single classFileUnhighlighterRegistered flag), stepping/highlighting in one workbench window/page can interfere with another, and ensureListenerRegistered will only ever register a listener for the first window/page encountered. Consider scoping state/listeners per workbench window (or not reusing a single adapter instance).
	private JavaStackFrameSourceDisplayAdapter javaStackFrameSourceDisplayAdapter = new JavaStackFrameSourceDisplayAdapter();


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@danthe1st
Copy link
Author

danthe1st commented Feb 28, 2026

I implemented some of the suppressed Copilot changes I consider to make sense but didn't implement the change in the review comment as this isn't really code I added.

Regarding the information about this being a prototype: I forgot to remove that from the PR description (done now).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants