This is an archive of the discontinued LLVM Phabricator instance.

Add AArch64 MASK watchpoint support to debugserver
ClosedPublic

Authored by jasonmolenda on May 3 2023, 3:11 PM.

Details

Summary

AArch64 supports two types of watchpoints - 1-8 byte watchpoints, which can watch up to 8 contiguous bytes aligned to a doubleword boundary, and mask watchpoints that can watch any power-of-2 range of memory aligned to that boundary (BAS watchpoints and MASK watchpoints). This patch adds support for MASK watchpoints when the user requests larger than 8 bytes be watched.

The major caveat with this is that there remains real work in lldb to support large watchpoints. If a user asks to watch 192 bytes, aligned to a 256 byte boundary, we still need to watch 256 bytes. Writes to the final 64 bytes will trap the watchpoint, and we need to work out how to silently skip these watchpoint hits. Watchpoints have a type: "read", "write", and I expect I'll add a new type "modify" that is the default, and stops when the memory region being watched *changes*.

(this problem of a mask watchpoint watching a larger memory range than the user expected is exacerbated with a memory region not properly aligned to that power-of-2 size. and it can come up easily with smaller objects, e.g. a 24 byte object requires a 32-byte watchpoint, or possibly two watchpoints if it's not aligned to a 32-byte boundary.)

The changes I did https://reviews.llvm.org/D149040 make this patch mostly a simple drop-in of the method for setting the debug control register properly for MASK watchpoints. There are some extra changes to the method which takes a trap address and tries to find the hardware watchpoint register which resulted in that watchpoint hit. (we further refine this later based on the user's watchpoint requests, using a "nearest wp wins" if no watched region correctly includes it, for AArch64 reasons.)

I added a test case with an array of uint32_t's, watch 256 of those unit32_t's, and a loop that modifies every 16th uint32_t. The test confirms that we hit this 256-uint32_t's watchpoint 16 times.

Diff Detail

Event Timeline

jasonmolenda created this revision.May 3 2023, 3:11 PM
Herald added a project: Restricted Project. · View Herald TranscriptMay 3 2023, 3:11 PM
jasonmolenda requested review of this revision.May 3 2023, 3:11 PM
delcypher added inline comments.
lldb/test/API/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py
132

@jasonmolenda Maybe this code should be guarded rather than deleted?

Your change looks like it only affects arm64 Apple platforms? For everything else, presumably this restriction still applies? If so maybe we should still be testing it?

JDevlieghere accepted this revision.May 4 2023, 12:59 PM

Some small nits but LGTM

lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp
1079

I assume this can be const?

1082

const too?

1260–1262
const bool is_bas_watchpoint = (mask ==0);
This revision is now accepted and ready to land.May 4 2023, 12:59 PM

Update patch with Dan and Jonas' feedback.

This revision was landed with ongoing or failed builds.May 4 2023, 1:25 PM
This revision was automatically updated to reflect the committed changes.