Skip to content

Commit 511b4e9

Browse files
committed
Remove parenthesis cleanup & extra getFullPathExpression() calls
The total removal of parenthesis removes casting parenthesis and breaks potential watch expressions so this cleanup should be removed. Instead of calling getFullPathExpression() multiple times, build the fullPath from the topLevelExpression variable. In the case of Expressions, add encapsulating parenthesis to handle type casting properly. Update variable casting tests accordingly.
1 parent 2cec653 commit 511b4e9

File tree

3 files changed

+102
-27
lines changed

3 files changed

+102
-27
lines changed

src/GDBDebugSession.ts

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,10 +2088,15 @@ export class GDBDebugSession extends LoggingDebugSession {
20882088
});
20892089
}
20902090
// Grab the full path of parent.
2091-
const topLevelPathExpression =
2091+
const tempTopLevelPathExpression =
20922092
varobj?.expression ??
20932093
(await this.getFullPathExpression(parentVarname));
20942094

2095+
// In the case of Expressions, there might be casting, so add outer ()
2096+
const topLevelPathExpression = varobj?.isVar
2097+
? tempTopLevelPathExpression
2098+
: `(${tempTopLevelPathExpression})`;
2099+
20952100
// iterate through the children
20962101
for (const child of children.children) {
20972102
// check if we're dealing with a C++ object. If we are, we need to fetch the grandchildren instead.
@@ -2123,25 +2128,24 @@ export class GDBDebugSession extends LoggingDebugSession {
21232128
}
21242129
} else {
21252130
// check if we're dealing with an array
2126-
let name = `${ref.varobjName}.${child.exp}`;
2127-
let varobjName = name;
2131+
let variableName = child.exp;
2132+
let varobjName = `${ref.varobjName}.${child.exp}`;
2133+
let fullPath = `${topLevelPathExpression}.${variableName}`;
21282134
let value = child.value ? child.value : child.type;
21292135
const isArrayParent = arrayRegex.test(child.type);
21302136
const isArrayChild =
21312137
varobj !== undefined
21322138
? arrayRegex.test(varobj.type) &&
21332139
arrayChildRegex.test(child.exp)
21342140
: false;
2135-
if (isArrayChild) {
2136-
// update the display name for array elements to have square brackets
2137-
name = `[${child.exp}]`;
2138-
}
21392141
if (isArrayParent || isArrayChild) {
21402142
// can't use a relative varname (eg. var1.a.b.c) to create/update a new var so fetch and track these
21412143
// vars by evaluating their path expression from GDB
2142-
const fullPath = await this.getFullPathExpression(
2143-
child.name
2144-
);
2144+
if (isArrayChild) {
2145+
// update the display name for array elements to have square brackets
2146+
variableName = `[${child.exp}]`;
2147+
fullPath = `(${topLevelPathExpression})${variableName}`;
2148+
}
21452149
// create or update the var in GDB
21462150
let arrobj = this.gdb.varManager.getVar(
21472151
frame.frameId,
@@ -2182,14 +2186,9 @@ export class GDBDebugSession extends LoggingDebugSession {
21822186
arrobj.isChild = true;
21832187
varobjName = arrobj.varname;
21842188
}
2185-
const variableName = isArrayChild ? name : child.exp;
2186-
const evaluateName =
2187-
isArrayParent || isArrayChild
2188-
? await this.getFullPathExpression(child.name)
2189-
: `${topLevelPathExpression}.${child.exp}`;
21902189
variables.push({
21912190
name: variableName,
2192-
evaluateName,
2191+
evaluateName: fullPath,
21932192
value,
21942193
type: child.type,
21952194
variablesReference:
@@ -2212,8 +2211,8 @@ export class GDBDebugSession extends LoggingDebugSession {
22122211
this.gdb,
22132212
inputVarName
22142213
);
2215-
// result from GDB looks like (parentName).field so remove ().
2216-
return exprResponse.path_expr.replace(/[()]/g, '');
2214+
// GDB result => (parentName).field
2215+
return exprResponse.path_expr;
22172216
}
22182217

22192218
// Register view

src/integration-tests/test-programs/vars.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@ int main()
3232
int rax = 1;
3333
const unsigned char h[] = {0x01, 0x10, 0x20};
3434
const unsigned char k[] = "hello"; // char string setup
35+
r.z.a = 10; // update embedded int
3536
return 0;
3637
}

src/integration-tests/var.spec.ts

Lines changed: 84 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { expect } from 'chai';
1212
import * as path from 'path';
1313
import { CdtDebugClient } from './debugClient';
1414
import {
15-
expectRejection,
1615
getScopes,
1716
resolveLineTagLocations,
1817
Scope,
@@ -37,6 +36,7 @@ describe('Variables Test Suite', function () {
3736
'STOP HERE': 0,
3837
'After array init': 0,
3938
'char string setup': 0,
39+
'update embedded int': 0,
4040
};
4141

4242
const hexValueRegex = /^0x[\da-fA-F]+$/;
@@ -557,7 +557,7 @@ describe('Variables Test Suite', function () {
557557
);
558558
});
559559

560-
it('catch error from casting of struct to a character array', async function () {
560+
it('support watch a character array', async function () {
561561
// skip ahead to array initialization
562562
const br = await dc.setBreakpointsRequest({
563563
source: { path: varsSrc },
@@ -586,13 +586,88 @@ describe('Variables Test Suite', function () {
586586
});
587587
expect(res2.body.result).eq('[6]');
588588
// Call handleVariableRequestObject() on above using returned variablesReference.
589-
const error = await expectRejection(
590-
dc.variablesRequest({
591-
variablesReference: res2.body.variablesReference,
592-
})
593-
);
594-
expect(error.message).contains(
595-
'-var-create: unable to create variable object'
589+
const vars = await dc.variablesRequest({
590+
variablesReference: res2.body.variablesReference,
591+
});
592+
expect(
593+
vars.body.variables.length,
594+
'There is a different number of variables than expected'
595+
).to.equal(6);
596+
verifyVariable(vars.body.variables[0], '[0]', 'char', "104 'h'", {
597+
hasMemoryReference: false,
598+
});
599+
verifyVariable(vars.body.variables[1], '[1]', 'char', "101 'e'", {
600+
hasMemoryReference: false,
601+
});
602+
});
603+
604+
it.only('support watch of char cast of an int in complex structure', async function () {
605+
// skip ahead to array initialization
606+
const br = await dc.setBreakpointsRequest({
607+
source: { path: varsSrc },
608+
breakpoints: [{ line: lineTags['update embedded int'] }],
609+
});
610+
expect(br.success).to.equal(true);
611+
await dc.continue({ threadId: scope.thread.id }, 'breakpoint', {
612+
line: lineTags['update embedded int'],
613+
path: varsSrc,
614+
});
615+
scope = await getScopes(dc);
616+
expect(
617+
scope.scopes.body.scopes.length,
618+
'Unexpected number of scopes returned'
619+
).to.equal(2);
620+
// Setup the new variable to be evaluated.
621+
const res = await dc.evaluateRequest({
622+
context: 'watch',
623+
expression: '(char[])r.z.a',
624+
frameId: scope.frame.id,
625+
});
626+
expect(res.body.result).eq('[4]');
627+
// Call handleVariableRequestObject() on above using returned variablesReference.
628+
let vars = await dc.variablesRequest({
629+
variablesReference: res.body.variablesReference,
630+
});
631+
expect(
632+
vars.body.variables.length,
633+
'There is a different number of variables than expected'
634+
).to.equal(4);
635+
verifyVariable(vars.body.variables[0], '[0]', 'char', "3 '\\003'", {
636+
hasMemoryReference: false,
637+
});
638+
verifyVariable(vars.body.variables[1], '[1]', 'char', "0 '\\000'", {
639+
hasMemoryReference: false,
640+
});
641+
// step the program and see that the values were passed to the program and evaluated.
642+
await dc.next(
643+
{ threadId: scope.thread.id },
644+
{ path: varsSrc, line: lineTags['update embedded int'] + 1 }
596645
);
646+
scope = await getScopes(dc);
647+
expect(
648+
scope.scopes.body.scopes.length,
649+
'Unexpected number of scopes returned'
650+
).to.equal(2);
651+
// Setup the updated embedded variable to be evaluated.
652+
const res2 = await dc.evaluateRequest({
653+
context: 'watch',
654+
expression: '(char[])r.z.a',
655+
frameId: scope.frame.id,
656+
});
657+
expect(res2.body.result).eq('[4]');
658+
// Call handleVariableRequestObject() on above using returned variablesReference.
659+
vars = await dc.variablesRequest({
660+
variablesReference: res2.body.variablesReference,
661+
});
662+
expect(
663+
vars.body.variables.length,
664+
'There is a different number of variables than expected'
665+
).to.equal(4);
666+
verifyVariable(vars.body.variables[0], '[0]', 'char', "10 '\\n'", {
667+
hasMemoryReference: false,
668+
});
669+
verifyVariable(vars.body.variables[1], '[1]', 'char', "0 '\\000'", {
670+
hasMemoryReference: false,
671+
});
597672
});
598673
});

0 commit comments

Comments
 (0)