112 Commits

Author SHA1 Message Date
Jonas Devlieghere
c4ea6cc3f7
[lldb] Remove call_once wrappers around PluginManager::RegisterPlugin (#184273)
Remove call_once wrappers around PluginManager::RegisterPlugin. Plugins
can be registered and unregistered in Initialize and Terminate
respectively. In its current state, after having called Terminate, a
plugin can never be re-initialized.
2026-03-03 13:17:21 -08:00
Charles Zablit
796a1ea79f
[lldb][windows] fix a race condition when closing the ConPTY (#182302)
This patch fixes a race condition when closing the ConPTY of a process
on Windows.

The read operation in `ConnectionGenericFile::Read` is asynchronous
because the ConPTY does not work with synchronous reads. However, this
is prone to a race condition if the ConPTY is closed between the
`ReadFile` and the `WaitForMultipleObjects`. This eventually leads to
the data being truncated, i.e some of the STDOUT is missing.

The fix is to introduce a mutex which prevents the ConPTY from closing
while a Read loop is in progress.

At the end of the pipe, `WaitForMultipleObjects` hangs until it receives
a `ERROR_BROKEN_PIPE` event, which is signaled when closing the ConPTY.
It's important to close the Read thread before closing the ConPTY,
otherwise the thread deadlocks waiting for the `ERROR_BROKEN_PIPE` which
is never sent because the ConPTY is waiting for the thread to exit
before closing.

All of this logic is encapsulated in the `ConnectionConPTY` class which
is a subclass of `ConnectionGenericFile`. `ConnectionConPTY` only
supports reading from the ConPTY. To write to it,
`IOHandlerProcessSTDIOWindows` should be used instead.

This patch depends on:
- https://github.com/llvm/llvm-project/pull/182536

This patch replaces https://github.com/llvm/llvm-project/pull/182109.

---------

Co-authored-by: Nerixyz <nero.9@hotmail.de>
2026-02-23 17:21:06 +00:00
Charles Zablit
6a365b004d
[lldb-dap][windows] fix lldb-dap's self.get_stdout() method (#181813)
`DAPTestCaseBase.get_stdout()` was originally not supported on Windows
due to the lack of ConPTY support.
https://github.com/llvm/llvm-project/pull/168729 fixed that by
implenenting the ConPTY support. It was partly reverted in
https://github.com/llvm/llvm-project/pull/177610 due to hard to
reproduce test failures.

The tests are now fixed (see the 2 patches below) and removing the check
for `GetFlags().Test(lldb::eLaunchFlagLaunchInTTY);` is the last step to
re-enabling ConPTY support.

This patch requires:
- https://github.com/llvm/llvm-project/pull/181811
- https://github.com/llvm/llvm-project/pull/181809

Fixes https://github.com/llvm/llvm-project/issues/137599.

rdar://168932366
2026-02-18 17:05:29 +00:00
Charles Zablit
71f49eb026
[lldb][windows] release the ConPTY instead of copying its reference (#181811)
When running multiple targets in lldb, the `ProcessLaunchInfo` instance
gets re-used. This is a problem for the ConPTY instance which is owned
by `launch_info` because, when creating a second target, we close and
reopen the `m_pty` of the first target.

This patch replaces the `GetPTYSP` method with `ReleasePTY`, which moves
the `std::shared_ptr` out of `launch_info` instead of creating a new
`std::shared_ptr`. The `m_pty` instance is moved into the target's
process. This way, each target's `Process` instance owns its PTY
instance and is responsible for closing it.

---------

Co-authored-by: Adrian Prantl <adrian.prantl@gmail.com>
2026-02-17 22:10:27 +00:00
Charles Zablit
3a658906ef
[lldb][windows] add STDIN and STDOUT forwarding support (#180561) 2026-02-12 16:14:41 +01:00
Charles Zablit
168ccaebf0
Revert "[lldb][windows] add STDIN and STDOUT forwarding support (#175812)" (#177610) 2026-01-23 16:40:05 +00:00
Charles Zablit
4b7cf46f6b
[lldb][windows] add STDIN and STDOUT forwarding support (#175812) 2026-01-23 13:37:21 +01:00
Nerixyz
783fbdc54e
[LLDB][Windows] Store PTY in ProcessWindows (#175837)
I noticed that LLDB takes longer to stop than it should. Running a tiny
program like `int main() { return 0; }` in LLDB with `lldb test.exe -o r
-o q` takes about five seconds.

This is caused by the `WaitForMultipleObjects` in
[`ConnectionGenericFile::Read`](25976e8360/lldb/source/Host/windows/ConnectionGenericFileWindows.cpp (L191-L192))
timing out (it has a timeout of 5s).

It times out, because we never close the PTY created in
[`ProcessLaunchInfo::SetUpPtyRedirection`](25976e8360/lldb/source/Host/common/ProcessLaunchInfo.cpp (L213)).
When we call `target->GetProcessLaunchInfo().GetPTY().Close()` in
`ProcessWindows::OnExitProcess`, we don't access the PTY we created when
setting up the redirection - we're closing a default constructed one.
This is because the target's `m_launch_info` isn't necessarily the
`launch_info` we get in
[`Target::FinalizeFileActions`](4a8a0593bd/lldb/source/Target/Target.cpp (L3850))
when calling `SetUpPtyRedirection`.

With this PR, we store the PTY that a process was launched with inside
`ProcessWindows`, so we can later close it.

The wait of five seconds and a timed out `WaitForMultipleObjects` sounds
similar to https://github.com/llvm/llvm-project/pull/159308, but it's a
different call to `WaitForMultipleObjects` here. Still, I wonder if we
could do something to detect this earlier. Maybe some warning message or
debug-only assert if these waits time out?
2026-01-16 10:07:11 +01:00
Charles Zablit
7fe5953a44
[lldb][windows] add Windows Virtual Console support (#168729) 2025-12-18 10:29:38 +00:00
Charles Zablit
fc1e91112b
[lldb] ensure comment conforms to LLVM guidelines (#170533)
This patch is a follow up to
https://github.com/llvm/llvm-project/pull/170471.
2025-12-03 20:14:05 +00:00
Charles Zablit
8b94997a47
[lldb][windows] fix invalid corefile error message (#170471) 2025-12-03 12:53:17 +00:00
nerix
a868f28c6e
[LLDB][ProcessWindows] Set exit status on instance rather than going through all targets (#159308)
When quitting LLDB on Windows while a process was still running, LLDB
would take unusually long to exit. This was due to a temporary deadlock:

The main thread was destroying the processes. In doing so, it iterated
over the target list:

88c64f76ed/lldb/source/Core/Debugger.cpp (L1095-L1098)

This locks the list for the whole iteration. Finalizing the process
would eventually lead to `DebuggerThread::StopDebugging`, which
terminates the process and waits for it to exit:

88c64f76ed/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp (L196)
The debugger loop (on a separate thread) would see that the process
exited and call
[`ProcessWindows::OnExitProcess`](88c64f76ed/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp (L656-L673)).
This calls the static function
[`Process::SetProcessExitStatus`](0a7a7d56fc/lldb/source/Target/Process.cpp (L1098-L1126)).
This tries to find the process by its ID from the debugger's target
list. Doing so requires locking the list, so the debugger thread would
then be stuck on

0a7a7d56fc/lldb/source/Target/TargetList.cpp (L403)

After 5s, the main thread would give up waiting. So every exit where the
process was still running would be delayed by about 5s.

Since `ProcessWindows` would find itself when calling
`SetProcessExitStatus`, we can call `SetExitStatus` directly.

This can also make some tests run faster. For example, the DIA PDB tests
previously took 15s to run on my PC (24 jobs) and now take 5s. For all
shell tests, the difference isn't that big (only about 3s), because most
don't run into this and the tests run in parallel.
2025-09-18 11:27:25 +02:00
Akash Agrawal
e4ed71818e
[LLDB] [NFC] - Remove duplicate #include headers from the files of lldb dir & few other files (#141478)
A few files of lldb dir & few other files had duplicate headers
included. This patch removes those redundancies.

---------

Co-authored-by: Akash Agrawal <akashag@qti.qualcomm.com>
2025-05-29 23:13:30 -07:00
David Spickett
65b0d21eb4 [lldb] Remove "error:" prefix from reverse execute error messages
Errors will get "error:" prefixes automatically so this is not needed.
2025-04-29 14:01:01 +00:00
David Spickett
332e181766
[lldb] Fix error that lead Windows to think it could reverse execute (#137351)
The new test added in https://github.com/llvm/llvm-project/pull/132783
was failing on Windows because it created a new error to say it did not
support the feature, but then returned the existing, default constructed
error. Which was a success value.

This also changes the GDBRemote error message to the same phrasing used
in all the other places so we don't have to special case any platform.
2025-04-25 18:04:08 +01:00
Pavel Labath
1b237198dc
Reapply "[lldb] Implement basic support for reverse-continue (#125242)" (again) (#128156)
This reverts commit
87b7f63a11,
reapplying

7e66cf74fb
with a small (and probably temporary)
change to generate more debug info to help with diagnosing buildbot
issues.
2025-03-17 16:06:25 +01:00
Jason Molenda
b666ac3b63
[lldb] Change lldb's breakpoint handling behavior, reland (#126988)
lldb today has two rules: When a thread stops at a BreakpointSite, we
set the thread's StopReason to be "breakpoint hit" (regardless if we've
actually hit the breakpoint, or if we've merely stopped *at* the
breakpoint instruction/point and haven't tripped it yet). And second,
when resuming a process, any thread sitting at a BreakpointSite is
silently stepped over the BreakpointSite -- because we've already
flagged the breakpoint hit when we stopped there originally.

In this patch, I change lldb to only set a thread's stop reason to
breakpoint-hit when we've actually executed the instruction/triggered
the breakpoint. When we resume, we only silently step past a
BreakpointSite that we've registered as hit. We preserve this state
across inferior function calls that the user may do while stopped, etc.

Also, when a user adds a new breakpoint at $pc while stopped, or changes
$pc to be the address of a BreakpointSite, we will silently step past
that breakpoint when the process resumes. This is purely a UX call, I
don't think there's any person who wants to set a breakpoint at $pc and
then hit it immediately on resuming.

One non-intuitive UX from this change, butt is necessary: If you're
stopped at a BreakpointSite that has not yet executed, you `stepi`, you
will hit the breakpoint and the pc will not yet advance. This thread has
not completed its stepi, and the ThreadPlanStepInstruction is still on
the stack. If you then `continue` the thread, lldb will now stop and
say, "instruction step completed", one instruction past the
BreakpointSite. You can continue a second time to resume execution.

The bugs driving this change are all from lldb dropping the real stop
reason for a thread and setting it to breakpoint-hit when that was not
the case. Jim hit one where we have an aarch64 watchpoint that triggers
one instruction before a BreakpointSite. On this arch we are notified of
the watchpoint hit after the instruction has been unrolled -- we disable
the watchpoint, instruction step, re-enable the watchpoint and collect
the new value. But now we're on a BreakpointSite so the watchpoint-hit
stop reason is lost.

Another was reported by ZequanWu in
https://discourse.llvm.org/t/lldb-unable-to-break-at-start/78282 we
attach to/launch a process with the pc at a BreakpointSite and
misbehave. Caroline Tice mentioned it is also a problem they've had with
putting a breakpoint on _dl_debug_state.

The change to each Process plugin that does execution control is that

1. If we've stopped at a BreakpointSite that has not been executed yet,
we will call Thread::SetThreadStoppedAtUnexecutedBP(pc) to record that.
When the thread resumes, if the pc is still at the same site, we will
continue, hit the breakpoint, and stop again.

2. When we've actually hit a breakpoint (enabled for this thread or
not), the Process plugin should call
Thread::SetThreadHitBreakpointSite(). When we go to resume the thread,
we will push a step-over-breakpoint ThreadPlan before resuming.

The biggest set of changes is to StopInfoMachException where we
translate a Mach Exception into a stop reason. The Mach exception codes
differ in a few places depending on the target (unambiguously), and I
didn't want to duplicate the new code for each target so I've tested
what mach exceptions we get for each action on each target, and
reorganized StopInfoMachException::CreateStopReasonWithMachException to
document these possible values, and handle them without specializing
based on the target arch.

I first landed this patch in July 2024 via
https://github.com/llvm/llvm-project/pull/96260

but the CI bots and wider testing found a number of test case failures
that needed to be updated, I reverted it. I've fixed all of those issues
in separate PRs and this change should run cleanly on all the CI bots
now.

rdar://123942164
2025-02-13 11:30:10 -08:00
Adrian Prantl
87b7f63a11 Revert "Reland "[lldb] Implement basic support for reverse-continue" (#125242)"
This reverts commit 7e66cf74fb4e6a103f923e34700a7b6f20ac2a9b.

Breaking green dragon:

https://green.lab.llvm.org/job/llvm.org/view/LLDB/job/as-lldb-cmake/19569/testReport/junit/lldb-api/functionalities_reverse-execution/TestReverseContinueWatchpoints_py/
2025-01-31 13:11:20 -08:00
David Spickett
7e66cf74fb
Reland "[lldb] Implement basic support for reverse-continue" (#125242)
This reverts commit a774de807e56c1147d4630bfec3110c11d41776e.

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".
2025-01-31 15:56:33 +00:00
David Spickett
a774de807e
Revert "Reland "[lldb] Implement basic support for reverse-continue" (#123906)"" (#125091)
Reverts llvm/llvm-project#123945

Has failed on the Windows on Arm buildbot:
https://lab.llvm.org/buildbot/#/builders/141/builds/5865
```
********************
Unresolved Tests (2):
  lldb-api :: functionalities/reverse-execution/TestReverseContinueBreakpoints.py
  lldb-api :: functionalities/reverse-execution/TestReverseContinueWatchpoints.py
********************
Failed Tests (1):
  lldb-api :: functionalities/reverse-execution/TestReverseContinueNotSupported.py
```
Reverting while I reproduce locally.
2025-01-30 16:45:36 +00:00
David Spickett
0caba6c8dc
Reland "[lldb] Implement basic support for reverse-continue" (#123906)" (#123945)
This reverts commit 22561cfb443267905d4190f0e2a738e6b412457f and fixes
b7b9ccf44988edf49886743ae5c3cf4184db211f (#112079).

The problem is that x86_64 and Arm 32-bit have memory regions above the
stack that are readable but not writeable. First Arm:
```
(lldb) memory region --all
<...>
[0x00000000fffcf000-0x00000000ffff0000) rw- [stack]
[0x00000000ffff0000-0x00000000ffff1000) r-x [vectors]
[0x00000000ffff1000-0xffffffffffffffff) ---
```
Then x86_64:
```
$ cat /proc/self/maps
<...>
7ffdcd148000-7ffdcd16a000 rw-p 00000000 00:00 0                          [stack]
7ffdcd193000-7ffdcd196000 r--p 00000000 00:00 0                          [vvar]
7ffdcd196000-7ffdcd197000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  [vsyscall]
```
Compare this to AArch64 where the test did pass:
```
$ cat /proc/self/maps
<...>
ffffb87dc000-ffffb87dd000 r--p 00000000 00:00 0                          [vvar]
ffffb87dd000-ffffb87de000 r-xp 00000000 00:00 0                          [vdso]
ffffb87de000-ffffb87e0000 r--p 0002a000 00:3c 76927217                   /usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1
ffffb87e0000-ffffb87e2000 rw-p 0002c000 00:3c 76927217                   /usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1
fffff4216000-fffff4237000 rw-p 00000000 00:00 0                          [stack]
```
To solve this, look up the memory region of the stack pointer (using
https://lldb.llvm.org/resources/lldbgdbremote.html#qmemoryregioninfo-addr)
and constrain the read to within that region. Since we know the stack is
all readable and writeable.

I have also added skipIfRemote to the tests, since getting them working
in that context is too complex to be worth it.

Memory write failures now display the range they tried to write, and
register write errors will show the name of the register where possible.

The patch also includes a workaround for a an issue where the test code
could mistake an `x` response that happens to begin with an `O` for an
output packet (stdout). This workaround will not be necessary one we
start using the [new
implementation](https://discourse.llvm.org/t/rfc-fixing-incompatibilties-of-the-x-packet-w-r-t-gdb/84288)
of the `x` packet.

---------

Co-authored-by: Pavel Labath <pavel@labath.sk>
2025-01-30 14:03:01 +00:00
Pavel Labath
22561cfb44
Revert "[lldb] Implement basic support for reverse-continue" (#123906)
Reverts llvm/llvm-project#112079 due to failures on the arm bot.
2025-01-22 09:43:11 +01:00
Robert O'Callahan
b7b9ccf449
[lldb] Implement basic support for reverse-continue (#112079)
This commit adds support for a
`SBProcess::ContinueInDirection()` API. A user-accessible command for
this will follow in a later commit.

This feature depends on a gdbserver implementation (e.g. `rr`) providing
support for the `bc` and `bs` packets. `lldb-server` does not support
those packets, and there is no plan to change that. For testing
purposes, this commit adds a Python implementation of *very limited*
record-and-reverse-execute functionality, implemented as a proxy between
lldb and lldb-server in `lldbreverse.py`. This should not (and in
practice cannot) be used for anything except testing.

The tests here are quite minimal but we test that simple breakpoints and
watchpoints work as expected during reverse execution, and that
conditional breakpoints and watchpoints work when the condition calls a
function that must be executed in the forward direction.
2025-01-22 08:37:17 +01:00
anatawa12
5bbe63ec91
fix: Target Process may crash or freezes on detaching process on windows (#115712)
Fixes #67825 Fixes #89077

Fixes
[RIDER-99436](https://youtrack.jetbrains.com/issue/RIDER-99436/Unity-Editor-will-be-crashed-when-detaching-LLDB-debugger-in-Rider),
which is upstream issue of #67825.

This PR changes the timing of calling `DebugActiveProcessStop` to after
calling `ContinueDebugEvent` for last debugger exception.

I confirmed the crashing behavior is because we call
`DebugActiveProcessStop` before `ContinueDebugEvent` for last debugger
exception with https://github.com/anatawa12/debug-api-test.
2024-11-15 10:52:36 +01:00
Jason Molenda
3bef742559 Revert "[lldb] Implement basic support for reverse-continue (#99736)"
Reverting this again; I added a commit which added @skipIfDarwin
markers to the TestReverseContinueBreakpoints.py and
TestReverseContinueNotSupported.py API tests, which use lldb-server
in gdbserver mode which does not work on Darwin.  But the aarch64 ubuntu
bot reported a failure on TestReverseContinueBreakpoints.py,
https://lab.llvm.org/buildbot/#/builders/59/builds/6397

  File "/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/functionalities/reverse-execution/TestReverseContinueBreakpoints.py", line 63, in test_reverse_continue_skip_breakpoint
    self.reverse_continue_skip_breakpoint_internal(async_mode=False)
  File "/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/functionalities/reverse-execution/TestReverseContinueBreakpoints.py", line 81, in reverse_continue_skip_breakpoint_internal
    self.expect(
  File "/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 2372, in expect
    self.runCmd(
  File "/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 1002, in runCmd
    self.assertTrue(self.res.Succeeded(), msg + output)
AssertionError: False is not true : Process should be stopped due to history boundary
Error output:
error: Process must be launched.

This reverts commit 4f297566b3150097de26c6a23a987d2bd5fc19c5.
2024-10-10 16:24:38 -07:00
Robert O'Callahan
4f297566b3 [lldb] Implement basic support for reverse-continue (#99736)
This commit only adds support for the
`SBProcess::ReverseContinue()` API. A user-accessible command for this
will follow in a later commit.

This feature depends on a gdbserver implementation (e.g. `rr`) providing
support for the `bc` and `bs` packets. `lldb-server` does not support
those packets, and there is no plan to change that. So, for testing
purposes, `lldbreverse.py` wraps `lldb-server` with a Python
implementation of *very limited* record-and-replay functionality for use
by *tests only*.

The majority of this PR is test infrastructure (about 700 of the 950
lines added).
2024-10-10 16:08:19 -07:00
Augusto Noronha
2ff4c25b7e Revert "[lldb] Implement basic support for reverse-continue (#99736)"
This reverts commit d5e1de6da96c1ab3b8cae68447e8ed3696a7006e.
2024-10-10 15:05:58 -07:00
Robert O'Callahan
d5e1de6da9
[lldb] Implement basic support for reverse-continue (#99736)
This commit only adds support for the
`SBProcess::ReverseContinue()` API. A user-accessible command for this
will follow in a later commit.

This feature depends on a gdbserver implementation (e.g. `rr`) providing
support for the `bc` and `bs` packets. `lldb-server` does not support
those packets, and there is no plan to change that. So, for testing
purposes, `lldbreverse.py` wraps `lldb-server` with a Python
implementation of *very limited* record-and-replay functionality for use
by *tests only*.

The majority of this PR is test infrastructure (about 700 of the 950
lines added).
2024-10-10 13:01:47 -07:00
Youngsuk Kim
d7796855b8
[lldb] Nits on uses of llvm::raw_string_ostream (NFC) (#108745)
As specified in the docs,
1) raw_string_ostream is always unbuffered and
2) the underlying buffer may be used directly

( 65b13610a5226b84889b923bae884ba395ad084d for further reference )

* Don't call raw_string_ostream::flush(), which is essentially a no-op.
* Avoid unneeded calls to raw_string_ostream::str(), to avoid excess
indirection.
2024-09-16 00:26:51 -04:00
Adrian Prantl
e0a93d3505 [lldb] Convert ProcessWindows.cpp to new Status API (NFC) 2024-09-05 16:12:17 -07:00
Adrian Prantl
0642cd768b
[lldb] Turn lldb_private::Status into a value type. (#106163)
This patch removes all of the Set.* methods from Status.

This cleanup is part of a series of patches that make it harder use the
anti-pattern of keeping a long-lives Status object around and updating
it while dropping any errors it contains on the floor.

This patch is largely NFC, the more interesting next steps this enables
is to:
1. remove Status.Clear()
2. assert that Status::operator=() never overwrites an error
3. remove Status::operator=()

Note that step (2) will bring 90% of the benefits for users, and step
(3) will dramatically clean up the error handling code in various
places. In the end my goal is to convert all APIs that are of the form

`    ResultTy DoFoo(Status& error)
`
to

`    llvm::Expected<ResultTy> DoFoo()
`
How to read this patch?

The interesting changes are in Status.h and Status.cpp, all other
changes are mostly

` perl -pi -e 's/\.SetErrorString/ = Status::FromErrorString/g' $(git
grep -l SetErrorString lldb/source)
`
plus the occasional manual cleanup.
2024-08-27 10:59:31 -07:00
Jason Molenda
52c08d7ffd Revert "[lldb] Change lldb's breakpoint handling behavior (#96260)"
This reverts commit 05f0e86cc895181b3d2210458c78938f83353002.

The debuginfo dexter tests are failing, probably because the way
stepping over breakpoints has changed with my patches.  And there
are two API tests fails on the ubuntu-arm (32-bit) bot. I'll need
to investigate both of these, neither has an obvious failure reason.
2024-07-19 18:43:53 -07:00
Jason Molenda
05f0e86cc8
[lldb] Change lldb's breakpoint handling behavior (#96260)
lldb today has two rules: When a thread stops at a BreakpointSite, we
set the thread's StopReason to be "breakpoint hit" (regardless if we've
actually hit the breakpoint, or if we've merely stopped *at* the
breakpoint instruction/point and haven't tripped it yet). And second,
when resuming a process, any thread sitting at a BreakpointSite is
silently stepped over the BreakpointSite -- because we've already
flagged the breakpoint hit when we stopped there originally.

In this patch, I change lldb to only set a thread's stop reason to
breakpoint-hit when we've actually executed the instruction/triggered
the breakpoint. When we resume, we only silently step past a
BreakpointSite that we've registered as hit. We preserve this state
across inferior function calls that the user may do while stopped, etc.

Also, when a user adds a new breakpoint at $pc while stopped, or changes
$pc to be the address of a BreakpointSite, we will silently step past
that breakpoint when the process resumes. This is purely a UX call, I
don't think there's any person who wants to set a breakpoint at $pc and
then hit it immediately on resuming.

One non-intuitive UX from this change, but I'm convinced it is
necessary: If you're stopped at a BreakpointSite that has not yet
executed, you `stepi`, you will hit the breakpoint and the pc will not
yet advance. This thread has not completed its stepi, and the thread
plan is still on the stack. If you then `continue` the thread, lldb will
now stop and say, "instruction step completed", one instruction past the
BreakpointSite. You can continue a second time to resume execution. I
discussed this with Jim, and trying to paper over this behavior will
lead to more complicated scenarios behaving non-intuitively. And mostly
it's the testsuite that was trying to instruction step past a breakpoint
and getting thrown off -- and I changed those tests to expect the new
behavior.

The bugs driving this change are all from lldb dropping the real stop
reason for a thread and setting it to breakpoint-hit when that was not
the case. Jim hit one where we have an aarch64 watchpoint that triggers
one instruction before a BreakpointSite. On this arch we are notified of
the watchpoint hit after the instruction has been unrolled -- we disable
the watchpoint, instruction step, re-enable the watchpoint and collect
the new value. But now we're on a BreakpointSite so the watchpoint-hit
stop reason is lost.

Another was reported by ZequanWu in
https://discourse.llvm.org/t/lldb-unable-to-break-at-start/78282 we
attach to/launch a process with the pc at a BreakpointSite and
misbehave. Caroline Tice mentioned it is also a problem they've had with
putting a breakpoint on _dl_debug_state.

The change to each Process plugin that does execution control is that

1. If we've stopped at a BreakpointSite that has not been executed yet,
we will call Thread::SetThreadStoppedAtUnexecutedBP(pc) to record
that.  When the thread resumes, if the pc is still at the same site, we
will continue, hit the breakpoint, and stop again.

2. When we've actually hit a breakpoint (enabled for this thread or not),
the Process plugin should call Thread::SetThreadHitBreakpointSite().
When we go to resume the thread, we will push a step-over-breakpoint
ThreadPlan before resuming.

The biggest set of changes is to StopInfoMachException where we
translate a Mach Exception into a stop reason. The Mach exception codes
differ in a few places depending on the target (unambiguously), and I
didn't want to duplicate the new code for each target so I've tested
what mach exceptions we get for each action on each target, and
reorganized StopInfoMachException::CreateStopReasonWithMachException to
document these possible values, and handle them without specializing
based on the target arch.

rdar://123942164
2024-07-19 17:26:13 -07:00
Aleksandr Korepanov
00ed887454
[LLDB][Windows] Fix watchpoints for Windows (#95446)
Hello!

Currently, watchpoints don't work on Windows (this can be reproduced
with the existing tests). This patch fixes the related issues so that
the tests and watchpoints start working.

Here is the list of tests that are fixed by this patch (on Windows,
checked in **release/18.x** branch):
- commands/watchpoints/hello_watchpoint/TestMyFirstWatchpoint.py
- commands/watchpoints/multiple_hits/TestMultipleHits.py
- commands/watchpoints/multiple_threads/TestWatchpointMultipleThreads.py
- commands/watchpoints/step_over_watchpoint/TestStepOverWatchpoint.py
- commands/watchpoints/unaligned-watchpoint/TestUnalignedWatchpoint.py
- commands/watchpoints/watchpoint_commands/TestWatchpointCommands.py
-
commands/watchpoints/watchpoint_commands/command/TestWatchpointCommandLLDB.py
-
commands/watchpoints/watchpoint_commands/command/TestWatchpointCommandPython.py
-
commands/watchpoints/watchpoint_commands/condition/TestWatchpointConditionCmd.py
- commands/watchpoints/watchpoint_count/TestWatchpointCount.py
- commands/watchpoints/watchpoint_disable/TestWatchpointDisable.py
- commands/watchpoints/watchpoint_size/TestWatchpointSizes.py
- python_api/watchpoint/TestSetWatchpoint.py
- python_api/watchpoint/TestWatchpointIgnoreCount.py
- python_api/watchpoint/TestWatchpointIter.py
- python_api/watchpoint/condition/TestWatchpointConditionAPI.py
- python_api/watchpoint/watchlocation/TestTargetWatchAddress.py

---------

Co-authored-by: Jason Molenda <jmolenda@apple.com>
2024-06-13 14:50:31 -07:00
Jason Molenda
c73a3f16f8 [lldb] [mostly NFC] Large WP foundation: WatchpointResources (#68845)
This patch is rearranging code a bit to add WatchpointResources to
Process. A WatchpointResource is meant to represent a hardware
watchpoint register in the inferior process. It has an address, a size,
a type, and a list of Watchpoints that are using this
WatchpointResource.

This current patch doesn't add any of the features of
WatchpointResources that make them interesting -- a user asking to watch
a 24 byte object could watch this with three 8 byte WatchpointResources.
Or a Watchpoint on 1 byte at 0x1002 and a second watchpoint on 1 byte at
0x1003, these must both be served by a single WatchpointResource on that
doubleword at 0x1000 on a 64-bit target, if two hardware watchpoint
registers were used to track these separately, one of them may not be
hit. Or if you have one Watchpoint on a variable with a condition set,
and another Watchpoint on that same variable with a command defined or
different condition, or ignorecount, both of those Watchpoints need to
evaluate their criteria/commands when their WatchpointResource has been
hit.

There's a bit of code movement to rearrange things in the direction I'll
need for implementing this feature, so I want to start with reviewing &
landing this mostly NFC patch and we can focus on the algorithmic
choices about how WatchpointResources are shared and handled as they're
triggeed, separately.

This patch also stops printing "Watchpoint <n> hit: old value: <x>, new
vlaue: <y>" for Read watchpoints. I could make an argument for print
"Watchpoint <n> hit: current value <x>" but the current output doesn't
make any sense, and the user can print the value if they are
particularly interested. Read watchpoints are used primarily to
understand what code is reading a variable.

This patch adds more fallbacks for how to print the objects being
watched if we have types, instead of assuming they are all integral
values, so a struct will print its elements. As large watchpoints are
added, we'll be doing a lot more of those.

To track the WatchpointSP in the WatchpointResources, I changed the
internal API which took a WatchpointSP and devolved it to a Watchpoint*,
which meant touching several different Process files. I removed the
watchpoint code in ProcessKDP which only reported that watchpoints
aren't supported, the base class does that already.

I haven't yet changed how we receive a watchpoint to identify the
WatchpointResource responsible for the trigger, and identify all
Watchpoints that are using this Resource to evaluate their conditions
etc. This is the same work that a BreakpointSite needs to do when it has
been tiggered, where multiple Breakpoints may be at the same address.

There is not yet any printing of the Resources that a Watchpoint is
implemented in terms of ("watchpoint list", or
SBWatchpoint::GetDescription).

"watchpoint set var" and "watchpoint set expression" take a size
argument which was previously 1, 2, 4, or 8 (an enum). I've changed this
to an unsigned int. Most hardware implementations can only watch 1, 2,
4, 8 byte ranges, but with Resources we'll allow a user to ask for
different sized watchpoints and set them in hardware-expressble terms
soon.

I've annotated areas where I know there is work still needed with
LWP_TODO that I'll be working on once this is landed.

I've tested this on aarch64 macOS, aarch64 Linux, and Intel macOS.

https://discourse.llvm.org/t/rfc-large-watchpoint-support-in-lldb/72116
(cherry picked from commit fc6b72523f3d73b921690a713e97a433c96066c6)
2023-11-30 14:59:10 -08:00
David Spickett
b0af8a1ede Revert "[lldb] [mostly NFC] Large WP foundation: WatchpointResources (#68845)"
...and follow ups.

As it has caused test failures on Linux Arm and AArch64:
https://lab.llvm.org/buildbot/#/builders/96/builds/49126
https://lab.llvm.org/buildbot/#/builders/17/builds/45824

```
  lldb-shell :: Subprocess/clone-follow-child-wp.test
  lldb-shell :: Subprocess/fork-follow-child-wp.test
  lldb-shell :: Subprocess/vfork-follow-child-wp.test
```

This reverts commit a6c62bf1a4717accc852463b664cd1012237d334,
commit a0a1ff3ab40e347589b4e27d8fd350c600526735 and commit
fc6b72523f3d73b921690a713e97a433c96066c6.
2023-11-28 09:39:37 +00:00
Jason Molenda
fc6b72523f
[lldb] [mostly NFC] Large WP foundation: WatchpointResources (#68845)
This patch is rearranging code a bit to add WatchpointResources to
Process. A WatchpointResource is meant to represent a hardware
watchpoint register in the inferior process. It has an address, a size,
a type, and a list of Watchpoints that are using this
WatchpointResource.

This current patch doesn't add any of the features of
WatchpointResources that make them interesting -- a user asking to watch
a 24 byte object could watch this with three 8 byte WatchpointResources.
Or a Watchpoint on 1 byte at 0x1002 and a second watchpoint on 1 byte at
0x1003, these must both be served by a single WatchpointResource on that
doubleword at 0x1000 on a 64-bit target, if two hardware watchpoint
registers were used to track these separately, one of them may not be
hit. Or if you have one Watchpoint on a variable with a condition set,
and another Watchpoint on that same variable with a command defined or
different condition, or ignorecount, both of those Watchpoints need to
evaluate their criteria/commands when their WatchpointResource has been
hit.

There's a bit of code movement to rearrange things in the direction I'll
need for implementing this feature, so I want to start with reviewing &
landing this mostly NFC patch and we can focus on the algorithmic
choices about how WatchpointResources are shared and handled as they're
triggeed, separately.

This patch also stops printing "Watchpoint <n> hit: old value: <x>, new
vlaue: <y>" for Read watchpoints. I could make an argument for print
"Watchpoint <n> hit: current value <x>" but the current output doesn't
make any sense, and the user can print the value if they are
particularly interested. Read watchpoints are used primarily to
understand what code is reading a variable.

This patch adds more fallbacks for how to print the objects being
watched if we have types, instead of assuming they are all integral
values, so a struct will print its elements. As large watchpoints are
added, we'll be doing a lot more of those.

To track the WatchpointSP in the WatchpointResources, I changed the
internal API which took a WatchpointSP and devolved it to a Watchpoint*,
which meant touching several different Process files. I removed the
watchpoint code in ProcessKDP which only reported that watchpoints
aren't supported, the base class does that already.

I haven't yet changed how we receive a watchpoint to identify the
WatchpointResource responsible for the trigger, and identify all
Watchpoints that are using this Resource to evaluate their conditions
etc. This is the same work that a BreakpointSite needs to do when it has
been tiggered, where multiple Breakpoints may be at the same address.

There is not yet any printing of the Resources that a Watchpoint is
implemented in terms of ("watchpoint list", or
SBWatchpoint::GetDescription).

"watchpoint set var" and "watchpoint set expression" take a size
argument which was previously 1, 2, 4, or 8 (an enum). I've changed this
to an unsigned int. Most hardware implementations can only watch 1, 2,
4, 8 byte ranges, but with Resources we'll allow a user to ask for
different sized watchpoints and set them in hardware-expressble terms
soon.

I've annotated areas where I know there is work still needed with
LWP_TODO that I'll be working on once this is landed.

I've tested this on aarch64 macOS, aarch64 Linux, and Intel macOS.

https://discourse.llvm.org/t/rfc-large-watchpoint-support-in-lldb/72116
2023-11-27 13:28:59 -08:00
Jason Molenda
a3fe9221ab
Remove hardware index from watchpoints and breakpoints (#72012)
The Watchpoint and Breakpoint objects try to track the hardware index
that was used for them, if they are hardware wp/bp's. The majority of
our debugging goes over the gdb remote serial protocol, and when we set
the watchpoint/breakpoint, there is no (standard) way for the remote
stub to communicate to lldb which hardware index was used. We have an
lldb-extension packet to query the total number of watchpoint registers.

When a watchpoint is hit, there is an lldb extension to the stop reply
packet (documented in lldb-gdb-remote.txt) to describe the watchpoint
including its actual hardware index,

<addr within wp range> <wp hw index> <actual accessed address>

(the third field is specifically needed for MIPS). At this point, if the
stub reported these three fields (the stub is only required to provide
the first), we can know the actual hardware index for this watchpoint.

Breakpoints are worse; there's never any way for us to be notified about
which hardware index was used. Breakpoints got this as a side effect of
inherting from StoppointSite with Watchpoints.

We expose the watchpoint hardware index through "watchpoint list -v" and
through SBWatchpoint::GetHardwareIndex.

With my large watchpoint support, there is no *single* hardware index
that may be used for a watchpoint, it may need multiple resources. Also
I don't see what a user is supposed to do with this information, or an
IDE. Knowing the total number of watchpoint registers on the target, and
knowing how many Watchpoint Resources are currently in use, is helpful.
Knowing how many Watchpoint Resources
a single user-specified watchpoint needed to be implemented is useful.
But knowing which registers were used is an implementation detail and
not available until we hit the watchpoint when using gdb remote serial
protocol.

So given all that, I'm removing watchpoint hardware index numbers. I'm
changing the SB API to always return -1.
2023-11-15 13:32:42 -08:00
Jason Molenda
eaeb8ddd4a [LLDB] add arch-specific watchpoint behavior defaults to lldb
lldb was originally designed to get the watchpoint exception behavior
from the gdb remote serial protocol stub -- exceptions are either
received before the instruction executes, or after the instruction
has executed.  This behavior was reported via two lldb extensions
to gdb RSP, so generic remote stubs like gdbserver or a JTAG stub,
would not tell lldb which behavior was correct, and it would default
to "exceptions are received after the instruction has executed".
Two architectures hard coded their correct "exceptions before
instruction" behavior, to work around this issue.

Most architectures have a fixed behavior of watchpoint exceptions,
and we can center that information in lldb.  We can allow a remote
stub to override the default behavior via our packet extensions
if it's needed on a specific target.

This patch also separates the fetching of the number of watchpoints
from whether exceptions are before/after the insn.  Currently if
lldb couldn't fetch the number of watchpoints (not really needed), it
also wouldn't get when exceptions are received, and watchpoint
handling would fail.  lldb doesn't actually use the number of
watchpoints for anything beyond printing it to the user.

Differential Revision: https://reviews.llvm.org/D143215
rdar://101426626
2023-02-14 11:35:39 -08:00
Alvin Wong
fe17e02695 [lldb][Windows] Always call SetExecutableModule on debugger connected
In `ProcessWindows::OnDebuggerConnected` (triggered from
`CREATE_PROCESS_DEBUG_EVENT`), we should always call
`Target::SetExecutableModule` regardless of whether LLDB has already
preloaded the executable modules. `SetExecutableModule` has the side
effect of clearing the module list of the Target, which help make sure
that module #0 is the executable module and the rest of the modules are
listed according to the DLL load order in the process (technically this
has no real consequences but it seems to make more sense anyway.) It
also fixes an issue where the modules preloaded by LLDB will be
duplicated when the debuggee process actually loads the DLL.

Reviewed By: labath

Differential Revision: https://reviews.llvm.org/D134636
2022-09-30 13:51:56 +03:00
Fangrui Song
59d2495fe2 [lldb] LLVM_FALLTHROUGH => [[fallthrough]]. NFC 2022-08-08 11:31:49 -07:00
Jonas Devlieghere
a6eeffa106
[lldb] Include lldb/Host/HostInfo.h in ProcessWindows.cpp 2022-03-11 12:34:41 -08:00
Jonas Devlieghere
68099b1d5c
[lldb] Add a getter for the process' system architecture
This patch adds a getter for the process' system architecture. I went
with Process::GetSystemArchitecture to match
Platform::GetSystemArchitecture.

Differential revision: https://reviews.llvm.org/D121443
2022-03-11 10:58:04 -08:00
David Spickett
2937b28218 Reland "[lldb] Remove non address bits when looking up memory regions"
This reverts commit 0df522969a7a0128052bd79182c8d58e00556e2f.

Additional checks are added to fix the detection of the last memory region
in GetMemoryRegions or repeating the "memory region" command when the
target has non-address bits.

Normally you keep reading from address 0, looking up each region's end
address until you get LLDB_INVALID_ADDR as the region end address.
(0xffffffffffffffff)

This is what the remote will return once you go beyond the last mapped region:
[0x0000fffffffdf000-0x0001000000000000) rw- [stack]
[0x0001000000000000-0xffffffffffffffff) ---

Problem is that when we "fix" the lookup address, we remove some bits
from it. On an AArch64 system we have 48 bit virtual addresses, so when
we fix the end address of the [stack] region the result is 0.
So we loop back to the start.

[0x0000fffffffdf000-0x0001000000000000) rw- [stack]
[0x0000000000000000-0x0000000000400000) ---

To fix this I added an additional check for the last range.
If the end address of the region is different once you apply
FixDataAddress, we are at the last region.

Since the end of the last region will be the last valid mappable
address, plus 1. That 1 will be removed by the ABI plugin.

The only side effect is that on systems with non-address bits, you
won't get that last catch all unmapped region from the max virtual
address up to 0xf...f.

[0x0000fffff8000000-0x0000fffffffdf000) ---
[0x0000fffffffdf000-0x0001000000000000) rw- [stack]
<ends here>

Though in some way this is more correct because that region is not
just unmapped, it's not mappable at all.

No extra testing is needed because this is already covered by
TestMemoryRegion.py, I simply forgot to run it on system that had
both top byte ignore and pointer authentication.

This change has been tested on a qemu VM with top byte ignore,
memory tagging and pointer authentication enabled.

Reviewed By: omjavaid

Differential Revision: https://reviews.llvm.org/D115508
2022-02-10 10:42:49 +00:00
Pavel Labath
6730df4779 [lldb] Convert ProcessWindowsLog to the new API 2022-01-27 10:05:05 +01:00
David Spickett
0df522969a Revert "Reland "[lldb] Remove non address bits when looking up memory regions""
This reverts commit fac3f20de55769d028bd92220e74f22fa57dd4b2.

I found this has broken how we detect the last memory region in
GetMemoryRegions/"memory region" command.

When you're debugging an AArch64 system with pointer authentication,
the ABI plugin will remove the top bit from the end address of the last
user mapped area.

(lldb)
[0x0000fffffffdf000-0x0001000000000000) rw- [stack]

ABI plugin removes anything above the 48th bit (48 bit virtual addresses
by default on AArch64, leaving an address of 0.

(lldb)
[0x0000000000000000-0x0000000000400000) ---

You get back a mapping for 0 and get into an infinite loop.
2021-11-26 15:35:02 +00:00
David Spickett
fac3f20de5 Reland "[lldb] Remove non address bits when looking up memory regions"
This reverts commit 5fbcf677347e38718461496d9e9e184a7a30c3fb.

ProcessDebugger is used in ProcessWindows and NativeProcessWindows.
I thought I was simplifying things by renaming to DoGetMemoryRegionInfo
in ProcessDebugger but the Native process side expects "GetMemoryRegionInfo".

Follow the pattern that WriteMemory uses. So:
* ProcessWindows::DoGetMemoryRegioninfo calls ProcessDebugger::GetMemoryRegionInfo
* NativeProcessWindows::GetMemoryRegionInfo does the same
2021-11-03 13:56:51 +00:00
David Spickett
5fbcf67734 Revert "[lldb] Remove non address bits when looking up memory regions"
This reverts commit 6f5ce43b433706c3ae5c37022d6c0964b6bfadf8 due to
build failure on Windows.
2021-11-03 13:27:41 +00:00
David Spickett
6f5ce43b43 [lldb] Remove non address bits when looking up memory regions
On AArch64 we have various things using the non address bits
of pointers. This means when you lookup their containing region
you won't find it if you don't remove them.

This changes Process GetMemoryRegionInfo to a non virtual method
that uses the current ABI plugin to remove those bits. Then it
calls DoGetMemoryRegionInfo.

That function does the actual work and is virtual to be overriden
by Process implementations.

A test case is added that runs on AArch64 Linux using the top
byte ignore feature.

Reviewed By: omjavaid

Differential Revision: https://reviews.llvm.org/D102757
2021-11-03 11:10:42 +00:00
Pavel Labath
5f4980f004 [lldb] Remove ConstString from Process, ScriptInterpreter and StructuredData plugin names 2021-10-28 10:15:03 +02:00