Skip to content

Chrome debugger: Stepping over await operator jumps to end of function #724

Open
@martinhiller

Description

@martinhiller

If the Chrome debugger is paused on a line with an await operator and you step over the next function call (F10), then the debugger does not pause in the next line, but jumps to the end of the current function.

Reproduction:

  • Launch the unit test below.
  • Open the debugger URL in Chrome: devtools://devtools/bundled/js_app.html?ws=127.0.0.1:4242/debug
  • Advance the debugger until you end up in line 3: const result = await compute();
  • Use the Step over next function call button or press F10.

Before:

image

After "Step over":

image

As a user, you would expect the debugger to pause in line 4, as it is also the case if you run the same scripts in Chrome natively.
For completeness, this is the DevTools protocol log: ProtocolMonitor-20230420T154826.json.log

Tested with GraalVM 22.3.1 on Java 17.

Test:

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.concurrent.CompletableFuture;

import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;
import org.graalvm.polyglot.proxy.ProxyExecutable;
import org.junit.jupiter.api.Test;

public class DebugAwaitTest {

    @Test
    void stepOverAwait() {
        try (Context context = Context.newBuilder("js")
                .option("inspect", "4242")
                .option("inspect.Suspend", "false")
                .option("inspect.WaitAttached", "true")
                .option("inspect.Path", "debug")
                .build()) {
            context.eval("js", """
                    async function compute() {
                        return Promise.resolve(42);
                    }
                    """);
            CompletableFuture<Integer> resultFuture = new CompletableFuture<>();
            Value promise = context.eval("js", """
                    (async function () {
                        debugger;
                        const result = await compute();
                        return result + 1;
                    })()
                    """);
            promise.invokeMember("then", (ProxyExecutable) args -> {
                resultFuture.complete(args[0].asInt());
                return null;
            });
            assertEquals(43, resultFuture.join());
        }
    }
}

Metadata

Metadata

Assignees

Labels

toolingTools like debugger, profiler, memtracer, etc.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions