Repository navigation
GDB 12.1: -var-create: unable to create variable object #437
Description
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
- If you are using gdb
-
gdb --version>= 12.1 (compiled from source, broken after https://github.com/bminor/binutils-gdb/commit/a9c82bc13cf8dd5d9076e746f744ee711eb55507) - it works on the command line with
gdb(when invoking-stack-select-frame) -
cwdandtargetare properly set
-
Other mentions
- Call stack window - selecting entry not actually changing frame in the debugger platformio/platform-espressif32#1330 seems to be caused by the same issue
Activity
GitMensch commentedon Aug 21, 2024
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()andsendCliCommand()?If this works out, then these changes, along with a Changelog entry, can be part of a PR.
oltolm commentedon Aug 21, 2024
I have already fixed it in be19c27.
GitMensch commentedon Aug 21, 2024
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?
oltolm commentedon Aug 21, 2024
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.
kmARC commentedon Aug 26, 2024
Thanks for looking into it!
Last week I couldn't build the
masterbranch, therefore I was trying a fix onv0.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
threadIdcheck and it works with it too (the check for thread Id was changed by be19c27, so wasn't part of the last release yet, I think.)GitMensch commentedon Aug 26, 2024
kmARC commentedon Aug 26, 2024
As of now, this report is still valid; is there a new release scheduled any time soon?
luckyfunky commentedon Sep 30, 2024
I also have this issue and would be happy about a new version :-)