Skip to content

Commit

Permalink
Allow display of local variables in frames multiple levels deep.
Browse files Browse the repository at this point in the history
Remove the arbitrary separation between the variable references used
to represent scopes and those used to represent variable objects.
This implementation uses a common pool of handles to support both
variable object references as well as scope references, thus
eliminating the previous bounded numerical range used for scopes,
which was not large enough to represent stack frames multiple levels
deep, due to thread and level information being encoded in the scope
variable reference value.
  • Loading branch information
brownts committed Apr 26, 2022
1 parent 15c8714 commit 6baa66b
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 18 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
# 0.26.0
# [Unreleased]
## Fixed
* Fixes #342 - Local variables not displayed more than 2 stack frames deep - PR #345 (@brownts)

[Unreleased]: https://github.com/WebFreak001/code-debug/compare/v0.26.0...HEAD

# [0.26.0] - 2022-04-16

* vscode dependency was increased from 1.28 to 1.55 along with the debug-adapter protocol to get rid of some outdated dependencies (@GitMensch)
* SSH2 module updated from deprecated 0.8.9 to current 1.6.0 (@GitMensch),
Expand All @@ -21,6 +27,8 @@
* Extra debugger arguments now work in all configurations #316, #338 fixing #206 (@GitMensch, @brownts)
* Attaching to local PID now performs initialization prior to attaching #341 fixing #329 (@brownts)

[0.26.0]: https://github.com/WebFreak001/code-debug/compare/v0.25.1...v0.26.0

# 0.25.1

* Remove the need for extra trust for debugging workspaces per guidance "for debug extensions" as noted in the [Workspace Trust Extension Guide](https://github.com/microsoft/vscode/issues/120251#issuecomment-825832603) (@GitMensch)
Expand Down
53 changes: 36 additions & 17 deletions src/mibase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,21 @@ class ExtendedVariable {
}
}

export enum RunCommand { CONTINUE, RUN, NONE }
class VariableScope {
constructor (public readonly name: string, public readonly threadId: number, public readonly level: number) {
}

public static variableName (handle: number, name: string): string {
return `var_${handle}_${name}`;
}
}

const STACK_HANDLES_START = 1000;
const VAR_HANDLES_START = 512 * 256 + 1000;
export enum RunCommand { CONTINUE, RUN, NONE }

export class MI2DebugSession extends DebugSession {
protected variableHandles = new Handles<string | VariableObject | ExtendedVariable>(VAR_HANDLES_START);
protected variableHandles = new Handles<VariableScope | string | VariableObject | ExtendedVariable>();
protected variableHandlesReverse: { [id: string]: number } = {};
protected scopeHandlesReverse: { [key: string]: number } = {};
protected useVarObjects: boolean;
protected quit: boolean;
protected attached: boolean;
Expand Down Expand Up @@ -176,8 +183,10 @@ export class MI2DebugSession extends DebugSession {
try {
if (this.useVarObjects) {
let name = args.name;
if (args.variablesReference >= VAR_HANDLES_START) {
const parent = this.variableHandles.get(args.variablesReference) as VariableObject;
const parent = this.variableHandles.get(args.variablesReference);
if (parent instanceof VariableScope) {
name = VariableScope.variableName(args.variablesReference, name);
} else if (parent instanceof VariableObject) {
name = `${parent.name}.${name}`;
}

Expand Down Expand Up @@ -396,7 +405,23 @@ export class MI2DebugSession extends DebugSession {

protected scopesRequest(response: DebugProtocol.ScopesResponse, args: DebugProtocol.ScopesArguments): void {
const scopes = new Array<Scope>();
scopes.push(new Scope("Local", STACK_HANDLES_START + (parseInt(args.frameId as any) || 0), false));
const [threadId, level] = this.frameIdToThreadAndLevel(args.frameId);

const createScope = (scopeName: string, expensive: boolean): Scope => {
const key: string = scopeName + ":" + threadId + ":" + level;
let handle: number;

if (this.scopeHandlesReverse.hasOwnProperty(key)) {
handle = this.scopeHandlesReverse[key];
} else {
handle = this.variableHandles.create(new VariableScope(scopeName, threadId, level));
this.scopeHandlesReverse[key] = handle;
}

return new Scope(scopeName, handle, expensive);
}

scopes.push(createScope("Local", false));

response.body = {
scopes: scopes
Expand All @@ -406,12 +431,7 @@ export class MI2DebugSession extends DebugSession {

protected async variablesRequest(response: DebugProtocol.VariablesResponse, args: DebugProtocol.VariablesArguments): Promise<void> {
const variables: DebugProtocol.Variable[] = [];
let id: number | string | VariableObject | ExtendedVariable;
if (args.variablesReference < VAR_HANDLES_START) {
id = args.variablesReference - STACK_HANDLES_START;
} else {
id = this.variableHandles.get(args.variablesReference);
}
const id: VariableScope | string | VariableObject | ExtendedVariable = this.variableHandles.get(args.variablesReference);

const createVariable = (arg, options?) => {
if (options)
Expand All @@ -431,15 +451,14 @@ export class MI2DebugSession extends DebugSession {
return varObj.isCompound() ? id : 0;
};

if (typeof id == "number") {
if (id instanceof VariableScope) {
let stack: Variable[];
try {
const [threadId, level] = this.frameIdToThreadAndLevel(id);
stack = await this.miDebugger.getStackVariables(threadId, level);
stack = await this.miDebugger.getStackVariables(id.threadId, id.level);
for (const variable of stack) {
if (this.useVarObjects) {
try {
const varObjName = `var_${id}_${variable.name}`;
const varObjName = VariableScope.variableName(args.variablesReference, variable.name);
let varObj: VariableObject;
try {
const changes = await this.miDebugger.varUpdate(varObjName);
Expand Down

0 comments on commit 6baa66b

Please sign in to comment.