fix(debug): prefer dlv for go directory launches

Prefer directory-capable adapters when selecting a launch adapter for a
resolved directory program. This keeps Go package directories on dlv in
mixed projects that also expose native-debugger root markers such as a
Makefile, instead of selecting gdb/lldb-dap first and rejecting the
directory during validation.

Added a regression test covering a Go module with both go.mod and
Makefile plus local dlv/gdb adapter shims.

Fixes #2020
This commit is contained in:
roboomp
2026-06-07 03:03:57 +00:00
parent 1745529368
commit 8c25f7d4aa
4 changed files with 48 additions and 4 deletions
@@ -411,6 +411,43 @@ describe("DebugTool launch validation", () => {
}
});
it("prefers directory-capable dlv over native adapters for extensionless Go package directories", async () => {
const dapModule = await import("../../src/dap");
const sessionLaunchSpy = spyOn(dapModule.dapSessionManager, "launch").mockImplementation(async opts => {
throw Object.assign(new Error("captured launch"), { capturedOptions: opts });
});
try {
const cwd = await fs.mkdtemp(path.join(os.tmpdir(), "omp-debug-dlv-mixed-roots-"));
try {
await fs.writeFile(path.join(cwd, "go.mod"), "module hello\n\ngo 1.22\n");
await fs.writeFile(path.join(cwd, "Makefile"), "all:\n\tgo build ./...\n");
await fs.mkdir(path.join(cwd, "bin"));
await fs.writeFile(path.join(cwd, "bin", "dlv"), "");
await fs.writeFile(path.join(cwd, "bin", "gdb"), "");
await fs.mkdir(path.join(cwd, "cmd", "hello"), { recursive: true });
const session: ToolSession = {
cwd,
hasUI: false,
getSessionFile: () => null,
getSessionSpawns: () => "*",
settings: Settings.isolated({ "debug.enabled": true }),
};
const tool = new DebugTool(session);
await expect(tool.execute("call", { action: "launch", program: "cmd/hello" })).rejects.toThrow(
/captured launch/,
);
const [opts] = sessionLaunchSpy.mock.calls[0]!;
expect(opts.adapter.name).toBe("dlv");
expect(opts.extraLaunchArguments).toEqual({ mode: "debug" });
} finally {
await fs.rm(cwd, { recursive: true, force: true });
}
} finally {
sessionLaunchSpy.mockRestore();
}
});
it("dlv launch with a compiled binary switches mode from debug to exec", async () => {
const dapModule = await import("../../src/dap");
const dlvAdapter: DapResolvedAdapter = {