Support explicit hardware breakpoints (option to send "hbreak" instead of "break" to GDB)
My hardware has 4 hardware breakpoints, so I pass set remote hardware-breakpoint-limit 4 to GDB during launch via my launch.json. However, if I set more than 4 breakpoints, GDB does not guard me from setting too many breakpoints as expected; instead it reports an error from the remote target that it "Cannot insert hardware breakpoint 5", and that "A serious error occurred with gdb, unable to continue or interrupt".
If I instead explicitly set 4 hardware breakpoints by manually passing hbreak to GDB, then attempting to set a 5th hardware breakpoint this way, GDB prevents me from setting this breakpoint and gracefully reports "Hardware breakpoints used exceeds limit", with no fatal errors.
When setting breakpoints in the UI, I can confirm that once they are sent from GDB to the gdbserver; seen with set debug remote 1, GDB is appropriately passing Z1 commands to automatically assign hardware breakpoints. But oddly enough, these automatic hardware breakpoints don't appear to count towards the hardware-breakpoint-limit. Upon querying info break, all breakpoints are listed as breakpoint, not hw breakpoint. This is contrary to what info break reports when manually passing hbreak to GDB.
The ideal solution for my use-case would be to allow users to specify how Cortex-Debug communicates breakpoints to GDB (specifically so I can set it to send hbreak instead of break).
This is already a feature in Microsoft's cpptools extension, however I would prefer not to rely on cpptools as it is largely closed-source, and I am attempting to maintain a fully FOSS development environment. I also do not know if that feature of the cpptools extension is even compatible with Cortex-Debug.
The following alternative solutions are not ideal workarounds for my use-case:
- Microsoft's cpptools extension (closed-source)
- Manually submitting
hbreakto GDB (cumbersome, doesn't update UI) - Intentionally avoiding setting more than 4 breakpoints (cumbersome, risks errors, unintuitive to new users)
For context, I am using Cortex-Debug with arm-none-eabi-gdb through OpenOCD to a Raspberry Pi Pico, communicating through a Picoprobe (an additional Pico running as a CMSIS-DAP debugger).
Thank you for developing and maintaining these extensions :)
EDIT - This issue is related to:
- #555
(After reading through #555, I'd like to emphasize that this feature request is simply asking to expose the commands Cortex-Debug is passing to GDB when calling breakpoints. I see no reason to change any default behaviour or VSCode UI, and I would be comfortable accepting that I only have 4 breakpoints as a result of this solution (I don't think I can get software breakpoints working anyway). All I suggest is exposing the breakpoint calls as a tool, such as an override through launch.json, for users who encounter issues like myself and those who commented in #555)
I'd like to bump this request as well. In my particular case, debugging firmware running in RAM on a Cortex-A target, using a Black Magic Probe, BMP sends the correct memory map to gdb which includes RAM areas and this causes 'break' to select software breakpoints by default. The catch, however, is that software breakpoints have not yet been implemented for Cortex-A targets on BMP (work-in-progress).
This leads to breakpoints not being set at all when "break" is called. I've temporarily worked around the issue in a BMP fork by forcing Cortex-A software breakwatch calls to use hardware instead, but I'm not sure this is the right direction for a long-term fix.
It would simply be nice to be able to set the break command to be used by cortex-debug somewhere in the launch file.
Chiming in a year later that I can all-but confirm this is caused by a bug in GDB itself. You can follow that bug report here.
In the meantime, an option to explicitly send hbreak instead of break to GDB would be a helpful workaround to prevent fatal errors, as I expect it will be a year or two before the bug is addressed, and then longer before a fix is shipped into the Arm GNU Toolchain releases.
Although I'm not familiar with VSCode extension development, I'm happy to help with a PR if given some initial direction.
The issues live on...
https://sourceware.org/bugzilla/show_bug.cgi?id=33592
I don't need a PR. I need to know that the VSCode UI has been updated (maybe some other debugger implemented this). Last check, it was not. And, then we have to wait for the GDB fixes.
Thanks for pinning @haneefdm. I have plans to submit a 1-of-2 patch to GDB when I'm able to find the time.
Can you clarify what's wrong with the VSCode UI, and how that relates to providing users with an option to send alternative GDB commands (ie. hbreak instead of break) when the UI generates a breakpoint, such as a setting in launch.json?
If we enabled HW breakpoints what does the GUI do with it. Last time I checked, nothing. There has to be something that says this is HW and this is NOT and what the default is
Normally, a debug adapter like ours advertises what it supports via Capabilities. See Capabilities. BreakpointMode[]
https://microsoft.github.io/debug-adapter-protocol/specification#Types_Capabilities BreakpointMode BreakpointModeApplicability
Then the UI and VSCode will make proper requests with additional info tagged on to the breakpoint request(s). If we never see the requests, it won't work. If there is no way for the user to specify breakpoint time...the story goes on
Do you see a way for the user to tag which bkpt is which? Or an exmple of some other debugger doing it? I wasted a few days on it and then gave up because the GUI did nothing.
You can use the Microsofts VSCode MockDebug extension to see what it does. I didn't check but when they out in a new feature, they first try it out over there. It is easy to experiment with that rather than with cortex-debug
Interesting - Thank you for sharing all this, it's very clarifying to your perspective.
In my mind, although knowing which breakpoints are HW vs. SW could be interesting information, that info does not have significant utility to the average end-user. In my experience, HW breakpoints can only exist in read-only memory, and SW breakpoints can only exist in RAM. So long as the red dot exists, the user can extrapolate the type of breakpoint based on the memory space it's placed within, or manually query GDB, if they really want to know.
I do want to clarify that GDB is already sending HW breakpoints by default. If the requested breakpoint is located at a read-only memory address, then GDB sends an automatic HW breakpoint request (the GDB bug report linked above simply notes that GDB fails to record those as HW breakpoints internally, but the target still receives them as HW breakpoints). This behaviour can be disabled with the command set breakpoint auto-hw off, however attempting to send a SW breakpoint to a read-only address will fail (and vice-versa). So sending the standard break command to GDB will, by default, already send a HW breakpoint to read-only addresses on the target.
I would argue that, in line with the current cortex-debug and GDB default behaviour, the user does not need to know which breakpoints are HW breakpoints, and that shouldn't stop such a feature from being implemented here as a workaround to GDB's scuffed automatic HW breakpoint implementation. Since the breakpoints are already being sent by GDB as HW breakpoints for read-only addresses, the option (not by default) for cortex-debug to explicitly send the hbreak command in place of break would not introduce any new GDB or UI behaviour. Having this as an option could also help users with an incorrect memory map, or whose targets do not support SW breakpoints as @litui mentioned above.
I fully acknowledge that the option requested here is not robust, as it would force all UI breakpoint requests to be hbreak; but that would enable functionality for users where previously there was none, and having the option of limited functionality is better than being stuck with no functionality.
All that said, I do agree that UI info reflecting breakpoint type would be a nice-to-have if it is easily implemented in the future; just not necessary to address this issue.
So, it would be all or nothing. By default gdb does the right thing based on memory map. I have a feeling I will get tons of issues asking me why it is all or nothng. But why would anyone want a HW bkpt when you can have limiless SW breakpoints (in RAM). Main reason, my guess is to deal with Cached memories. Consider devices like NXP RT-500 (or other RAM heavy devices, but with i-cache) where you want to be selective about what gets the limited HW breakpoints and what does not.
So, that is the use case I was thinking.
Besides, can't we already do what is needed by using a gdb script/init? Did anyone try something like this?
alias break hbreak
or if you want to preserve the original
alias default-break break
alias break hbreak
Only way to find out is to try.
Then, I don't need to make a change that is questionable.
Besides, can't we already do what is needed by using a gdb script/init?
This was a good idea, but unfortunately:
Alias break is the name of an existing command
I have a feeling I will get tons of issues asking me why it is all or nothng.
I think an easy way around this is if the option was something such as "overrideBreakCommand" in launch.json (default: "break", or however the current behaviour is implemented). That would clearly show that the user is overriding something, so the responsibility is on the user to know what they are doing. That way, the default behaviour is unchanged, and so the only "all-or-nothing" situation is where a user inflicts it upon themselves explicitly by adding "overrideBreakCommand" to their launch.json.
But why would anyone want a HW bkpt when you can have limiless SW breakpoints (in RAM)
Well, on my target (Raspberry Pi Pico), I cannot place a SW breakpoint on code which is run from the flash (which is nearly all Pico programs). SW breakpoints can only apply to code which is run in RAM (which is not common to do on Picos). As such, I can only use the 4 HW breakpoints that the RP2040 provides in most cases, so for me the ability to override the break command with hbreak would allow for GDB to appropriately track the number of HW breakpoints I have used, and gracefully prevent me from creating more - for example.
Well, on my target (Raspberry Pi Pico), I cannot place a SW breakpoint on code which is run from the flash
And, rightfully, you shouldn't try to use a SW breakpoint for code in FLASH
But, this is the most common case for nearly all embedded. Between gdb and the gdb-server, they know the memory map, max HW bkpts, and do the right thing. If it is in FLASH, you should automatically get HW breakpoints. Guess, I am not understanding.
So, what could be wrong here? Your exe mamory regions don't have right attributes, yur gdb-server does not know? So, I don't know waht is going on. Can you attach the gdb-server output found in the TERMINAL tab? This aspect is a combination of your gdb-server and gdb. GDB has no way of knowing how many HW breakpoints there are.
If it is in FLASH, you should automatically get HW breakpoints.
So I get automatic HW breakpoints, however GDB has the longstanding bug (linked above) which causes automatic HW breakpoints to not count towards the hardware-breakpoint-limit. So, setting more than 4 breakpoints causes the VSCode UI to show 5 breakpoints, and GDB fails when attempting to add the 5th, with the UI emphasizing "Exception has occurred". But having an option to override break with hbreak would mean GDB would accurately keep track of HW breakpoints, and once the limit is reached, return a graceful warning preventing the creation of the breakpoint and subsequent exception.
Within launch.json:
"postLaunchCommands": [
"set remote hardware-breakpoint-limit 4",
"set remote hardware-watchpoint-limit 2",
],
gdb-server output:
[2025-11-07T15:36:46.938Z] SERVER CONSOLE DEBUG: onBackendConnect: gdb-server session connected. You can switch to "DEBUG CONSOLE" to see GDB interactions.
openocd.exe -c "gdb_port 50000" -c "tcl_port 50001" -c "telnet_port 50002" -s "C:/tools/openocd/scripts" -f "c:/Users/User/.vscode-oss/extensions/marus25.cortex-debug-1.12.1/support/openocd-helpers.tcl" -f interface/cmsis-dap.cfg -f target/rp2040.cfg -f debugger/gdb.cfg -c "adapter speed 12000"
Open On-Chip Debugger 0.12.0+dev (2025-07-17-14:39)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
DEPRECATED! use 'gdb port', not 'gdb_port'
DEPRECATED! use 'tcl port' not 'tcl_port'
DEPRECATED! use 'telnet port', not 'telnet_port'
CDLiveWatchSetup
Info : [rp2040.core0] Hardware thread awareness created
Info : [rp2040.core1] Hardware thread awareness created
adapter speed: 12000 kHz
Info : Listening on port 50001 for tcl connections
Info : Listening on port 50002 for telnet connections
Info : Using CMSIS-DAPv2 interface with VID:PID=0x2e8a:0x000c, serial=E661385283386235
Info : CMSIS-DAP: SWD supported
Info : CMSIS-DAP: Atomic commands supported
Info : CMSIS-DAP: Test domain timer supported
Info : CMSIS-DAP: FW Version = 2.0.0
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 0 SWDIO/TMS = 0 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : clock speed 12000 kHz
Info : SWD DPIDR 0x0bc12477, DLPIDR 0x00000001
Info : SWD DPIDR 0x0bc12477, DLPIDR 0x10000001
Info : [rp2040.core0] Cortex-M0+ r0p1 processor detected
Info : [rp2040.core0] target has 4 breakpoints, 2 watchpoints
Info : [rp2040.core0] Examination succeed
Info : [rp2040.core1] Cortex-M0+ r0p1 processor detected
Info : [rp2040.core1] target has 4 breakpoints, 2 watchpoints
Info : [rp2040.core1] Examination succeed
Info : [rp2040.core0] starting gdb server on 50000
Info : Listening on port 50000 for gdb connections
Info : accepting 'gdb' connection on tcp/50000
Info : RP2040 rev 2, QSPI Flash win w25q16jv id = 0x1540ef size = 2048 KiB in 512 sectors
Info : New GDB Connection: 1, Target rp2040.core0, state: halted
[rp2040.core0] halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x10002854 msp: 0x20041f78
[rp2040.core1] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x00000184 msp: 0x20041f00
[rp2040.core0] halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ea msp: 0x20041f00
[rp2040.core1] halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ea msp: 0x20041f00
[rp2040.core0] halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ea msp: 0x20041f00
[rp2040.core1] halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ea msp: 0x20041f00
Error: Invalid command argument
Error: [rp2040.core0] Execution of event reset-init failed:
args[i] option value ('CX') is not valid
Info : Padding image section 0 at 0x1000cb54 with 4 bytes
Info : Padding image section 1 at 0x1000f74c with 180 bytes (bank write end alignment)
[rp2040.core0] halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ea msp: 0x20041f00
[rp2040.core1] halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ea msp: 0x20041f00
[rp2040.core0] halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ea msp: 0x20041f00
[rp2040.core1] halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ea msp: 0x20041f00
[rp2040.core1] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x00000184 msp: 0x20041f00
[rp2040.core1] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x00000184 msp: 0x20041f00
[rp2040.core1] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x00000184 msp: 0x20041f00
[rp2040.core1] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x00000184 msp: 0x20041f00
[rp2040.core1] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x00000184 msp: 0x20041f00
Error: [rp2040.core0] Can not find free FPB Comparator!
Error: [rp2040.core0] can't add breakpoint: resource not available
Error: [rp2040.core0] Can not find free FPB Comparator!
Error: [rp2040.core0] can't add breakpoint: resource not available
DEBUG CONSOLE (GDB) output:
[rp2040.core0] Can not find free FPB Comparator!
[rp2040.core0] can't add breakpoint: resource not available
Warning:
Cannot insert hardware breakpoint 4:Remote failure reply: 0E.
0x100003ce in main () at C:\tools\pico-testing\hello-world\main.c:28
28 gpio_put(PIN_LED, false);
Not implemented stop reason (assuming exception): undefined
info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x100003ac in main at C:\tools\pico-testing\hello-world\main.c:17
2 breakpoint keep y 0x100003b6 in main at C:\tools\pico-testing\hello-world\main.c:20
3 breakpoint keep y 0x100003be in main at C:\tools\pico-testing\hello-world\main.c:26
4 breakpoint keep y 0x100003cc in main at C:\tools\pico-testing\hello-world\main.c:28
5 breakpoint keep y 0x100003d4 in main at C:\tools\pico-testing\hello-world\main.c:29
So all you are looking for a graceful rejection of a failed breakpoint? But the debugger is still functional? If the latter is untrue, I can do something about that.
GDB will barf regardless of if you exceeded the limit set by you hardware-breakpoint-limit or by the gdb-server because it ran out of HW slots. Either way, the command we issue to gdb will fail and you will a very similar outcome in the Debug Console. Not true? Not sure what this buys us.
In my case, I'm explicitly looking for the override capability as it's not an issue of running out of hw breakpoints. Reasons discussed in my original comment and linked draft PR.
It's obviously not cortex-debug's fault nor its responsibility if a downstream gdb implementation is broken on any of these counts. Nonetheless, a gdb that is broken in either of the ways discussed in this PR renders cortex-debug completely unusable when the option to override breakpoint type would provide a handy workaround.
In terms of representation in the UI I agree this is an "all or nothing" sort of approach and needn't be reflected meaningfully in the UI. I think it could be best viewed as being a "use at your own risk" type feature for those who know what they're doing (as much in the world of low level hardware debugging is already...).
option to override breakpoint type would provide a handy workaround
This is the part I am not getting. Workaround for what?. Workaround to a faulty gdb-server? Or how that gdb-server is configured? I am missing some context from this thread. Help me.
We issue a 'break' and if the address is in FLASH (R/O mem), you will get a HW breakpoing courtesy of gdb+gdb-server. It has been this way forever or else nothing would have worked.
So all you are looking for a graceful rejection of a failed breakpoint?
Ideally, for my specific situation, what I would like is to be unable to add a breakpoint, or at least have immediate feedback (such as a warning) if I have exceeded the hardware-breakpoint-limit (ie. in a perfect world, GDB returns its warning, and the breakpoint does not get set as a red dot in the UI). I can only exceed the hardware-breakpoint-limit if hbreak is sent to GDB, otherwise the error is deferred to the target's response via openOCD.
Either way, the command we issue to gdb will fail and you will a very similar outcome in the Debug Console.
The handling is different. If hardware-breakpoint-limit is reached through hbreak, GDB catches this immediately and doesn't ever send the command to the server (openOCD). Whereas for exceeding that limit through break, the command is sent through openOCD only after the user continues execution because GDB fails to log it as a HW breakpoint, and it fails via a response from the target. This would be more graceful to immediately reject the breakpoint the user just set, rather than waiting for the user to continue.
I have different needs from @litui, which they describe above; but both of our issues would be resolved with the ability to send the hbreak command. I agree with their justificiation that even though the problem stems from GDB, offering more versatility within cortex-debug allows more people to be able to use it for debugging.
Example showing that hbreak is different from break in the context of hardware-breakpoint-limit:
Within launch.json:
"postLaunchCommands": [
"set remote hardware-breakpoint-limit 4",
"set remote hardware-watchpoint-limit 2",
],
GDB commands:
interrupt
hbreak main.c:17
hbreak main.c:19
hbreak main.c:20
hbreak main.c:26
hbreak main.c:27
continue
info break
DEBUG CONSOLE (GDB) output:
interrupt
{"output":"","token":28,"outOfBandRecord":[],"resultRecords":{"resultClass":"done","results":[]}}
Thread
1 "rp2040.core0" received signal SIGINT, Interrupt.
sleep_until (t=94605449) at C:\tools\sdk\pico\pico-sdk\src\common\pico_time\time.c:408
408 while (!time_reached(t_before)) {
hbreak main.c:17
Hardware assisted breakpoint 1 at 0x100003ac: file C:\tools\pico-testing\hello-world\main.c, line 17.
{"output":"","token":39,"outOfBandRecord":[],"resultRecords":{"resultClass":"done","results":[]}}
hbreak main.c:19
Hardware assisted breakpoint 2 at 0x100003b0: file C:\tools\pico-testing\hello-world\main.c, line 19.
{"output":"","token":46,"outOfBandRecord":[],"resultRecords":{"resultClass":"done","results":[]}}
hbreak main.c:20
Hardware assisted breakpoint 3 at 0x100003b6: file C:\tools\pico-testing\hello-world\main.c, line 20.
{"output":"","token":53,"outOfBandRecord":[],"resultRecords":{"resultClass":"done","results":[]}}
hbreak main.c:26
Hardware assisted breakpoint 4 at 0x100003be: file C:\tools\pico-testing\hello-world\main.c, line 26.
{"output":"","token":60,"outOfBandRecord":[],"resultRecords":{"resultClass":"done","results":[]}}
hbreak main.c:27
Hardware breakpoints used exceeds limit.
Hardware breakpoints used exceeds limit. (from interpreter-exec console "hbreak main.c:27")
continue
Continuing.
{"output":"","token":74,"outOfBandRecord":[],"resultRecords":{"resultClass":"running","results":[]}}
Thread 1 "rp2040.core0" hit Breakpoint 4, main () at C:\tools\pico-testing\hello-world\main.c:26
26 gpio_put(PIN_LED, true);
info break
Num Type Disp Enb Address What
1 hw breakpoint keep y 0x100003ac in main at C:\tools\pico-testing\hello-world\main.c:17
2 hw breakpoint keep y 0x100003b0 in main at C:\tools\pico-testing\hello-world\main.c:19
3 hw breakpoint keep y 0x100003b6 in main at C:\tools\pico-testing\hello-world\main.c:20
4 hw breakpoint keep y 0x100003be in main at C:\tools\pico-testing\hello-world\main.c:26
breakpoint already hit 1 time
{"output":"","token":81,"outOfBandRecord":[],"resultRecords":{"resultClass":"done","results":[]}}
Warning:
Cannot insert hardware breakpoint 4:Remote failure reply: 0E.
0x100003ce in main () at C:\tools\pico-testing\hello-world\main.c:28
28 gpio_put(PIN_LED, false);
So what happens after this with Cortexx-Debug. I have run out of breakpoints plenty of times but it does let me continue debugging.
Ahhh, I see @recursivenomad You are saying it looks like an exception occurs which is like hitting a breakpoint and the debugger stops right there, requiring a manual continue? Is this what is happening?
Btw, we have been cross posting furiously and I got lost in the thread.
Yes, this has turned into quite the conversation :) Thank you for your responsiveness.
To clarify, the warning you sent above is from the current implementation, which sends break. That warning only occurs after you "continue" the execution. VSCode highlights a random (or perhaps the closest) breakpoint, and shows this:
I can continue debugging if I remove one of the breakpoints and "continue" again, but that does not address the issue of immediacy, which I describe in my previous message - nor does it help @litui's situation, which to the best of my understanding is an issue where their target does not accept SW breakpoints, even in RAM (but somehow does handle HW breakpoints in RAM), and so sending hbreak would help their unique situation as well, just in a different way.
Ultimately, the request is for an additional point of versatility in cortex-debug, allowing us to override what command is sent to GDB when a breakpoint is set in the UI (with both of our cases benefiting from changing that command from break to hbreak). Having this as an option would allow us to fix these issues ourselves, instead of bugging you in the future 🙂
to the best of my understanding is an issue where their target does not accept SW breakpoints, even in RAM (but somehow does handle HW breakpoints in RAM), and so sending hbreak would help their unique situation as well, just in a different way.
You got it. It's a Cortex-A feature.
This is the part I am not getting. Workaround for what?. Workaround to a faulty gdb-server? Or how that gdb-server is configured?
In this particular case, it's a hardware JTAG/SWD debug adapter (Blackmagic Debug) that runs an embedded, integrated gdb instance (over serial UART) that does not (yet) support software breakpoints on some hardware. You're not wrong about how a fully functioning gdb instance should behave in its stock behaviour. I recognize this is an edge case, but it's one that gdb itself allows one to work around through explicit calls to hbreak. I'm just desiring the ability to make use of that gdb workaround via cortex-debug so I'm not stuck using the commandline for it.
to the best of my understanding is an issue where their target does not accept SW breakpoints, even in RAM (but somehow does handle HW breakpoints in RAM), and so sending hbreak would help their unique situation as well, just in a different way.
I didn't know such targets existed. SW breakpoints are typically done by inserting a trap-like instruction (replacing the original instr at that address). This is normal for all processors. But if gdb cannot do memory writes even though it is a RAM location, then it can't set that breakpoint. This is how a SW breakpoint works.
Also, for these kinds of RAM breakpoints, no support from the gdb-server (BMP) is needed. Also, you say BMP runs an embedded, integrated gdb instance. You probably mean gdb-server instance?
Again, I am flummoxed.
I know what you guys are saying. Just give me the feature and I will be happy. But doing it for the wrong reasons is not a good thing.
I will look into what can be done (if any) about @recursivenomad issue. Wondering if this is just OpenOCD or it is all gdb-servers.
Lets keep the issue faced by @recursivenomad separate from @litui Completely different issues and from your perspectives, this feature will satisfy both. I don't see it that way. Issues should be addressed where they belong as the first priority.
And, this is not the first time I have seen BMP users come to me and ask for special features that should be rightfully addressed in BMP FW.
for these kinds of RAM breakpoints, no support from the gdb-server (BMP) is needed. Also, you say BMP runs an embedded, integrated gdb instance. You probably mean gdb-server instance?
Correct. I did mean an integrated gdb-server instance, accessible over serial. I should have been more specific in that yes gdb-server on the blackmagic debugger (which I'll remind that cortex-debug does include support for) supports the break behaviour you described above. However, the underlying code that gdb-server directs on the dongle is not 100% complete for all supported devices. In the case of my particular SWD target software breakpoint support is missing still.
100% the correct, ideal solution is for SW breakpoints to be supported by the blackmagic debugger here. No argument from me. However, the automated breakpoint selection behaviour in GDB operates alongside the ability to specify either hardware or software breakpoints in order to work around issues like this in the interim. I'm not really asking for cortex-debug to support a "special feature" here but a more complete support for the gdb feature set. I don't believe I've mischaracterized my request here either.
If my request can be accommodated in stream of @recursivenomad's request as it seemed in the beginning, I'd appreciate it, but if the direction has changed here I'm also okay to step aside in the interests of @recursivenomad reaching a solution after the nearly 2 years their issue has been pending.
PS: I believe @recursivenomad even brought up bad memory mapping as a potential reason for this earlier too. That can occur regardless of whether one is a "BMP user", fwiw.
@haneefdm:
But doing it for the wrong reasons is not a good thing.
I don't believe these are "wrong reasons" to include a broad feature - the goal is enabling user control of more complete GDB command support. As of right now, cortex-debug does not provide any way to support GDB's hbreak command, and the discussed solution here would bring that support to cortex-debug.
For example, look at "overrideLaunchCommands", "overrideRestartCommands", and "overrideResetCommands". In my experience, they each allow for users to override default behaviour in cortex-debug, enabling us to implement GDB commands that are unique to our hardware & software situation.
In my mind, adding "overrideBreakCommand" (or similar) is no different. It is an option which would override default behaviour and enable users to implement GDB commands which are currently missing from cortex-debug.
Lets keep the issue faced by @recursivenomad separate from @litui
I still believe the implementation of something like "overrideBreakCommand" could resolve both (as well as prevent future issues), but I respect your desire to keep the topics separate moving forward.
I will look into what can be done (if any) about @recursivenomad issue. Wondering if this is just OpenOCD or it is all gdb-servers.
As my specific issue stems from GDB being allowed to pass an automatic hardware breakpoint request which exceeds the supported number of HW breakpoints on the target (which could be avoided by explicitly sending hbreak instead), I assume this would affect all gdb-servers; however, I assume the way in which they each respond to this bad request is likely different.
I am happy to continue providing any logs or ideas as you need them.
PS: I believe @recursivenomad even brought up bad memory mapping as a potential reason for this earlier too. That can occur regardless of whether one is a "BMP user", fwiw.
Again fixing the wrong tool. I don't want to be a dumping ground for all the other tools. You are missing out big time is SW breakpoints are not working when they should.
I'm not really asking for cortex-debug to support a "special feature" here but a more complete support for the gdb feature set
We use dozens of gdb commands and this is of course special to work around issues of other tools. I have to maintain this.
overrideBreakCommand is nothing similar to all the other overrides.
I don't have a board right now (traveling). I will look at this when I do. Neither issue really justifies adding a feature by editing a 3000+ file --- that I can't even explain later. That is how I feel and I know your perspective is different.
If I do implement it, I will likely do what cpptools did.
Alright. I've stated my case, you've stated yours. Bowing out of this thread. All the best.
If I do implement it, I will likely do what cpptools did.
An implementation like what cpptools does would certainly resolve this issue.
I just committed the cpptools equivalent of HW breakpoints. PR#1166 does not do a limit check that I think is important, as GDB+openocd gets wedged when you exceed the bpt limit. Of course, involved lots of changes. If you can help test it and give feedback, I would appreciate it.
Okay, I have tested the latest automated build.
"required": true works, but "limit": 4 has a bug.
I am pleased to report that adding the following lines to launch.json works correctly:
"hardwareBreakpoints": {
"required": true,
},
"postLaunchCommands": [
"set remote hardware-breakpoint-limit 4",
"set remote hardware-watchpoint-limit 2",
],
The above configuration provides the same comprehensive UX/UI benefits as I described in #1166
. .
info break now always correctly returns that all are of type "hw breakpoint".
However, "limit": 4 has a bug. Adding the following to launch.json will revert to auto breakpoints once the limit is reached:
"hardwareBreakpoints": {
"required": true,
"limit": 4,
},
After exceeding 4 breakpoints, info break now incorrectly returns that all are of type "breakpoint" (not "hw breakpoint").
I will note that so long as "set remote hardware-breakpoint-limit 4" is set, the "limit": 4 option does not seem to be necessary in order to resolve my issue, because GDB does a good job with immediate & gracefull feedback to the UX/UI when hardware-breakpoint-limit is set.
Also, if your intention was for the options to use the same language as cpptools, I want to point out that cpptools uses "require", whereas you have chosen "required".
Thank you for being willing to submit this feature into the main branch 🙂
Thanks for pointing the typo. But, I cannot see the issue with the limit. Not sure how the limit enforcement interferes with getting HW breakpoints ... according to the code I have. I added the limit not just to mirror cpptools. Without it, when you exceed the number of breakpoints, GDB is not well behaved....unless you set the "set remote hardware-breakpoint-limit 4", This is the whole reason I did this. Most people would not know to use that gdb feature. But, I made another mistake. I lumped breakpoints and watchpoints into the same category.
While your way of enforcing limits is clearly better, I don't want to revisit this when people see GDB messing up and me explaining oh...you need set these gdb options in preLaunchTask....
I see these commands go to gdb. Can you check your output again?
launch.json:
"hardwareBreakpoints": {
"require": true, // I fixed this typo
"limit": 6
},
Debug Console
18-break-insert -h "/Users/hdm/mtw35/Dual-CPU_Empty_PSOC6_App/proj_cm4/main.c:66"
19-break-insert -h "/Users/hdm/mtw35/Dual-CPU_Empty_PSOC6_App/proj_cm4/main.c:71"
20-break-insert -h "/Users/hdm/mtw35/Dual-CPU_Empty_PSOC6_App/proj_cm4/main.c:72"
21-break-insert -h "/Users/hdm/mtw35/Dual-CPU_Empty_PSOC6_App/proj_cm4/main.c:73"
22-break-insert -h "/Users/hdm/mtw35/Dual-CPU_Empty_PSOC6_App/proj_cm4/main.c:74"
23-break-insert -h "/Users/hdm/mtw35/Dual-CPU_Empty_PSOC6_App/proj_cm4/main.c:75"
and the following for the info: They are all HW breakpoints (I cleaned up the output)
info breakpoints
42-interpreter-exec console "info breakpoints"
1 hw breakpoint keep y 0x10004744 in main at /Users/hdm/mtw35/Dual-CPU_Empty_PSOC6_App/proj_cm4/main.c:66
2 hw breakpoint keep y 0x10004762 in main at /Users/hdm/mtw35/Dual-CPU_Empty_PSOC6_App/proj_cm4/main.c:71
3 hw breakpoint keep y 0x10004768 in main at /Users/hdm/mtw35/Dual-CPU_Empty_PSOC6_App/proj_cm4/main.c:72
4 hw breakpoint keep y 0x1000476e in main at /Users/hdm/mtw35/Dual-CPU_Empty_PSOC6_App/proj_cm4/main.c:73
5 hw breakpoint keep y 0x10004774 in main at /Users/hdm/mtw35/Dual-CPU_Empty_PSOC6_App/proj_cm4/main.c:74
6 hw breakpoint keep y 0x1000477a in main at /Users/hdm/mtw35/Dual-CPU_Empty_PSOC6_App/proj_cm4/main.c:75
I can provide a more thorough reproduction later, but I'll quickly note that the bug with "limit" only occurs after you try to set more than the "limit" value. So in your above example, if you try setting a 7th breakpoint, and then submit info break, I believe it will show that all the breakpoints have been converted to automatic breakpoints.