cdt-gdb-vscode
cdt-gdb-vscode copied to clipboard
Removing breakpoints does not actually delete them from GDB
I’m using the cdt-gdb-vscode extrension for remote debugging in an IDE based on Eclipse Theia 1.60.2 (running on Windows 11). I’ve encountered a problem where removing breakpoints in the IDE does not delete them from the GDB session, even though they disappear from the UI.
Repro steps
- Launch a debug session using a configuration like this:
{
"type": "gdbtarget",
"request": "launch",
"name": "My Debugger",
"cwd": "${command:my-vscode-ext.gdb-shared-path}",
"gdb": "${command:my-vscode-ext.gdb-path}",
"target": {
"type": "remote",
"host": "${command:my-vscode-ext.get-remote-target}",
"port": "${command:my-vscode-ext.gdb-remote-port}",
"server": "${command:my-vscode-ext.gdb-server-control-command}",
"serverParameters": [
"${command:my-vscode-ext.get-remote-target}",
"-start"
]
},
"initCommands": [
"source ${command:my-vscode-ext.initgdb-file}"
],
"verbose": true
}
- Set a breakpoint in the IDE → the debugger successfully hits the breakpoint and pauses the execution
- While paused remove this breakpoint in the IDE
- Press "Continue" in the IDE
- The debugger hits the breakpoint again, even though the IDE does not show it anymore
Logs
Setting the first breakpoint
From client: setBreakpoints({"source":{"name":"Main.c","path":"d:\\DbgTest\\Main.c"},"sourceModified":true,"breakpoints":[{"line":20}],"lines":[20]})
GDB command: 9 -exec-interrupt --all
GDB result: 9 done
To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":"\nThread "}}
Thread
To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":"1 received signal SIGTRAP, Trace/breakpoint trap.\n"}}
1 received signal SIGTRAP, Trace/breakpoint trap.
To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":"0x7759320c in ?? ()\n"}}
0x7759320c in ?? ()
GDB exec async: stopped,reason="signal-received",signal-name="SIGTRAP",signal-meaning="Trace/breakpoint trap",frame={addr="0x7759320c",func="??",args=[],arch="i386"},thread-id="1",stopped-threads="all"
GDB command: 10 -break-list
GDB result: 10 done,BreakpointTable={nr_rows="0",nr_cols="6",hdr=[{width="7",alignment="-1",col_name="number",colhdr="Num"},{width="14",alignment="-1",col_name="type",colhdr="Type"},{width="4",alignment="-1",col_name="disp",colhdr="Disp"},{width="3",alignment="-1",col_name="enabled",colhdr="Enb"},{width="10",alignment="-1",col_name="addr",colhdr="Address"},{width="40",alignment="2",col_name="what",colhdr="What"}],body=[]}
GDB command: 11 -break-insert --source "d:\\DbgTest\\Main.c" --line 20
GDB result: 11 done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x097228c8",func="ProgramCyclic",file="D:/DbgTest/Main.c",fullname="D:\\DbgTest\\Main.c",line="20",thread-groups=["i1"],times="0",original-location="-source d:\\DbgTest\\Main.c -line 20"}
To client: {"seq":0,"type":"response","request_seq":8,"command":"setBreakpoints","success":true,"body":{"breakpoints":[{"id":1,"line":20,"verified":true}]}}
GDB command: 12 -exec-continue
GDB result: 12 running
GDB exec async: running,thread-id="all"
To client: {"seq":0,"type":"event","event":"continued","body":{"threadId":1,"allThreadsContinued":true}}
GDB notify async: breakpoint-modified,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x097228c8",func="ProgramCyclic",file="D:/DbgTest/Main.c",fullname="D:\\DbgTest\\Main.c",line="20",thread-groups=["i1"],times="1",original-location="-source d:\\DbgTest\\Main.c -line 20"}
To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":"[Switching to Thread 310]\n"}}
[Switching to Thread 310]
To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":"\n"}}
To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":"Thread 8 hit Breakpoint 1, ProgramCyclic () at D:/DbgTest/Main.c:20\n"}}
Thread 8 hit Breakpoint 1, ProgramCyclic () at D:/DbgTest/Main.c:20
Verifying with info breakpoints
>info breakpoints
From client: evaluate({"expression":">info breakpoints","frameId":1000,"context":"repl"})
GDB command: 19 -interpreter-exec --thread 8 --frame 0 console "info breakpoints"
To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":"Num Type Disp Enb Address What\n"}}
Num Type Disp Enb Address What
To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":"1 breakpoint keep y 0x097228c8 in ProgramCyclic at D:/DbgTest/Main.c:20\n"}}
1 breakpoint keep y 0x097228c8 in ProgramCyclic at D:/DbgTest/Main.c:20
To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":"\tbreakpoint already hit 1 time\n"}}
breakpoint already hit 1 time
GDB result: 19 done
To client: {"seq":0,"type":"response","request_seq":13,"command":"evaluate","success":true,"body":{"result":"\r","variablesReference":0}}
Removing the breakpoint
From client: setBreakpoints({"source":{"name":"Main.c","path":"D:\\DbgTest\\Main.c","sourceReference":0},"sourceModified":true,"breakpoints":[],"lines":[]})
GDB command: 20 -break-list
GDB result: 20 done,BreakpointTable={nr_rows="1",nr_cols="6",hdr=[{width="7",alignment="-1",col_name="number",colhdr="Num"},{width="14",alignment="-1",col_name="type",colhdr="Type"},{width="4",alignment="-1",col_name="disp",colhdr="Disp"},{width="3",alignment="-1",col_name="enabled",colhdr="Enb"},{width="10",alignment="-1",col_name="addr",colhdr="Address"},{width="40",alignment="2",col_name="what",colhdr="What"}],body=[bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x097228c8",func="ProgramCyclic",file="D:/DbgTest/Main.c",fullname="D:\\DbgTest\\Main.c",line="20",thread-groups=["i1"],times="1",original-location="-source d:\\DbgTest\\Main.c -line 20"}]}
To client: {"seq":0,"type":"response","request_seq":14,"command":"setBreakpoints","success":true,"body":{"breakpoints":[]}}
Verifying with info breakpoints
>info breakpoints
From client: evaluate({"expression":">info breakpoints","frameId":1000,"context":"repl"})
GDB command: 21 -interpreter-exec --thread 8 --frame 0 console "info breakpoints"
To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":"Num Type Disp Enb Address What\n"}}
Num Type Disp Enb Address What
To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":"1 breakpoint keep y 0x097228c8 in ProgramCyclic at D:/DbgTest/Main.c:20\n"}}
1 breakpoint keep y 0x097228c8 in ProgramCyclic at D:/DbgTest/Main.c:20
To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":"\tbreakpoint already hit 1 time\n"}}
breakpoint already hit 1 time
GDB result: 21 done
To client: {"seq":0,"type":"response","request_seq":15,"command":"evaluate","success":true,"body":{"result":"\r","variablesReference":0}}
Expected Behavior
After removing the breakpoint, when pressing "Continue" in the IDE, the removed breakpoint shall not be hit anymore.
Follow-up Observation:
I’ve just noticed that this issue only affects the first breakpoint that was created during the debugging session. Any subsequent breakpoints can be removed correctly as expected.
This might suggest the bug may be specific to how the adapter tracks or manages the initial breakpoint internally. Let me know if I can provide further logs or help narrow it down.
Is this issue related to https://github.com/eclipse-cdt-cloud/cdt-gdb-adapter/issues/330?
@jreineckearm it seems like this issue is not present anymore in version 2.0.5. When creating this issue I was using 2.0.3. Can you confirm this has been solved in version 2.0.4 or 2.0.5?
Thanks for pointing this out, @chroberino .
As part of the change to support async GDB breakpoint notifications, we fixed a problem in internal breakpoint-matching mechanics where, depending on how you set a breakpoint, GDB returned breakpoint information in different styles. I suspect this implicitly fixed this defect.
Unfortunately, I wasn't even able to reproduce the problem you saw with 2.0.3. So, GDB, GDB server, or the particular build of your target application might also play into this.
Given this problem goes away for you, I'd suggest to close this issue and reopen if you see it happening again. What do you think?
Given this problem goes away for you, I'd suggest to close this issue and reopen if you see it happening again.
Fully agree, @jreineckearm. Let's close the issue for now. Thank you!
@jreineckearm, the issue is back in version 2.0.6. I have just switched between 2.0.5 and 2.0.6 a couple of times and can confirm that 2.0.5 solves the issue while 2.0.6 has a regression.
Note that I could not test with version 2.1.0 since my existing launch config seems to be incompatible with this version (it fails to establish a remote connection).
Thanks for reopening, @chroberino . Looking at the code changes between 2.0.5 and 2.0.6, I can't see an obvious change breaking this. It's mostly about a button label and about adding support for instruction breakpoints (the ones in the disassembly view). I am afraid it wasn't fixed in the first place. :-(
Note that I could not test with version 2.1.0 since my existing launch config seems to be incompatible with this version (it fails to establish a remote connection).
This one sounds worrying. There were a couple of changes in the way of managing gdb and gdbserver processes to reduce the number of error cases where we left behind such processes. Could you please try such connection again with 2.1.0 and set option verbose to true? Would you mind raising this is a separate bug? Thanks.
This one sounds worrying. There were a couple of changes in the way of managing gdb and gdbserver processes to reduce the number of error cases where we left behind such processes. Could you please try such connection again with 2.1.0 and set option
verbosetotrue? Would you mind raising this is a separate bug? Thanks.
@jreineckearm, I planned to do this anyway and just finished collecting all relevant details => https://github.com/eclipse-cdt-cloud/cdt-gdb-vscode/issues/173
Thanks, @chroberino !
@jreineckearm, do you have any experience with debugging cdt-gdb-vscode using Eclipse Theia instead of VS Code? This breakpoint removal issue is only present in Theia, not in VS Code. Therefore I am striving to launch my debug build of cdt-gdb-vscode from Theia to see where the issue has its roots. (Debugging of cdt-gdb-adapter itself can stay in VS Code I guess).
However, I am having troubles running the extension host launch config in Theia: https://github.com/eclipse-theia/theia-ide/issues/559
@chroberino , unfortunately, my knowledge there is limited. :-( @planger , @jonahgraham , would you be able to give some hints? Or know who could?
@jreineckearm I think that @chroberino has identified the problem correctly as https://github.com/eclipse-cdt-cloud/cdt-gdb-adapter/issues/330#issuecomment-3118779190
I don't think there is anything to do on the extension side and further work should happen in https://github.com/eclipse-cdt-cloud/cdt-gdb-adapter/issues/330
This issue has been confirmed to be a duplicate of https://github.com/eclipse-cdt-cloud/cdt-gdb-adapter/issues/330. Since https://github.com/eclipse-cdt-cloud/cdt-gdb-adapter/issues/330 has been solved I am closing this issue as well.