Skip to content

Hardware breakpoint remains armed after Cortex-Debug stops a pyOCD session #1244

Description

@CaFeZn

Describe the bug

When ending a Cortex-Debug session that uses pyOCD, a hardware breakpoint can remain programmed in the target's FPB comparator even though Cortex-Debug has issued break-delete and GDB reports success.

This reproduces with both Stop and Disconnect and Suspend. After the debug session has ended, asserting the board's hardware NRST still causes the target to halt at the old breakpoint. A later non-initializing SWD diagnostic read shows that the halt is a breakpoint event and that the old FPB comparator remains enabled.

As a diagnostic control, I manually issued a DAP disconnect request equivalent to:

{
  "terminateDebuggee": false,
  "suspendDebuggee": false
}

This exact plain-disconnect action is not exposed by the VS Code UI in this setup. It follows the detach path and does not reproduce the issue. This is evidence that distinguishes the two shutdown paths, not a user-accessible UI workaround.

Steps to reproduce

  1. Start a Cortex-Debug session using "servertype": "pyocd" and a CMSIS-DAP probe.
  2. Set a code breakpoint and continue until it is hit.
  3. End the session using Stop or Disconnect and Suspend.
  4. Assert hardware NRST after the debug session has ended.
  5. Observe that the target halts again at the old breakpoint location.
  6. Read the Cortex-M debug registers without target initialization. The stale FPB comparator is still enabled.

Expected behavior

All breakpoint removals should be committed to the target before the managed pyOCD process is terminated. After the session ends, no FPB comparator from that session should remain enabled, and NRST should not cause the target to halt at the old breakpoint.

Observed command sequence

The following is a shortened and sanitized sequence. Probe identifiers have been removed.

VS Code -> disconnect { terminateDebuggee: true }
Cortex-Debug -> <N>-break-delete
GDB -> <N>^done

GDB -> pyOCD: z1,<BREAKPOINT_ADDRESS>,2
pyOCD -> GDB: OK

Cortex-Debug -> terminates the managed pyOCD server process

No subsequent breakpoint insertion was observed after break-delete.

The evidence suggests that pyOCD updates its pending breakpoint state and replies OK, but the physical write that clears FP_COMP is not flushed before the process is terminated.

Hardware register evidence

After the session had ended and hardware NRST had been asserted, a non-initializing diagnostic read showed:

PC        = 0x08000804
DFSR.BKPT = 1
FP_COMP0  = 0x08000805

After explicitly clearing the stale comparator, a second read showed no enabled FPB comparator and the old breakpoint no longer remained.

Related issues

Environment

  • OS: Windows 11
  • VS Code: 1.125.1
  • Cortex-Debug: 1.12.1
  • pyOCD: 0.45.1
  • Arm GNU GDB: GNU Tools for STM32 13.3.rel1.20240926-1715 / GDB 14.2.90.20240526-git
  • Target: STM32C552CCU6 / Cortex-M33
  • Probe: CMSIS-DAP; serial number intentionally omitted
  • Session request: attach

Additional logs

Full sanitized Cortex-Debug, pyOCD, and GDB RSP traces can be provided if needed. Probe identifiers, user names, and local paths will be omitted.

Could Cortex-Debug allow the managed pyOCD process to complete its graceful cleanup before force termination, or use a pyOCD-specific graceful termination mechanism? If the current termination sequence is intentional, please confirm so the same trace can be followed up in pyOCD.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions