GDB 12.1: -var-create: unable to create variable object
Symptom
When using a recent version of gdb (anything after 2022 March 08), the thread context is not selected by the extension anymore, and therefore (multi-threaded?) binaries cannot be properly debugged. Our team encountered two issues:
- Debugging a multi-threaded binary resulted in never stopping at a breakpoint
-var-create: unable to create variable objecterror displayed next to variables when selecting a different stack frame from the Call stack list (see screenshot)
Cause
I git-bisected the offending commit in gdb: https://github.com/bminor/binutils-gdb/commit/a9c82bc13cf8dd5d9076e746f744ee711eb55507 changed how the thread / stack frame context is selected. From the commit message:
With this change, there are only two GDB/MI commands that can change user selected context: -thread-select and -stack-select-frame. This allows us to remove all and rather complicated logic of notifying about user selected context change from mi_execute_command (), leaving it to these two commands themselves to notify.
Workaround
- Either after selecting the stack frame, manually invoke
-stack-select-frame Nwith N being the stack frame number - Or apply the following patch on
v0.27.0of the extension
diff --git a/src/backend/mi2/mi2.ts b/src/backend/mi2/mi2.ts
index e641160..fcef83b 100644
--- a/src/backend/mi2/mi2.ts
+++ b/src/backend/mi2/mi2.ts
@@ -741,6 +741,7 @@ export class MI2 extends EventEmitter implements IBackend {
if (trace)
this.log("stderr", "getStackVariables");
+ await this.sendCommand(`stack-select-frame ${frame}`);
const result = await this.sendCommand(`stack-list-variables --thread ${thread} --frame ${frame} --simple-values`);
const variables = result.result("variables");
const ret: Variable[] = [];
Note that I'm not sure if this is the right spot to invoke -stack-select-frame. It seems to be performant and does its job.
System
- [x] If you are using gdb
- [x]
gdb --version>= 12.1 (compiled from source, broken after https://github.com/bminor/binutils-gdb/commit/a9c82bc13cf8dd5d9076e746f744ee711eb55507) - [x] it works on the command line with
gdb(when invoking-stack-select-frame) - [x]
cwdandtargetare properly set
- [x]
Other mentions
- https://github.com/platformio/platform-espressif32/issues/1330 seems to be caused by the same issue
As that command is available in GDB since < 7.1 I think using it in some places may be the way to go - but that shouldn't be this place; checking the notes on the GDB change, this mostly means that no command should rely on a stack frame or thread to be set (it should be always explicit requested), as it previously was in this extension in some places.
@kmARC Starting from the message you see.. Can you please test the following change in the same file (backend/mi2/mi2.ts) instead (which, I guess, should fix the var-create issue):
async varCreate(threadId: number, frameLevel: number, expression: string, name: string = "-", frame: string = "@"): Promise<VariableObject> {
if (trace)
this.log("stderr", "varCreate");
- let miCommand = "var-create ";
- if (threadId != 0) {
- miCommand += `--thread ${threadId} --frame ${frameLevel}`;
- }
- const res = await this.sendCommand(`${miCommand} ${this.quote(name)} ${frame} "${expression}"`);
+ cconst miCommand = `var-create --thread ${threadId} --frame ${frameLevel} ${this.quote(name)} ${frame} "${expression}"`;
+ const res = await this.sendCommand(`${miCommand}`);
return new VariableObject(res.result(""));
}
and do the the same change to evalExpression() and sendCliCommand()?
If this works out, then these changes, along with a Changelog entry, can be part of a PR.
I have already fixed it in https://github.com/WebFreak001/code-debug/commit/be19c277870e04469347bc2f7032af9dd2daf580.
I don't think so as you only pass the frame if there's a thread-id?!? And even if the thread id is zero, I think we should always pass it, as it can be different in GDB (for example via console and commands executing at breakpoints) than in the ui, no?
I don't know if the thread id can even be zero in practice. The OP should just test the git version, but I don't know how to build the extension from source.
Thanks for looking into it!
Last week I couldn't build the master branch, therefore I was trying a fix on v0.27.0 (the latest tag that time).
I'm happy to report that today master succeeded to build and the issue is gone. I also tried removing the threadId check and it works with it too (the check for thread Id was changed by https://github.com/WebFreak001/code-debug/commit/be19c277870e04469347bc2f7032af9dd2daf580, so wasn't part of the last release yet, I think.)
So this PR should be closed?
So this PR should be closed?
As of now, this report is still valid; is there a new release scheduled any time soon?
I also have this issue and would be happy about a new version :-)