Skip to content

Commit 9ba130c

Browse files
committed
use memory references to read big strings from delve
1 parent a8264cd commit 9ba130c

File tree

1 file changed

+36
-15
lines changed

1 file changed

+36
-15
lines changed

extension/src/goDebugCommands.ts

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as vscode from 'vscode';
2+
import { TextDecoder } from 'util';
23

34
// Track sessions since vscode doesn't provide a list of them.
45
const sessions = new Map<string, vscode.DebugSession>();
@@ -25,21 +26,45 @@ export function registerGoDebugCommands(ctx: vscode.ExtensionContext) {
2526
const session = sessions.get(sessionId);
2627
if (!session) return 'Debug session has been terminated';
2728

28-
const r: { variables: Variable[] } = await session.customRequest('variables', {
29+
const { variables } = await session.customRequest('variables', {
2930
variablesReference: parseInt(container, 10)
30-
});
31+
}) as { variables: Variable[] };
3132

32-
const v = r.variables.find((v) => v.name === name);
33+
const v = variables.find(v => v.name === name);
3334
if (!v) return `Cannot resolve variable ${name}`;
3435

35-
const { result } = await session.customRequest('evaluate', {
36-
expression: v.evaluateName,
37-
context: 'clipboard'
38-
});
36+
if (!v.memoryReference) {
37+
const { result } = await session.customRequest('evaluate', {
38+
expression: v.evaluateName,
39+
context: 'clipboard'
40+
}) as { result: string };
41+
42+
v.value = result ?? v.value;
43+
44+
return parseVariable(v);
45+
}
46+
47+
const chunk = 1 << 14;
48+
let offset = 0;
49+
let full: Uint8Array[] = [];
3950

40-
v.value = result ?? v.value;
51+
while (true) {
52+
const resp = await session.customRequest('readMemory', {
53+
memoryReference: v.memoryReference,
54+
offset,
55+
count: chunk
56+
}) as { address: string; data: string; unreadableBytes: number };
4157

42-
return parseVariable(v);
58+
if (!resp.data) break;
59+
full.push(Buffer.from(resp.data, 'base64'));
60+
61+
if (resp.unreadableBytes === 0) break;
62+
offset += chunk;
63+
}
64+
65+
const allBytes = Buffer.concat(full);
66+
67+
return new TextDecoder('utf-8').decode(allBytes);
4368
}
4469
}
4570

@@ -72,6 +97,7 @@ export function registerGoDebugCommands(ctx: vscode.ExtensionContext) {
7297
value: string;
7398
evaluateName: string;
7499
variablesReference: number;
100+
memoryReference?: string;
75101
}
76102

77103
const escapeCodes: Record<string, string> = {
@@ -83,14 +109,9 @@ export function registerGoDebugCommands(ctx: vscode.ExtensionContext) {
83109
function parseVariable(variable: Variable) {
84110
let raw = variable.value.trim();
85111
try {
86-
// Attempt to parse as JSON
87112
return JSON.parse(raw);
88113
} catch (_) {
89-
// Fall back to manual unescaping
90-
raw = raw.slice(1, -1);
114+
return raw.replace(/\\[nrt\\"'`]/, (_, s) => (s in escapeCodes ? escapeCodes[s] : s));
91115
}
92-
93-
// Manually unescape
94-
return raw.replace(/\\[nrt\\"'`]/, (_, s) => (s in escapeCodes ? escapeCodes[s] : s));
95116
}
96117
}

0 commit comments

Comments
 (0)