Skip to content

Invalidate the register cache after a successful register write - #1173

Merged
xusheng6 merged 1 commit into
devfrom
test_1172_writeregister_cache
Aug 13, 2026
Merged

Invalidate the register cache after a successful register write#1173
xusheng6 merged 1 commit into
devfrom
test_1172_writeregister_cache

Conversation

@xusheng6

@xusheng6 xusheng6 commented Aug 12, 2026

Copy link
Copy Markdown
Member

Fixes #1172

WriteRegister did not invalidate the register cache after a successful P write, so
ReadRegister kept returning the pre-write value until a step or resume cleared it.
Editing a register looked like it did nothing.

Also check the reply is "OK" rather than non-empty: RSP answers E xx on failure and
'E' is non-zero, so failed writes were reported as successful. An empty reply means P
is unsupported and still falls through to the G fallback.

Same three lines in the Corellium, GDB and esReven adapters, so all three are fixed.

Verified on a live Corellium device: WriteRegister("x0") now reads back what it wrote.

@xusheng6
xusheng6 requested a review from plafosse August 12, 2026 20:54
WriteRegister sent the P packet and returned without invalidating the register
cache. ReadRegister goes through ReadAllRegisters, which serves m_regCache when it
is populated, so every read after a write returned the pre-write value until a step
or resume happened to clear it. Editing a register looked like it did nothing, and
the debugger kept computing with the old value.

Also check the reply is "OK" rather than merely non-empty. RSP answers "E xx" on
failure and 'E' is non-zero, so testing the first byte reported failed writes as
successful. An empty reply means P is unsupported and still falls through to the G
fallback, which already invalidates.

The same three lines are duplicated in the Corellium, GDB and esReven adapters, so
all three are fixed together.

Verified against a live Corellium device: before, a write to x0 landed on the target
(a raw RSP probe showed P0= returning OK and p0 returning the new value) while the
adapter kept reporting the old one; after, the read-back matches the written value
and restoring the original works.

Fixes #1172
@xusheng6
xusheng6 force-pushed the test_1172_writeregister_cache branch from 2ed0c35 to 1cc0e84 Compare August 12, 2026 20:55
@xusheng6
xusheng6 requested review from bdash and removed request for plafosse August 12, 2026 20:56

@plafosse plafosse left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is approved however i'm concerned about it a bit architecturally. Having to remember to call InvalidateCache at a bunch of different locations across all the adapters seems fragile and error prone. Could it be moved into WriteRegister

@xusheng6
xusheng6 removed the request for review from bdash August 13, 2026 21:24
@xusheng6

Copy link
Copy Markdown
Member Author

This is approved however i'm concerned about it a bit architecturally. Having to remember to call InvalidateCache at a bunch of different locations across all the adapters seems fragile and error prone. Could it be moved into WriteRegister

it is already inside of WriteRegister. The reason you see the code repeated 3 times is that we have 3 copies of similar code, and the reason for that is that we do that to account for the subtle differences and incompatibilities of the specific GDB RSP they each speak

The reason they all work with a GDB is that they tested against it during development. So if we also wish to be compatible with all of them, we need to replicate what GDB does exactly. That is also why I think we would be circulating back to GDB MI bc that feels like the only way to actually "do exactly as GDB"

@xusheng6
xusheng6 merged commit 4cf94e4 into dev Aug 13, 2026
2 checks passed
@xusheng6
xusheng6 deleted the test_1172_writeregister_cache branch August 13, 2026 21:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WriteRegister leaves a stale register cache, so reads return the pre-write value

2 participants