Skip to content

Commit d96719d

Browse files
committed
merge bugfix for #831
1 parent 7f8b02e commit d96719d

File tree

4 files changed

+77
-111
lines changed

4 files changed

+77
-111
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
ChangeLog
22
=========
33

4-
# V1.7.0 - Major release only available as a Pre-release.
4+
# V1.7.1 - Major release only available as a Pre-release.
55
* This is a preview (Pre-release). The biggest feature is the addition of Live Watch. In your launch.json add an object property called `liveWatch` and Intellisense should fill out a template to enable Live Watch.
66
```
77
"liveWatch": {
@@ -11,6 +11,7 @@ ChangeLog
1111
```
1212
* There are tons of other changes planned as pre-releases and they will have versions 1.7.x (this is a Microsoft convention). There has been some major restructuring of our code and as such, this version may not be as stable as the production releases. **Please help us get to production**
1313
* To enable Pre-releases, you have use the Extension Manager/Pane within VSCode
14+
* Bugfix: [#831 Unable to read variables during 2nd breakpoint stop](https://github.com/Marus/cortex-debug/issues/831)
1415

1516
# V1.6.10
1617
* [Issue#793 Container install broke from v1.6.7 to v1.6.9](https://github.com/Marus/cortex-debug/issues/793). It appears that VSCode does not install extensions with dependencies fully. Ie, if ext. `a` depends on `b` which depends on `c`, `c` is not installed so extension `a` fails to load properly. While we confirm, report this issue to VSCode folks, a (ugly) workaround has been implemented.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "1.7.0",
2+
"version": "1.7.1-pre1",
33
"preview": false,
44
"activationEvents": [
55
"onDebugResolve:cortex-debug",

src/gdb.ts

+70-105
Original file line numberDiff line numberDiff line change
@@ -2639,50 +2639,86 @@ export class GDBDebugSession extends LoggingDebugSession {
26392639
this.sendResponse(response);
26402640
}
26412641

2642-
private async globalVariablesRequest(response: DebugProtocol.VariablesResponse, args: DebugProtocol.VariablesArguments): Promise<void> {
2643-
const symbolInfo: SymbolInformation[] = this.symbolTable.getGlobalVariables();
2644-
2645-
const globals: DebugProtocol.Variable[] = [];
2642+
private async updateOrCreateVariable(
2643+
symOrExpr: string, gdbVarName: string, parentVarReference: number,
2644+
threadId: number, frameId: number, isFloating: boolean): Promise<DebugProtocol.Variable> {
26462645
try {
2647-
for (const symbol of symbolInfo) {
2648-
const varObjName = `global_var_${symbol.name}`;
2649-
let varObj: VariableObject;
2650-
try {
2651-
const changes = await this.miDebugger.varUpdate(varObjName, -1, -1);
2652-
const changelist = changes.result('changelist');
2653-
changelist.forEach((change) => {
2646+
let varObj: VariableObject;
2647+
let outOfScope = false;
2648+
try {
2649+
const changes = await this.miDebugger.varUpdate(gdbVarName, threadId, frameId);
2650+
const changelist = changes.result('changelist');
2651+
for (const change of changelist || []) {
2652+
const inScope = MINode.valueOf(change, 'in_scope');
2653+
if (inScope === 'true') {
26542654
const name = MINode.valueOf(change, 'name');
26552655
const vId = this.variableHandlesReverse[name];
26562656
const v = this.variableHandles.get(vId) as any;
2657-
v.applyChanges(change);
2658-
});
2659-
const varId = this.variableHandlesReverse[varObjName];
2660-
varObj = this.variableHandles.get(varId) as any;
2657+
v.applyChanges(change /*, variable.valueStr*/);
2658+
} else {
2659+
const msg = `${symOrExpr} currently not in scope`;
2660+
await this.miDebugger.sendCommand(`var-delete ${gdbVarName}`);
2661+
if (this.args.showDevDebugOutput) {
2662+
this.handleMsg('log', `Expression ${msg}. Will try to create again\n`);
2663+
}
2664+
outOfScope = true;
2665+
throw new Error(msg);
2666+
}
26612667
}
2662-
catch (err) {
2663-
try {
2664-
if (err instanceof MIError && err.message === 'Variable object not found') {
2665-
varObj = await this.miDebugger.varCreate(args.variablesReference, symbol.name, varObjName);
2666-
const varId = this.findOrCreateVariable(varObj);
2667-
varObj.exp = symbol.name;
2668-
varObj.id = varId;
2668+
const varId = this.variableHandlesReverse[gdbVarName];
2669+
varObj = this.variableHandles.get(varId) as any;
2670+
}
2671+
catch (err) {
2672+
try {
2673+
if (outOfScope || (err instanceof MIError && err.message === 'Variable object not found')) {
2674+
// Create variable in current frame/thread context. Matters when we have to set the variable */
2675+
if (isFloating) {
2676+
varObj = await this.miDebugger.varCreate(parentVarReference, symOrExpr, gdbVarName);
26692677
} else {
2670-
throw err;
2678+
varObj = await this.miDebugger.varCreate(parentVarReference, symOrExpr, gdbVarName, '*', threadId, frameId);
26712679
}
2680+
const varId = this.findOrCreateVariable(varObj);
2681+
varObj.exp = symOrExpr;
2682+
varObj.id = varId;
2683+
} else if (isFloating) {
2684+
throw err;
26722685
}
2673-
catch (err) {
2686+
}
2687+
catch (err) {
2688+
if (isFloating) {
26742689
if (this.args.showDevDebugOutput) {
2675-
this.handleMsg('stderr', `Could not create global variable ${symbol.name}\n`);
2690+
this.handleMsg('stderr', `Could not create global/static variable ${symOrExpr}\n`);
26762691
this.handleMsg('stderr', `Error: ${err}\n`);
26772692
}
26782693
varObj = null;
2694+
} else {
2695+
throw err;
26792696
}
26802697
}
2698+
}
2699+
if (isFloating && varObj) {
2700+
this.putFloatingVariable(parentVarReference, symOrExpr, varObj);
2701+
}
2702+
return varObj?.toProtocolVariable();
2703+
}
2704+
catch (err) {
2705+
const ret: DebugProtocol.Variable = {
2706+
name: symOrExpr,
2707+
value: `<${err}>`,
2708+
variablesReference: 0
2709+
};
2710+
return ret;
2711+
}
2712+
}
26812713

2682-
if (varObj) {
2683-
this.putFloatingVariable(args.variablesReference, symbol.name, varObj);
2684-
globals.push(varObj.toProtocolVariable());
2685-
}
2714+
private async globalVariablesRequest(response: DebugProtocol.VariablesResponse, args: DebugProtocol.VariablesArguments): Promise<void> {
2715+
const symbolInfo: SymbolInformation[] = this.symbolTable.getGlobalVariables();
2716+
const globals: DebugProtocol.Variable[] = [];
2717+
try {
2718+
for (const symbol of symbolInfo) {
2719+
const varObjName = `global_var_${symbol.name}`;
2720+
const tmp = await this.updateOrCreateVariable(symbol.name, varObjName, args.variablesReference, -1, -1, true);
2721+
globals.push(tmp);
26862722
}
26872723

26882724
response.body = { variables: globals };
@@ -2744,46 +2780,8 @@ export class GDBDebugSession extends LoggingDebugSession {
27442780

27452781
for (const symName of staticNames) {
27462782
const varObjName = this.createStaticVarName(fHash, symName);
2747-
let varObj: VariableObject;
2748-
try {
2749-
const changes = await this.miDebugger.varUpdate(varObjName, -1, -1);
2750-
const changelist = changes.result('changelist');
2751-
changelist.forEach((change) => {
2752-
const name = MINode.valueOf(change, 'name');
2753-
const vId = this.variableHandlesReverse[name];
2754-
const v = this.variableHandles.get(vId) as any;
2755-
v.applyChanges(change);
2756-
});
2757-
const varId = this.variableHandlesReverse[varObjName];
2758-
varObj = this.variableHandles.get(varId) as any;
2759-
}
2760-
catch (err) {
2761-
try {
2762-
// Not all static variables found via objdump can be found with gdb. Happens
2763-
// with function/block scoped static variables (objdump uses one name and gdb uses another)
2764-
// Try to report what we can. Others show up under the Locals section hopefully.
2765-
if (err instanceof MIError && err.message === 'Variable object not found') {
2766-
varObj = await this.miDebugger.varCreate(args.variablesReference, symName, varObjName);
2767-
const varId = this.findOrCreateVariable(varObj);
2768-
varObj.exp = symName;
2769-
varObj.id = varId;
2770-
} else {
2771-
throw err;
2772-
}
2773-
}
2774-
catch (err) {
2775-
if (this.args.showDevDebugOutput) {
2776-
this.handleMsg('stderr', `Could not create static variable ${file}:${symName}\n`);
2777-
this.handleMsg('stderr', `Error: ${err}\n`);
2778-
}
2779-
varObj = null;
2780-
}
2781-
}
2782-
2783-
if (varObj) {
2784-
this.putFloatingVariable(args.variablesReference, symName, varObj);
2785-
statics.push(varObj.toProtocolVariable());
2786-
}
2783+
const tmp = await this.updateOrCreateVariable(symName, varObjName, args.variablesReference, threadId, frameId, true);
2784+
statics.push(tmp);
27872785
}
27882786

27892787
response.body = { variables: statics };
@@ -2835,42 +2833,9 @@ export class GDBDebugSession extends LoggingDebugSession {
28352833
await this.miDebugger.sendCommand(`stack-select-frame --thread ${threadId} ${frameId}`);
28362834
stack = await this.miDebugger.getStackVariables(threadId, frameId);
28372835
for (const variable of stack) {
2838-
try {
2839-
const varObjName = this.createStackVarName(variable.name, args.variablesReference);
2840-
let varObj: VariableObject;
2841-
try {
2842-
const changes = await this.miDebugger.varUpdate(varObjName, threadId, frameId);
2843-
const changelist = changes.result('changelist');
2844-
changelist.forEach((change) => {
2845-
const name = MINode.valueOf(change, 'name');
2846-
const vId = this.variableHandlesReverse[name];
2847-
const v = this.variableHandles.get(vId) as any;
2848-
v.applyChanges(change/*, variable.valueStr*/);
2849-
});
2850-
const varId = this.variableHandlesReverse[varObjName];
2851-
varObj = this.variableHandles.get(varId) as any;
2852-
}
2853-
catch (err) {
2854-
if (err instanceof MIError && err.message === 'Variable object not found') {
2855-
// Create variable in current frame/thread context. Matters when we have to set the variable */
2856-
varObj = await this.miDebugger.varCreate(args.variablesReference, variable.name, varObjName, '*', threadId, frameId);
2857-
const varId = this.findOrCreateVariable(varObj);
2858-
varObj.exp = variable.name;
2859-
varObj.id = varId;
2860-
}
2861-
else {
2862-
throw err;
2863-
}
2864-
}
2865-
variables.push(varObj.toProtocolVariable());
2866-
}
2867-
catch (err) {
2868-
variables.push({
2869-
name: variable.name,
2870-
value: `<${err}>`,
2871-
variablesReference: 0
2872-
});
2873-
}
2836+
const varObjName = this.createStackVarName(variable.name, args.variablesReference);
2837+
const tmp = await this.updateOrCreateVariable(variable.name, varObjName, args.variablesReference, threadId, frameId, false);
2838+
variables.push(tmp);
28742839
}
28752840
response.body = {
28762841
variables: variables

src/gdb.ts.bak

+4-4
Original file line numberDiff line numberDiff line change
@@ -2861,7 +2861,7 @@ export class GDBDebugSession extends LoggingDebugSession {
28612861
}
28622862
else if (typeof id === 'object') {
28632863
if (id instanceof VariableObject) {
2864-
const pvar = id as VariableObject;
2864+
const pVar = id as VariableObject;
28652865

28662866
// Variable members
28672867
let children: VariableObject[];
@@ -2872,7 +2872,7 @@ export class GDBDebugSession extends LoggingDebugSession {
28722872
const varId = this.findOrCreateVariable(child);
28732873
child.id = varId;
28742874
if (/^\d+$/.test(child.exp)) {
2875-
child.fullExp = `${pvar.fullExp || pvar.exp}[${child.exp}]`;
2875+
child.fullExp = `${pVar.fullExp || pVar.exp}[${child.exp}]`;
28762876
}
28772877
else {
28782878
let suffix = '.' + child.exp; // A normal suffix
@@ -2887,9 +2887,9 @@ export class GDBDebugSession extends LoggingDebugSession {
28872887
} else {
28882888
// The full-name is not always derivable from the parent and child info. Esp. children
28892889
// of anonymous stuff. Might as well store all of them or set-value will not work.
2890-
pvar.children[child.exp] = child.name;
2890+
pVar.children[child.exp] = child.name;
28912891
}
2892-
child.fullExp = `${pvar.fullExp || pvar.exp}${suffix}`;
2892+
child.fullExp = `${pVar.fullExp || pVar.exp}${suffix}`;
28932893
}
28942894
return child.toProtocolVariable();
28952895
});

0 commit comments

Comments
 (0)