Skip to content

Commit 83f2822

Browse files
committed
Negative offset read optimisation
1 parent 8cd7292 commit 83f2822

File tree

3 files changed

+38
-40
lines changed

3 files changed

+38
-40
lines changed

src/gdb/GDBDebugSessionBase.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -1387,11 +1387,9 @@ export abstract class GDBDebugSessionBase extends LoggingDebugSession {
13871387
};
13881388
this.sendResponse(response);
13891389
} catch (err) {
1390-
this.sendErrorResponse(
1391-
response,
1392-
1,
1393-
err instanceof Error ? err.message : String(err)
1394-
);
1390+
const message = err instanceof Error ? err.message : String(err);
1391+
this.sendEvent(new OutputEvent(`Error: ${message}`));
1392+
this.sendErrorResponse(response, 1, message);
13951393
}
13961394
}
13971395

src/integration-tests/diassemble.spec.ts

+11-23
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import * as path from 'path';
1313
import { DebugProtocol } from '@vscode/debugprotocol/lib/debugProtocol';
1414
import { CdtDebugClient } from './debugClient';
1515
import { fillDefaults, standardBeforeEach, testProgramsDir } from './utils';
16-
import { calculateMemoryOffset } from '../util/calculateMemoryOffset';
1716
import { assert } from 'sinon';
1817

1918
describe('Disassembly Test Suite', function () {
@@ -180,28 +179,17 @@ describe('Disassembly Test Suite', function () {
180179
);
181180
});
182181

183-
it('can handle disassemble at bad address', async function () {
184-
const disassemble = (await dc.send('disassemble', {
185-
memoryReference: '0x0',
186-
instructionCount: 10,
187-
})) as DebugProtocol.DisassembleResponse;
188-
189-
expect(disassemble).not.eq(undefined);
190-
expect(disassemble.body).not.eq(undefined);
191-
if (disassemble.body) {
192-
const instructions = disassemble.body.instructions;
193-
expect(instructions).to.have.lengthOf(10);
194-
// Checking the invalid instructions content
195-
instructions.forEach((inst, ix) => {
196-
expect(inst.address).to.eq(
197-
calculateMemoryOffset('0x0', ix * 2)
198-
);
199-
expect(inst.address).to.have.lengthOf.greaterThan(0);
200-
expect(inst.instruction).to.eq(
201-
'failed to retrieve instruction'
202-
);
203-
expect(inst.presentationHint).to.eq('invalid');
204-
});
182+
it('return error at bad address', async function () {
183+
try {
184+
await dc.send('disassemble', {
185+
memoryReference: '0x0',
186+
instructionCount: 10,
187+
} as DebugProtocol.DisassembleArguments);
188+
assert.fail('Should throw error!');
189+
} catch (e) {
190+
expect(e).to.be.deep.equal(
191+
new Error('Cannot access memory at address 0x0')
192+
);
205193
}
206194
});
207195
});

src/util/disassembly.ts

+24-12
Original file line numberDiff line numberDiff line change
@@ -178,22 +178,16 @@ export const getInstructions = async (
178178
if (result.length === 0) {
179179
// If cannot retrieve more instructions, break the loop, go to catch
180180
// and fill the remaining instructions with empty instruction information
181-
throw new Error('Cannot retrieve more instructions!');
181+
break;
182182
}
183183
pushToList(result);
184184
}
185185
} catch (e) {
186-
// Fill with empty instructions in case of memory error.
187-
const lastMemoryAddress =
188-
list.length === 0
189-
? memoryReference
190-
: list[isReverseFetch ? 0 : list.length - 1].address;
191-
const emptyInstuctions = getEmptyInstructions(
192-
lastMemoryAddress,
193-
remainingLength(),
194-
2
195-
);
196-
pushToList(emptyInstuctions);
186+
// If error occured in the first iteration and no items can be read
187+
// throw the original error, otherwise continue and fill the empty instructions.
188+
if (list.length === 0) {
189+
throw e;
190+
}
197191
}
198192

199193
if (absLength < list.length) {
@@ -206,5 +200,23 @@ export const getInstructions = async (
206200
}
207201
}
208202

203+
// Fill with empty instructions in case couldn't read desired length
204+
if (absLength > list.length) {
205+
if (list.length === 0) {
206+
// In case of memory read error, where no instructions read before you cannot be sure about the memory offsets
207+
// Avoid sending empty instructions, which is overriding the previous disassembled instructions in the VSCode
208+
// Instead, send error message and fail the request.
209+
throw new Error(`Cannot retrieve instructions!`);
210+
}
211+
const lastMemoryAddress =
212+
list[isReverseFetch ? 0 : list.length - 1].address;
213+
const emptyInstuctions = getEmptyInstructions(
214+
lastMemoryAddress,
215+
absLength - list.length,
216+
Math.sign(length) * 2
217+
);
218+
pushToList(emptyInstuctions);
219+
}
220+
209221
return list;
210222
};

0 commit comments

Comments
 (0)