7
31
Fork
You've already forked blackmagic
23

Fix memory management in stm32mp15.c #2222

Merged
dragonmux merged 6 commits from ALTracer/blackmagic:fix/stm32mp15-ap-refcnt into main 2026年04月05日 19:10:12 +02:00
Contributor
Copy link

Detailed description

  • This is a bugfix to a recently introduced feature (#1757).
  • The existing problem is ASan reporting double-free after scanning STM32MP157 SoC.
  • The PR solves it by refactoring the (outdated, directly rebased) code to manage reference-counted AP properly and use priv_storage_s.

Tested with BMDA + STLINK/V3MINIE against STM32MP157 in Production and Engi Boot.
There are up to three targets, each allocates an extra AP (some of them will be duplicate), so let's move this from _probe() to _attach(). Then clean up in _detach() but keep in mind that target_list_free() will attempt to free() the priv storage, so it has to become NULL before that. It cannot be automatically freed that way because otherwise DP refcnt results in a small memory leak, reported by ASan (LSan). Finally, cm4 dbgmcu-related code also uses the priv storage, so simply add a pointer field to the struct and cast everywhere to access that.

Your checklist for this pull request

Closing issues

## Detailed description * This is a bugfix to a recently introduced feature (#1757). * The existing problem is ASan reporting double-free after scanning STM32MP157 SoC. * The PR solves it by refactoring the (outdated, directly rebased) code to manage reference-counted AP properly and use priv_storage_s. Tested with BMDA + STLINK/V3MINIE against STM32MP157 in Production and Engi Boot. There are up to three targets, each allocates an extra AP (some of them will be duplicate), so let's move this from _probe() to _attach(). Then clean up in _detach() but keep in mind that target_list_free() will attempt to free() the priv storage, so it has to become NULL before that. It cannot be automatically freed that way because otherwise DP refcnt results in a small memory leak, reported by ASan (LSan). Finally, cm4 dbgmcu-related code also uses the priv storage, so simply add a pointer field to the struct and cast everywhere to access that. ## Your checklist for this pull request * [x] I've read the [Code of Conduct](https://codeberg.org/blackmagic-debug/blackmagic/src/CODE_OF_CONDUCT.md) * [x] I've read the [guidelines for contributing](https://codeberg.org/blackmagic-debug/blackmagic/src/CONTRIBUTING.md) to this repository * [x] It builds for hardware native (see [Building the firmware](https://codeberg.org/blackmagic-debug/blackmagic?tab=readme-ov-file#building-the-firmware)) * [x] It builds as BMDA (see [Building the BMDA](https://codeberg.org/blackmagic-debug/blackmagic?tab=readme-ov-file#building-black-magic-debug-app)) * [x] I've tested it to the best of my ability * [x] My commit messages provide a useful short description of what the commits do ## Closing issues
dragonmux requested changes 2026年03月30日 19:59:52 +02:00
Dismissed
@ -229,2 +231,3 @@
{
adiv5_access_port_s *const ap0 = (adiv5_access_port_s *)target->target_storage;
stm32mp15_priv_s *const priv = (stm32mp15_priv_s *)target->target_storage;
adiv5_access_port_s *const ap0 = priv->ap;

this could just become priv->ap on the line below.. having the extra variable here doesn't give us anything extra we think.

this could just become `priv->ap` on the line below.. having the extra variable here doesn't give us anything extra we think.
Author
Contributor
Copy link

It carries the name ap0, which is not very important.
However, there was an uncleaned up bug in cmd_swo, I need to access a field of priv, not entire priv, to reach saved ap1.

It carries the name ap0, which is not very important. However, there was an uncleaned up bug in cmd_swo, I need to access a field of priv, not entire priv, to reach saved ap1.
Author
Contributor
Copy link

this item should be fixed now.

this item should be fixed now.
dragonmux marked this conversation as resolved
@ -258,0 +276,4 @@
if (!cortexar_attach(target))
return false;
stm32mp15_ca7_setup_axi_ap(target);
target->mem_read = stm32mp15_ca7_mem_read;

As detach doesn't put these back after, this will cause a crash.. would be better to assign them in probe, and have a check for target storage and the AP being NULL, and if either are, deferring back to cortexar_mem_read()/cortexar_mem_write()..

As detach doesn't put these back after, this will cause a crash.. would be better to assign them in probe, and have a check for target storage and the AP being NULL, and if either are, deferring back to cortexar_mem_read()/cortexar_mem_write()..
Author
Contributor
Copy link

Have a NULL-check where? In every access, i.e. in mem_read? Isn't that expensive?
What uses mem_read after detach?

Have a NULL-check where? In every access, i.e. in mem_read? Isn't that expensive? What uses mem_read after detach?

The next attach; and not necessarily expensive.. it's not a check against the target, just a local check in those control structures

The next attach; and not necessarily expensive.. it's not a check against the target, just a local check in those control structures
Author
Contributor
Copy link

cortexar_mem_read/write() are not public functions. Should I save-restore the pointers or just NULL them?

cortexar_mem_read/write() are not public functions. Should I save-restore the pointers or just NULL them?

Save/restore or otherwise expose the functions..

Save/restore or otherwise expose the functions..
Author
Contributor
Copy link

As save/restore will create a larger size-diff, opted for exposing the functions. The standalone commit for that produces a local +0 size-diff when cherry-picked onto a clear throwaway branch on main.

As save/restore will create a larger size-diff, opted for exposing the functions. The standalone commit for that produces a local +0 size-diff when cherry-picked onto a clear throwaway branch on `main`.
dragonmux marked this conversation as resolved
ALTracer force-pushed fix/stm32mp15-ap-refcnt from c5f1adbd0b
Some checks failed
ci/woodpecker/pr/build-firmware/3 Pipeline was successful
ci/woodpecker/pr/build-firmware/1 Pipeline was successful
ci/woodpecker/pr/build-firmware/8 Pipeline was successful
ci/woodpecker/pr/build-firmware/4 Pipeline was successful
ci/woodpecker/pr/build-firmware/5 Pipeline was successful
ci/woodpecker/pr/build-firmware/7 Pipeline was successful
ci/woodpecker/pr/build-firmware/2 Pipeline was successful
ci/woodpecker/pr/build-firmware/6 Pipeline was successful
ci/woodpecker/pr/build-firmware/12 Pipeline was successful
ci/woodpecker/pr/build-firmware/13 Pipeline was successful
ci/woodpecker/pr/build-firmware/15 Pipeline was successful
ci/woodpecker/pr/build-firmware/10 Pipeline was successful
ci/woodpecker/pr/build-firmware/16 Pipeline was successful
ci/woodpecker/pr/build-firmware/14 Pipeline was successful
ci/woodpecker/pr/build-firmware/11 Pipeline was successful
ci/woodpecker/pr/build-firmware/9 Pipeline was successful
ci/woodpecker/pr/build-firmware/17 Pipeline was successful
ci/woodpecker/pr/build-linux/1 Pipeline was successful
ci/woodpecker/pr/build-firmware/18 Pipeline failed
ci/woodpecker/pr/build-firmware/19 Pipeline was successful
ci/woodpecker/pr/build-firmware/20 Pipeline was successful
ci/woodpecker/pr/build-linux/2 Pipeline was successful
ci/woodpecker/pr/build-windows Pipeline was successful
to 8620e0f359
Some checks are pending
ci/woodpecker/pr/build-firmware/1 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/2 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/3 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/4 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/5 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/6 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/7 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/8 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/9 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/10 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/11 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/12 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/13 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/14 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/15 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/16 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/17 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/18 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/19 Pipeline is pending approval
ci/woodpecker/pr/build-firmware/20 Pipeline is pending approval
ci/woodpecker/pr/build-linux/1 Pipeline is pending approval
ci/woodpecker/pr/build-linux/2 Pipeline is pending approval
ci/woodpecker/pr/build-windows Pipeline is pending approval
2026年03月31日 10:53:17 +02:00
Compare
dragonmux left a comment
Copy link

We can only spot the one thing still slightly amiss - with that sorted, we'll approve this and merge it. Everything else looks good!

We can only spot the one thing still slightly amiss - with that sorted, we'll approve this and merge it. Everything else looks good!
@ -134,1 +135,3 @@
adiv5_access_port_s *const ap1 = (adiv5_access_port_s *)target->target_storage;
stm32mp15_priv_s *priv = (stm32mp15_priv_s *)target->target_storage;
/* Prefer AP1 over AP0 when attached to CA7 (because no CoreSight components are on AP0) */
adiv5_access_port_s *const ap1 = (priv->ap->apsel == 1) ? priv->ap : cortex_ap(target);

Please suffix the constant with U so it's an unsigned-unsigned comparison

Please suffix the constant with `U` so it's an unsigned-unsigned comparison
Author
Contributor
Copy link

Suffixed.

Suffixed.
dragonmux marked this conversation as resolved
ALTracer force-pushed fix/stm32mp15-ap-refcnt from 14dee0c8ab
Some checks failed
ci/woodpecker/pr/build-firmware/4 Pipeline failed
ci/woodpecker/pr/build-firmware/1 Pipeline failed
ci/woodpecker/pr/build-firmware/3 Pipeline failed
ci/woodpecker/pr/build-firmware/6 Pipeline failed
ci/woodpecker/pr/build-firmware/7 Pipeline failed
ci/woodpecker/pr/build-firmware/2 Pipeline failed
ci/woodpecker/pr/build-firmware/5 Pipeline failed
ci/woodpecker/pr/build-firmware/8 Pipeline failed
ci/woodpecker/pr/build-firmware/9 Pipeline failed
ci/woodpecker/pr/build-firmware/12 Pipeline failed
ci/woodpecker/pr/build-firmware/10 Pipeline failed
ci/woodpecker/pr/build-firmware/15 Pipeline failed
ci/woodpecker/pr/build-firmware/11 Pipeline failed
ci/woodpecker/pr/build-firmware/16 Pipeline failed
ci/woodpecker/pr/build-firmware/14 Pipeline failed
ci/woodpecker/pr/build-firmware/13 Pipeline failed
ci/woodpecker/pr/build-linux/2 Pipeline failed
ci/woodpecker/pr/build-firmware/20 Pipeline failed
ci/woodpecker/pr/build-linux/1 Pipeline failed
ci/woodpecker/pr/build-firmware/17 Pipeline failed
ci/woodpecker/pr/build-firmware/18 Pipeline failed
ci/woodpecker/pr/build-firmware/19 Pipeline failed
ci/woodpecker/pr/build-windows Pipeline failed
to 5d034726d2
Some checks failed
ci/woodpecker/pr/build-firmware/7 Pipeline was successful
ci/woodpecker/pr/build-firmware/4 Pipeline was successful
ci/woodpecker/pr/build-firmware/2 Pipeline was successful
ci/woodpecker/pr/build-firmware/5 Pipeline was successful
ci/woodpecker/pr/build-firmware/1 Pipeline was successful
ci/woodpecker/pr/build-firmware/6 Pipeline was successful
ci/woodpecker/pr/build-firmware/3 Pipeline was successful
ci/woodpecker/pr/build-firmware/12 Pipeline was successful
ci/woodpecker/pr/build-firmware/8 Pipeline was successful
ci/woodpecker/pr/build-firmware/9 Pipeline was successful
ci/woodpecker/pr/build-firmware/14 Pipeline was successful
ci/woodpecker/pr/build-firmware/10 Pipeline was successful
ci/woodpecker/pr/build-firmware/13 Pipeline was successful
ci/woodpecker/pr/build-firmware/11 Pipeline was successful
ci/woodpecker/pr/build-linux/1 Pipeline was successful
ci/woodpecker/pr/build-firmware/17 Pipeline was successful
ci/woodpecker/pr/build-firmware/18 Pipeline failed
ci/woodpecker/pr/build-firmware/20 Pipeline was successful
ci/woodpecker/pr/build-firmware/15 Pipeline was successful
ci/woodpecker/pr/build-firmware/16 Pipeline was successful
ci/woodpecker/pr/build-firmware/19 Pipeline was successful
ci/woodpecker/pr/build-linux/2 Pipeline was successful
ci/woodpecker/pr/build-windows Pipeline was successful
2026年04月05日 18:44:20 +02:00
Compare
dragonmux approved these changes 2026年04月05日 18:48:08 +02:00
Dismissed
dragonmux left a comment
Copy link

LGTM, merging once CI completes. Thank you for the contribution!

LGTM, merging once CI completes. Thank you for the contribution!
ALTracer force-pushed fix/stm32mp15-ap-refcnt from 5d034726d2
Some checks failed
ci/woodpecker/pr/build-firmware/7 Pipeline was successful
ci/woodpecker/pr/build-firmware/4 Pipeline was successful
ci/woodpecker/pr/build-firmware/2 Pipeline was successful
ci/woodpecker/pr/build-firmware/5 Pipeline was successful
ci/woodpecker/pr/build-firmware/1 Pipeline was successful
ci/woodpecker/pr/build-firmware/6 Pipeline was successful
ci/woodpecker/pr/build-firmware/3 Pipeline was successful
ci/woodpecker/pr/build-firmware/12 Pipeline was successful
ci/woodpecker/pr/build-firmware/8 Pipeline was successful
ci/woodpecker/pr/build-firmware/9 Pipeline was successful
ci/woodpecker/pr/build-firmware/14 Pipeline was successful
ci/woodpecker/pr/build-firmware/10 Pipeline was successful
ci/woodpecker/pr/build-firmware/13 Pipeline was successful
ci/woodpecker/pr/build-firmware/11 Pipeline was successful
ci/woodpecker/pr/build-linux/1 Pipeline was successful
ci/woodpecker/pr/build-firmware/17 Pipeline was successful
ci/woodpecker/pr/build-firmware/18 Pipeline failed
ci/woodpecker/pr/build-firmware/20 Pipeline was successful
ci/woodpecker/pr/build-firmware/15 Pipeline was successful
ci/woodpecker/pr/build-firmware/16 Pipeline was successful
ci/woodpecker/pr/build-firmware/19 Pipeline was successful
ci/woodpecker/pr/build-linux/2 Pipeline was successful
ci/woodpecker/pr/build-windows Pipeline was successful
to 3c2be4a101
Some checks failed
ci/woodpecker/pr/build-firmware/5 Pipeline is pending
ci/woodpecker/pr/build-firmware/6 Pipeline is pending
ci/woodpecker/pr/build-firmware/7 Pipeline is pending
ci/woodpecker/pr/build-firmware/8 Pipeline is pending
ci/woodpecker/pr/build-firmware/9 Pipeline is pending
ci/woodpecker/pr/build-firmware/10 Pipeline is pending
ci/woodpecker/pr/build-firmware/11 Pipeline is pending
ci/woodpecker/pr/build-firmware/12 Pipeline is pending
ci/woodpecker/pr/build-firmware/13 Pipeline is pending
ci/woodpecker/pr/build-firmware/14 Pipeline is pending
ci/woodpecker/pr/build-firmware/15 Pipeline is pending
ci/woodpecker/pr/build-firmware/16 Pipeline is pending
ci/woodpecker/pr/build-firmware/17 Pipeline is pending
ci/woodpecker/pr/build-firmware/18 Pipeline is pending
ci/woodpecker/pr/build-firmware/19 Pipeline is pending
ci/woodpecker/pr/build-firmware/20 Pipeline is pending
ci/woodpecker/pr/build-linux/1 Pipeline is pending
ci/woodpecker/pr/build-linux/2 Pipeline is pending
ci/woodpecker/pr/build-windows Pipeline is pending
ci/woodpecker/pr/build-firmware/3 Pipeline failed
ci/woodpecker/pr/build-firmware/1 Pipeline failed
ci/woodpecker/pr/build-firmware/2 Pipeline failed
ci/woodpecker/pr/build-firmware/4 Pipeline failed
2026年04月05日 18:57:58 +02:00
Compare
ALTracer dismissed dragonmux's review 2026年04月05日 18:57:59 +02:00
Reason:

New commits pushed, approval review dismissed automatically according to repository settings

Author
Contributor
Copy link

Published cortexar_mem_read/write() like cortexar_attach/detach() to cortexar.h header. Will rebase onto main as preparation for merge.

Published cortexar_mem_read/write() like cortexar_attach/detach() to cortexar.h header. Will rebase onto main as preparation for merge.
ALTracer force-pushed fix/stm32mp15-ap-refcnt from 3c2be4a101
Some checks failed
ci/woodpecker/pr/build-firmware/5 Pipeline is pending
ci/woodpecker/pr/build-firmware/6 Pipeline is pending
ci/woodpecker/pr/build-firmware/7 Pipeline is pending
ci/woodpecker/pr/build-firmware/8 Pipeline is pending
ci/woodpecker/pr/build-firmware/9 Pipeline is pending
ci/woodpecker/pr/build-firmware/10 Pipeline is pending
ci/woodpecker/pr/build-firmware/11 Pipeline is pending
ci/woodpecker/pr/build-firmware/12 Pipeline is pending
ci/woodpecker/pr/build-firmware/13 Pipeline is pending
ci/woodpecker/pr/build-firmware/14 Pipeline is pending
ci/woodpecker/pr/build-firmware/15 Pipeline is pending
ci/woodpecker/pr/build-firmware/16 Pipeline is pending
ci/woodpecker/pr/build-firmware/17 Pipeline is pending
ci/woodpecker/pr/build-firmware/18 Pipeline is pending
ci/woodpecker/pr/build-firmware/19 Pipeline is pending
ci/woodpecker/pr/build-firmware/20 Pipeline is pending
ci/woodpecker/pr/build-linux/1 Pipeline is pending
ci/woodpecker/pr/build-linux/2 Pipeline is pending
ci/woodpecker/pr/build-windows Pipeline is pending
ci/woodpecker/pr/build-firmware/3 Pipeline failed
ci/woodpecker/pr/build-firmware/1 Pipeline failed
ci/woodpecker/pr/build-firmware/2 Pipeline failed
ci/woodpecker/pr/build-firmware/4 Pipeline failed
to 24e36ec574
Some checks failed
ci/woodpecker/pr/build-firmware/18 Pipeline failed
ci/woodpecker/pr/build-firmware/17 Pipeline was successful
ci/woodpecker/pr/build-firmware/19 Pipeline was successful
ci/woodpecker/pr/build-firmware/20 Pipeline was successful
ci/woodpecker/pr/build-linux/1 Pipeline was successful
ci/woodpecker/pr/build-linux/2 Pipeline was successful
ci/woodpecker/pr/build-windows Pipeline was successful
ci/woodpecker/push/build-firmware/1 Pipeline was successful
ci/woodpecker/push/build-firmware/2 Pipeline was successful
ci/woodpecker/push/build-firmware/3 Pipeline was successful
ci/woodpecker/push/build-firmware/4 Pipeline was successful
ci/woodpecker/push/build-firmware/5 Pipeline was successful
ci/woodpecker/push/build-firmware/6 Pipeline was successful
ci/woodpecker/push/build-firmware/11 Pipeline was successful
ci/woodpecker/push/build-firmware/10 Pipeline was successful
ci/woodpecker/push/build-firmware/7 Pipeline was successful
ci/woodpecker/push/build-firmware/8 Pipeline was successful
ci/woodpecker/push/build-firmware/9 Pipeline was successful
ci/woodpecker/push/build-firmware/12 Pipeline was successful
ci/woodpecker/push/build-firmware/17 Pipeline was successful
ci/woodpecker/push/build-firmware/13 Pipeline was successful
ci/woodpecker/push/build-firmware/16 Pipeline was successful
ci/woodpecker/push/build-firmware/14 Pipeline was successful
ci/woodpecker/push/build-firmware/15 Pipeline was successful
ci/woodpecker/push/build-linux/1 Pipeline was successful
ci/woodpecker/push/build-firmware/18 Pipeline failed
ci/woodpecker/push/build-firmware/19 Pipeline was successful
ci/woodpecker/push/build-firmware/20 Pipeline was successful
ci/woodpecker/push/build-linux/2 Pipeline was successful
ci/woodpecker/push/build-windows Pipeline was successful
2026年04月05日 19:02:04 +02:00
Compare
Sign in to join this conversation.
No reviewers
Labels
Clear labels
BMD App
Black Magic Debug App (aka. PC hosted) (not firmware)
BMP Firmware
Black Magic Probe Firmware (not PC hosted software)
Bug
Confirmed bug
Build system
Build system
Can't reproduce
Maintainers can't reproduce this problem
CI
Continuous Integration System
Contribution wanted
User contributions welcome
Documentation
Project documentation
Draft
Work in progress draft
Duplicate
This issue or pull request already exists
Enhancement
General project improvement
Feedback wanted
Requires additional submitter feedback
Foreign Host Board
Non Native hardware to runing Black Magic firmware on
GDB
Issue/PR related to GDB
Good first issue
Good for newcommers
HwIssue Mitigation
Solving or mitigating a Hardware issue in Software
Information Needed
Maintainers need more information
NativeHardware
Official Black Magic Debug Hardware
New Host Board
New hardware to run Black Magic firmware on
New Target
New debug target
Off Topic
Something that does not involve the project in any way
Potential Bug
A potential, unconfirmed or very special circumstance bug
Regression
Bug caused by a regression
User Interest Needed
More user interest required before consideration
User Testing Needed
Looking for user testing reports
Won't fix
Outside of the project scope or works as intended
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
blackmagic-debug/blackmagic!2222
Reference in a new issue
blackmagic-debug/blackmagic
No description provided.
Delete branch "ALTracer/blackmagic:fix/stm32mp15-ap-refcnt"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?