Wasm: fix issues with debugger

This commit is contained in:
Alexey Andreev 2022-12-13 18:51:19 +01:00
parent a6add26aaa
commit 313e4ed87f
7 changed files with 60 additions and 32 deletions

View File

@ -59,8 +59,8 @@ public class LineInfoUnpackedSequence {
}
var index = CollectionUtil.binarySearch(locations, address, InstructionLocation::address);
if (index < 0) {
index = -index;
index = -index - 2;
}
return Math.min(locations.size() - 1, index);
return index;
}
}

View File

@ -18,14 +18,9 @@ package org.teavm.backend.wasm.debug.info;
import com.carrotsearch.hppc.IntArrayDeque;
import com.carrotsearch.hppc.IntHashSet;
import com.carrotsearch.hppc.IntSet;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.teavm.backend.wasm.debug.parser.DebugInfoParser;
import org.teavm.common.ByteArrayAsyncInputStream;
import org.teavm.common.CollectionUtil;
public class StepLocationsFinder {
@ -208,16 +203,4 @@ public class StepLocationsFinder {
this.address = address;
}
}
public static void main(String[] args) throws IOException {
var file = new File("/home/konsoletyper/prog/apache-tomcat-10.0.4/webapps/wasm/classes.wasm");
var input = new ByteArrayAsyncInputStream(Files.readAllBytes(file.toPath()));
var parser = new DebugInfoParser(input);
input.readFully(parser::parse);
var debugInfo = parser.getDebugInfo();
var finder = new StepLocationsFinder(debugInfo);
finder.step("org/teavm/samples/wasi/WasiTest2.java", 9, 0x943e + debugInfo.offset(), false);
System.out.println(Arrays.toString(finder.getBreakpointAddresses()));
}
}

View File

@ -73,6 +73,7 @@ public class ControlFlowParser implements CodeSectionListener, CodeListener, Add
var token = blocks.size();
var branch = !loop ? newPendingBranch(false) : null;
var block = new Block(branch, address);
block.loop = loop;
blocks.add(block);
if (branch != null) {
block.pendingBranches.add(branch);
@ -135,17 +136,16 @@ public class ControlFlowParser implements CodeSectionListener, CodeListener, Add
if (opcode == BranchOpcode.BR_IF) {
pendingBranches.add(branch);
}
var block = blocks.get(target);
block.pendingBranches.add(branch);
branch.jumpTo(blocks.get(target));
}
@Override
public void tableBranch(int[] depths, int[] targets, int defaultDepth, int defaultTarget) {
var branch = newPendingBranch(false);
for (var target : targets) {
blocks.get(target).pendingBranches.add(branch);
branch.jumpTo(blocks.get(target));
}
blocks.get(defaultTarget).pendingBranches.add(branch);
branch.jumpTo(blocks.get(defaultDepth));
}
private Branch newPendingBranch(boolean isCall) {
@ -185,6 +185,7 @@ public class ControlFlowParser implements CodeSectionListener, CodeListener, Add
private static class Block {
Branch branch;
boolean loop;
final int address;
List<Branch> pendingBranches = new ArrayList<>();
@ -203,5 +204,13 @@ public class ControlFlowParser implements CodeSectionListener, CodeListener, Add
this.address = address;
this.isCall = isCall;
}
void jumpTo(Block block) {
if (block.loop) {
targets.add(block.address);
} else {
block.pendingBranches.add(this);
}
}
}
}

View File

@ -1463,26 +1463,40 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
WasmIntBinary binary = (WasmIntBinary) expr;
if (binary.getType() == WasmIntType.INT32 && binary.getOperation() == WasmIntBinaryOperation.XOR) {
if (isOne(binary.getFirst())) {
return binary.getSecond();
var result = binary.getSecond();
if (result.getLocation() == null && expr.getLocation() != null) {
result.setLocation(expr.getLocation());
}
return result;
}
if (isOne(binary.getSecond())) {
return binary.getFirst();
var result = binary.getFirst();
if (result.getLocation() == null && expr.getLocation() != null) {
result.setLocation(expr.getLocation());
}
return result;
}
}
WasmIntBinaryOperation negatedOp = negate(binary.getOperation());
if (negatedOp != null) {
return new WasmIntBinary(binary.getType(), negatedOp, binary.getFirst(), binary.getSecond());
var result = new WasmIntBinary(binary.getType(), negatedOp, binary.getFirst(), binary.getSecond());
result.setLocation(expr.getLocation());
return result;
}
} else if (expr instanceof WasmFloatBinary) {
WasmFloatBinary binary = (WasmFloatBinary) expr;
WasmFloatBinaryOperation negatedOp = negate(binary.getOperation());
if (negatedOp != null) {
return new WasmFloatBinary(binary.getType(), negatedOp, binary.getFirst(), binary.getSecond());
var result = new WasmFloatBinary(binary.getType(), negatedOp, binary.getFirst(), binary.getSecond());
result.setLocation(expr.getLocation());
return result;
}
}
return new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.EQ, expr, new WasmInt32Constant(0));
var result = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.EQ, expr, new WasmInt32Constant(0));
result.setLocation(expr.getLocation());
return result;
}
private static boolean isOne(WasmExpression expression) {

View File

@ -86,6 +86,7 @@ public class ChromeRDPDebugger extends BaseChromeRDPDebugger implements JavaScri
protected void onDetach() {
suspended = false;
callStack = null;
}
private Promise<Void> injectFunctions(int contextId) {
@ -119,6 +120,7 @@ public class ChromeRDPDebugger extends BaseChromeRDPDebugger implements JavaScri
protected Promise<Void> handleMessage(Message message) throws IOException {
switch (message.getMethod()) {
case "TeaVM.ping":
sendPong();
return Promise.VOID;
case "Debugger.paused":
return firePaused(parseJson(SuspendedNotification.class, message.getParams()));
@ -130,6 +132,12 @@ public class ChromeRDPDebugger extends BaseChromeRDPDebugger implements JavaScri
return Promise.VOID;
}
private void sendPong() {
var message = new Message();
message.setMethod("TeaVM.pong");
sendMessage(message);
}
private Promise<Void> firePaused(SuspendedNotification params) {
suspended = true;
CallFrameDTO[] callFrameDTOs = params.getCallFrames();

View File

@ -90,6 +90,7 @@ public final class ChromeRDPRunner {
@Override
public void detached() {
queue.offer(() -> { });
}
};
@ -121,6 +122,7 @@ public final class ChromeRDPRunner {
}
}).start();
} else if (!debugger.isAttached() && wasAttached) {
System.out.println("Detached");
break;
}
}

View File

@ -45,20 +45,32 @@ class DebuggerAgent {
this.sendMessage(pendingMessage);
}
this.pendingMessages = null;
this.pingTimeout = setInterval(() => {
this.sendMessage({ method: "TeaVM.ping" });
}, 2000);
this.sendPing();
};
}
sendPing() {
this.sendMessage({ method: "TeaVM.ping" });
}
schedulePing() {
this.pingTimeout = setTimeout(() => {
this.sendPing();
}, 2000);
}
stopPing() {
if (this.pingTimeout != null) {
clearInterval(this.pingTimeout);
clearTimeout(this.pingTimeout);
this.pingTimeout = null;
}
}
receiveMessage(message) {
if (message.method === "TeaVM.pong") {
this.schedulePing();
return;
}
chrome.debugger.sendCommand(this.debuggee, message.method, message.params, response => {
if (message.id) {
const responseToServer = {