I will be changing breakpoint hitting behavior soon, where currently
lldb reports a breakpoint as being hit when a thread is *at* a
BreakpointSite, but possibly has not executed the breakpoint instruction
and trapped yet, to having lldb only report a breakpoint hit when the
breakpoint instruction has actually been executed.
One corner case bug with this change is that when you are stopped at a
breakpoint (that has been hit) on the last instruction of a function,
and you do `finish`, a ThreadPlanStepOut is pushed to the thread's plan
stack to put a breakpoint on the return address and resume execution.
And when the thread is asked to resume, it sees that it is at a
BreakpointSite that has been hit, and pushes a
ThreadPlanStepOverBreakpoint on the thread. The StepOverBreakpoint
plan sees that the thread's state is eStateRunning (not eStateStepping),
so it marks itself as "auto continue" -- so once the breakpoint has
been stepped over, we will execution on the thread.
With current lldb stepping behavior ("a thread *at* a BreakpointSite is
said to have stopped with a breakpoint-hit stop reason, even if the
breakpoint hasn't been executed yet"),
`ThreadPlanStepOverBreakpoint::DoPlanExplainsStop` has a special bit of
code which detects when the thread stops with a eStopReasonBreakpoint.
It first checks if the pc is the same as when we started -- did our
"step instruction" not actually step? -- says the stop reason is
explained. Otherwise it sets auto-continue to false (because we've hit
an *unexpected* breakpoint, and we have advanced past our original pc,
and returns false - the stop reason is not explained.
So we do the "finish", lldb instruction steps, we stop *at* the
return-address breakpoint and lldb sets the thread's stop reason to
breakpoint-hit. ThreadPlanStepOverBreakpoint sees an
eStopReasonBreakpoint, sets its auto-continue to false, and says we
stopped for osme reason other than this plan. (and it will also report
`IsPlanStale()==true` so it will remove itself) Meanwhile the
ThreadPlanStepOut sees that it has stopped in the StackID it wanted to
run to, and return success.
This all changes when stopping at a breakpoint site doesn't report
breakpoint-hit until we actually execute the instruction. Now the
ThraedPlanStepOverBreakpoint looks at the thread's stop reason, it's
eStopReasonTrace (we've instruction stepped), and so it leaves its
auto-continue to `true`. ThreadPlanStepOut sees that it has reached its
goal StackID, removes its breakpoint, and says it is done.
Thread::ShouldStop thinks the auto-continue == yes vote from
ThreadPlanStepOverBreakpoint wins, and we lose control of the process.
This patch changes ThreadPlanStepOut to require that *both* (1) we are
at the StackID of the caller function, where we wanted to end up, and
(2) we have actually hit the breakpoint that we inserted.
This in effect means that now lldb instruction-steps over the breakpoint
in the callee function, stops at the return address of the caller
function. StepOverBreakpoint has completed. StepOut is still running,
and we continue the thread again. We immediatley hit the breakpoint
(that we're sitting at), and now ThreadPlanStepOut marks itself as
completed, and we return control to the user.
Jim suggests that ThreadPlanStepOverBreakpoint is a bit unusual because
it's not something pushed on the stack by a higher-order thread plan
that "owns" it, it is inserted by the Thread as it is about to resume,
if we're at a BreakpointSite. It has no connection to the thread plans
above it, but tries to set the auto-continue mode based on the state of
the thread when it is inserted (and tries to detect an unexpected
breakpoint and unset that auto-continue it previously decided on,
because it now realizes it should not influence execution control any
more). Instead maybe the
ThreadPlanStepOverBreakpoint should be inserted as a child plan of
whatever the lowest plan is on the stack at the point it is added.
I added an API test that will catch this bug in the new thread
breakpoint algorithm.
Remove Debugger::GetOutputStream and Debugger::GetErrorStream in
preparation for replacing both with a new variant that needs to be
locked and hence can't be handed out like we do right now.
The patch replaces most uses with GetAsyncOutputStream and
GetAsyncErrorStream respectively. There methods return new StreamSP
objects that automatically get flushed on destruction.
See #126630 for more details.
Background:
Telemetry code isn't always built (controlled by this
LLVM_BUILD_TELEMETRY cmake flag)
This means users of the library may not have the library. So we're
definding the `-DLLVM_BUILD_TELEMETRY` to be used in ifdef.
The command already supported disassembling multiple ranges, among other
reasons because inline functions can be discontinuous. The main thing
that was missing was being able to retrieve the function ranges from the
top level function object.
The output of the command for the case where the function entry point is
not its lowest address is somewhat confusing (we're showing negative
offsets), but it is correct.
Nobody is overriding GetValueProperties, so in practice we're always
using `m_collection_sp`, which means we don't need to check the pointer.
The temlated helpers were already operating on `m_collection_sp`
directly so this makes the rest of the class consistent.
This typedef doesn't match the signature below, specifically the
signature takes a `lldb:SBDebugger` vs this was defined as
`lldb:SBDebugger&`.
```
lldb/source/API/SBDebugger.cpp:199:13: runtime error: call to function lldb::PluginInitialize(lldb::SBDebugger) through pointer to incorrect function type 'bool (*)(lldb::SBDebugger &)'
.../CustomPlugin.cpp:134: note: lldb::PluginInitialize(lldb::SBDebugger) defined here
```
Use a preprocessor `#ifdef LLVM_BUILD_TELEMETRY` guard rather than
`PARTIAL_SOURCES_INTENDED` for the `Telemetry.cpp` file, to fix building
with telemetry disabled. `PARTIAL_SOURCES_INTENDED` does not currently
work in `lldb_add_library()`, and while it could be fixed, it seems to
be used contrary to its purpose — in other parts of LLVM project, the
option is used to indicate that the sources found in the directory are
split between different targets (e.g. a library and a tool), not to
include sources conditionally.
A section of ObjectFileMachO is ifdef compiled only when
building to run on iOS etc natively, so this old method
call rename wasn't detected by normal on-mac building.
A DriverKit process is a kernel extension that runs in userland, instead
of running in the kernel address space/priv levels, they've been around
a couple of years. From lldb's perspective a DriverKit process is no
different from any other userland level process, but it has a different
Triple so we need to handle those cases in the lldb codebase. Some of
the DriverKit triple handling had been upstreamed to llvm-project, but I
noticed a few cases that had not yet. Cleaning that up.
Details:
- This is a subset of PR/98528.( Pavel's suggestion was to split up the
patch to make reviewing easier)
- This contains only the concrete implementation of the framework to be
used but no usages yet.
- I plan to send a few follow-up patches:
+ part2 : includes changes in the plugin-manager to set up the plugin
stuff (ie., how to create a default vs vendor impl)
+ part3 (all of the following can be done in parallel):
* part 3_a: define DebuggerTelemetryInfo and related methods to collect
data about debugger startup/exit
* part 3_b: define TargetTelemetryInfo and related methods to collect
data about debug target(s)
* part 3_c: define CommandTelemetryInfo and related methods to collect
data about debug-commands
* part 3_d: define ClientTelemtryInfo and related methods to collect
data about lldb-dap/any other client
---------
Co-authored-by: Pavel Labath <pavel@labath.sk>
Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
Recognize the visionOS Triple::OSType::XROS os type. Some of these have
already been landed on main, but I reviewed the downstream sources and
there were a few that still needed to be landed upstream.
This patch consumes the `DW_AT_APPLE_enum_kind` attribute added in
https://github.com/llvm/llvm-project/pull/124752 and turns it into a
Clang attribute in the AST. This will currently be used by the Swift
language plugin when it creates `EnumDecl`s from debug-info and passes
it to Swift compiler, which expects these attributes
The maximum number of load/store watchpoints and fetch instruction
watchpoints is 14 each according to LoongArch Reference Manual [1],
so extend the maximum number of watchpoints from 8 to 14 for ptrace.
A new struct user_watch_state_v2 was added into uapi in the related
kernel commit 531936dee53e ("LoongArch: Extend the maximum number of
watchpoints") [2], but there may be no struct user_watch_state_v2 in
the system header in time.
In order to avoid undefined or redefined error, just add a new struct
loongarch_user_watch_state in LLDB which is same with the uapi struct
user_watch_state_v2, then replace the current user_watch_state with
loongarch_user_watch_state.
As far as I can tell, the only users for this struct in the userspace
are GDB and LLDB, there are no any problems of software compatibility
between the application and kernel according to the analysis.
The compatibility problem has been considered while developing and
testing. When the applications in the userspace get watchpoint state,
the length will be specified which is no bigger than the sizeof struct
user_watch_state or user_watch_state_v2, the actual length is assigned
as the minimal value of the application and kernel in the generic code
of ptrace:
```
kernel/ptrace.c: ptrace_regset():
kiov->iov_len = min(kiov->iov_len,
(__kernel_size_t) (regset->n * regset->size));
if (req == PTRACE_GETREGSET)
return copy_regset_to_user(task, view, regset_no, 0,
kiov->iov_len, kiov->iov_base);
else
return copy_regset_from_user(task, view, regset_no, 0,
kiov->iov_len, kiov->iov_base);
```
For example, there are four kind of combinations, all of them work well.
(1) "older kernel + older app", the actual length is 8+(8+8+4+4)*8=200;
(2) "newer kernel + newer app", the actual length is 8+(8+8+4+4)*14=344;
(3) "older kernel + newer app", the actual length is 8+(8+8+4+4)*8=200;
(4) "newer kernel + older app", the actual length is 8+(8+8+4+4)*8=200.
[1]
https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#control-and-status-registers-related-to-watchpoints
[2]
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=531936dee53e
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
PR #86603 broke unwinding in for unwind info added via "target symbols
add". #86770 attempted to fix this, but the fix was only partial -- it
accepted new sources of unwind information, but didn't take into account
that the symbol file can alter what lldb percieves as function
boundaries.
A stripped file will not contain information about private
(non-exported) symbols, which will make the public symbols appear very
large. If lldb tries to unwind from such a function before symbols are
added, then the cached unwind plan will prevent new (correct) unwind
plans from being created.
target-symbols-add-unwind.test might have caught this, were it not for
the fact that the "image show-unwind" command does *not* use cached
unwind information (it recomputes it from scratch).
The changes in this patch come in three pieces:
- Clear cached unwind plans when adding symbols. Since the symbol
boundaries can change, we cannot trust anything we've computed
previously.
- Add a flag to "image show-unwind" to display the cached unwind
information (mainly for the use in the test, but I think it's also
generally useful).
- Rewrite the test to better and more reliably simulate the real-world
scenario: I've swapped the running process for a core (minidump) file so
it can run anywhere; used the caching version of the show-unwind
command; and swapped C for assembly to better control the placement of
symbols
This addresses the MSAN failure reported
in
https://github.com/llvm/llvm-project/pull/125791#issuecomment-2639183154:
```
==5633==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 in clang::ASTNodeImporter::CallOverloadedCreateFun<clang::ClassTemplateSpecializationDecl>::operator()
#1 in bool clang::ASTNodeImporter::GetImportedOrCreateSpecialDecl<...>
...
```
The ASTImporter reads `D->hasStrictPackMatch()` and forwards it to the
constructor of the destination `ClassTemplateSpecializationDecl`. But if
`D` is a decl that LLDB created from debug-info, it would've been
created using `ClassTemplateSpecializationDecl::CreateDeserialized`,
which doesn't initialize the `StrictPackMatch` field.
This patch just initializes the field to a fixed value of `false`, to
preserve previous behaviour and avoid the use-of-uninitialized-value.
An alternative would be to always initialize it in the
`ClassTemplateSpecializationDecl` constructor, but there were
reservations about providing a default value for it because it might
lead to hard-to-diagnose problems down the line.
Setting a breakpoint on `<symbol> + <offset>` used to work until
`2c76e88e9eb284d17cf409851fb01f1d583bb22a`, where this regex was
reworked. Now we only accept `<symbol>+ <offset>` or
`<symbol>+<offset>`.
This patch fixes the regression by adding yet another `[[:space:]]*`
component to the regex.
One could probably simplify the regex (or even replace the regex by just
calling the relevent `consumeXXX` APIs on `llvm::StringRef`). Though I
left that for the future.
rdar://130780342
On some OS distros such as LoongArch Fedora 38 mate-5 [1], there are
no macro definitions NT_LOONGARCH_HW_BREAK and NT_LOONGARCH_HW_WATCH
in the system header, then there exist some errors when building LLDB
on LoongArch.
(1) Description of Problem:
```
llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_loongarch64.cpp:529:16:
error: 'NT_LOONGARCH_HW_WATCH' was not declared in this scope; did you mean 'NT_LOONGARCH_LBT'?
529 | int regset = NT_LOONGARCH_HW_WATCH;
| ^~~~~~~~~~~~~~~~~~~~~
| NT_LOONGARCH_LBT
llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_loongarch64.cpp:543:12:
error: 'NT_LOONGARCH_HW_BREAK' was not declared in this scope; did you mean 'NT_LOONGARCH_CSR'?
543 | regset = NT_LOONGARCH_HW_BREAK;
| ^~~~~~~~~~~~~~~~~~~~~
| NT_LOONGARCH_CSR
```
(2) Steps to Reproduce:
```
git clone https://github.com/llvm/llvm-project.git
mkdir -p llvm-project/llvm/build && cd llvm-project/llvm/build
cmake .. -G "Ninja" \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_BUILD_RUNTIME=OFF \
-DLLVM_ENABLE_PROJECTS="clang;lldb" \
-DCMAKE_INSTALL_PREFIX=/usr/local/llvm \
-DLLVM_TARGETS_TO_BUILD="LoongArch" \
-DLLVM_HOST_TRIPLE=loongarch64-redhat-linux
ninja
```
(3) Additional Info:
Maybe there are no problems on the OS distros with newer glibc devel
library, so this issue is related with OS distros.
(4) Root Cause Analysis:
This is because the related Linux kernel commit [2] was merged in
2023-02-25 and the glibc devel library has some delay with kernel,
the glibc version of specified OS distros is not updated in time.
(5) Final Solution:
One way is to ask the maintainer of OS distros to update glibc devel
library, but it is better to not depend on the glibc version.
In order to avoid the build errors, just define NT_LOONGARCH_HW_BREAK
and NT_LOONGARCH_HW_WATCH in LLDB if there are no these definitions in
the system header.
By the way, in order to fit within 80 columns, use C++-style comments
for the new added NT_LOONGARCH_HW_BREAK and NT_LOONGARCH_HW_WATCH.
While at it, for consistency, just modify the current NT_LOONGARCH_LSX
and NT_LOONGARCH_LASX to C++-style comments too.
[1]
https://mirrors.wsyu.edu.cn/fedora/linux/development/rawhide/Everything/loongarch64/iso/livecd-fedora-mate-5.loongarch64.iso
[2]
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1a69f7a161a7
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
In Sep 2016 and newer Darwin releases, debugserver uses libdyld SPI to
gather information about the binaries loaded in a process. Before Sep
2016, lldb would inspect the dyld internal data structures directly
itself to find this information.
DynamicLoaderDarwin::UseDYLDSPI currently defaults to the old
inspect-dyld-internal-structures method for binaries
(DynamicLoaderMacOSXDYLD). If it detects that the Process' host OS
version is new enough, it enables the newer libdyld SPI methods in
debugserver (DynamicLoaderMacOS).
This patch changes the default to use the new libdyld SPI interfaces. If
the Process has a HostOS and it is one of the four specific OSes that
existed in 2015 (Mac OS X, iOS, tvOS, watchOS) with an old version
number, then we will enable the old DynamicLoader plugin.
If this debug session is a corefile, we will always use the old
DynamicLoader plugin -- the libdyld SPI cannot run against a corefile,
lldb must read metadata or the dyld internal data structures in the
corefile to find the loaded binaries.
…uffer
ValueObjectDynamicValue::UpdateValue() assumes that the dynamic type
found by GetDynamicTypeAndAddress() would return an address in the
inferior. This commit makes it so it can deal with being passed a host
address instead.
This is needed downstream by the Swift fork.
rdar://143357274
These prevented ThreadMemory from correctly returning the
Name/Queue/Info of the backing thread.
Note about testing: this test only finds regressions if the system sets
a name or queue for the backing thread. While this may not be true
everywhere, it still provides coverage in some systems, e.g. in Apple
platforms.
Many uses of SC::GetAddressRange were not interested in the range, but
in the address of the function/symbol contained inside the symbol
context. They were getting that by calling the GetBaseAddress on the
returned range, which worked well enough so far, but isn't compatible
with discontinuous functions, whose address (entry point) may not be the
lowest address in the range.
To resolve this problem, this PR creates a new function whose purpose is
return the address of the function or symbol inside the symbol context.
It also changes all of the callers of GetAddressRange which do not
actually care about the range to call this function instead.
This patch adds the ability to open URLs from lldb on macOS. This can be
a website URL or a deep link to a particular application.
rdar://143327616
Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
Class templates might be only instantiated when they are required to be
complete, but checking the template args against the primary template is
immediate.
This result is cached so that later when the class is instantiated,
checking against the primary template is not repeated.
The 'MatchedPackOnParmToNonPackOnArg' flag is also produced upon
checking against the primary template, so it needs to be cached in the
specialziation as well.
This fixes a bug which has not been in any release, so there are no
release notes.
Fixes#125290
The WatchAddress API includes a flag to indicate if watchpoint should be
for read, modify or both. This API uses 2 booleans, but the 'modify'
flag was ignored and WatchAddress unconditionally watched write
(actually modify).
We now only watch for modify when the modify flag is true.
---
The included test fails prior to this patch and succeeds after. That is
previously specifying `False` for `modify` would still stop on _write_,
but after the patch correctly only stops on _read_
Xcode uses a pseudoterminal for the debugger console.
- The upside of this apporach is that it means that it can rely on
LLDB's IOHandlers for multiline and script input.
- The downside of this approach is that the command output is printed to
the PTY and you don't get a SBCommandReturnObject. Adrian added support
for inline diagnostics (#110901) and we'd like to access those from the
IDE.
This patch adds support for registering a callback in the command
interpreter that gives access to the `(SB)CommandReturnObject` right
before it will be printed. The callback implementation can choose
whether it likes to handle printing the result or defer to lldb. If the
callback indicated it handled the result, the command interpreter will
skip printing the result.
We considered a few other alternatives to solve this problem:
- The most obvious one is using `HandleCommand`, which returns a
`SBCommandReturnObject`. The problem with this approach is the multiline
input mentioned above. We would need a way to tell the IDE that it
should expect multiline input, which isn't known until LLDB starts
handling the command.
- To address the multiline issue,we considered exposing (some of the)
IOHandler machinery through the SB API. To solve this particular issue,
that would require reimplementing a ton of logic that already exists
today in the CommandInterpeter. Furthermore that seems like overkill
compared to the proposed solution.
rdar://141254310
As suggested in #125006. Depending on which PR lands first, I'll update
`TestCommandInterepterPrintCallback.py` to check that the
`CommandReturnObject` passed to the callback has the correct command.
I encountered a `qMemoryRegionInfo not supported` error when capturing a
Minidump. This was surprising, and I started looking around I found
@jasonmolenda's fix in #115963 and then realized I was not validated
anything from the custom ranges.
Generally speaking, process plugins (e.g. ProcessGDBRemote) should not
be aware of OS plugin threads. However, ProcessGDBRemote attempts to
check for the existence of OS threads when calculating stop info. When
OS threads are present, it sets the stop info directly on the OS plugin
thread and leaves the ThreadGDBRemote without a StopInfo.
This is problematic for a few reasons:
1. No other process plugins do this, as they shouldn't. They should set
the stop info for their own process threads, and let the abstractions
built on top propagate StopInfos.
2. This conflicts with the expectations of ThreadMemory, which checks
for the backing threads's info, and then attempts to propagate it (in
the future, it should probably ask the plugin itself too...). We see
this happening in the code below. The `if` condition will not trigger,
because `backing_stop_info_sp` will be null (remember, ProcessGDB remote
is ignoring its own threads), and then this method returns false.
```
bool ThreadMemory::CalculateStopInfo() {
...
lldb::StopInfoSP backing_stop_info_sp(
m_backing_thread_sp->GetPrivateStopInfo());
if (backing_stop_info_sp &&
backing_stop_info_sp->IsValidForOperatingSystemThread(*this)) {
backing_stop_info_sp->SetThread(shared_from_this());
```
```
Thread::GetPrivateStopInfo
...
if (!CalculateStopInfo())
SetStopInfo(StopInfoSP());
```
To solve this, we change ProcessGDB remote so that it does the
principled thing: it now only sets the stop info of its own threads.
This change by itself breaks the tests TestPythonOSPlugin.py and
TestOSPluginStepping.py and probably explains why ProcessGDB had
originally "violated" this isolation of layers.
To make this work, BreakpointSites must be aware of BackingThreads when
answering the question: "Is this breakpoint valid for this thread?".
Why? Breakpoints are created on top of the OS threads (that's what the
user sees), but breakpoints are hit by process threads. In the presence
of OS threads, a TID-specific breakpoint is valid for a process thread
if it is backing an OS thread with that TID.
LLDB: correct event when removing all watchpoints
Previously we incorrectly checked for a "breakpoint changed" event
listener removing all watchpoints (e.g. via
SBTarget::DeleteAllWatchpoints()), although we would emit a "watchpoint
changed" event if there were a listener for 'breakpoint changed'.
This meant that we might not emit a "watchpoint changed" event if there
was a listener for this event.
Correct it to check for the "watchpoint changed" event.
---
Updated regression tests which were also incorrectly peeking for the
wrong event type. The 'remove' action actually triggers 2 events which
the test didn't allow, so I updated it to allow specifically what was
requested.
The test fails (expectedly) at the line following "DeleteAllWatchpoints"
prior to this patch, and passes after.
This patch fixes LLDB Windows build with MSVC compiler. MSVC deletes
the default constructor due to virtual inheritance rules. Explicitly
define the default constructor in NativeRegisterContextWindows to
ensure constructibility.
The `DWARFASTParserClang` reads enum values as `int64_t`s regardless of
the enumerators signedness. Then we pass it to
`AddEnumerationValueToEnumerationType` and only then do we create an
`APSInt` from it. However, there are other places where we read/pass
around the enum value as unsigned. This patch makes sure we consistently
use the same integer type for the enum value and let `APSInt` take care
of signedness. This shouldn't have any observable effect.
Use `llvm::Error` instead of `CommandReturnObject` for error reporting.
The command return objects were populated with errors but never
displayed. With this patch they're at least logged.
This reverts commit a774de807e.
This is the same changes as last time, plus:
* We load the binary into the target object so that on Windows, we can
resolve the locations of the functions.
* We now assert that each required breakpoint has at least 1 location,
to prevent an issue like that in the future.
* We are less strict about the unsupported error message, because it
prints "error: windows" on Windows instead of "error: gdb-remote".
I tried using `CompleteEnumType` to replace some duplicated code in
`DWARFASTParserClang::ParseEnum` but tests started failing.
`CompleteEnumType` parses/attaches the child enumerators using the
signedness it got from `CompilerType::IsIntegerType`. However, this
would only report the correct signedness for builtin integer types
(never for `clang::EnumType`s). We have a different API for that in
`CompilerType::IsIntegerOrEnumerationType` which could've been used
there instead. This patch calls `IsEnumerationIntegerTypeSigned` to
determine signedness because we always pass an enum type into
`CompleteEnumType` anyway.
Based on git history this has been the case for a long time, but
possibly never caused issues because `ParseEnum` was completing the
definition manually instead of through `CompleteEnumType`.
I couldn't find a good way to test `CompleteEnumType` on its own because
it expects an enum type to be passed to it, which only gets created in
`ParseEnum` (at which point we already call `CompleteEnumType`). The
only other place we call `CompleteEnumType` at is in
[`CompleteTypeFromDWARF`](466217eb03/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (L2260-L2262)).
Though I think we don't actually ever end up calling into that codepath
because we eagerly complete enum definitions. Maybe we can remove that
call to `CompleteEnumType` in a follow-up.
This PR adds support for hardware watchpoints in LLDB for AArch64
Windows targets.
Windows does not provide an API to query the number of available
hardware watchpoints supported by underlying hardware platform.
Therefore, current implementation supports only a single hardware
watchpoint, which has been verified on Windows 11 using Microsoft
SQ2 and Snapdragon Elite X hardware.
LLDB test suite ninja check-lldb still fails watchpoint-related tests.
However, tests that do not require more than a single watchpoint
pass successfully when run individually.
The original code resulted in a misfire in the symtab vs. debug info
deduplication code, which caused us to return the same function twice
when searching via a regex (for functions whose entry point is also not
the lowest address).