<feed xmlns='http://www.w3.org/2005/Atom'>
<title>llvm-project.git/lldb/source/Target/Thread.cpp, branch main</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.
</subtitle>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/'/>
<entry>
<title>Revert "[lldb] Introduce ScriptedFrameProvider for real threads" (#167662)</title>
<updated>2025-11-12T10:13:43+00:00</updated>
<author>
<name>Michael Buch</name>
<email>michaelbuch12@gmail.com</email>
</author>
<published>2025-11-12T10:13:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=b7bc4a2103a77328f50f7e0b08ca073e34673755'/>
<id>b7bc4a2103a77328f50f7e0b08ca073e34673755</id>
<content type='text'>
The new test fails on x86 and arm64 public macOS bots:
```
09:27:59  ======================================================================
09:27:59  FAIL: test_append_frames (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that we can add frames after real stack.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 122, in test_append_frames
09:27:59      self.assertEqual(new_frame_count, original_frame_count + 1)
09:27:59  AssertionError: 5 != 6
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ======================================================================
09:27:59  FAIL: test_applies_to_thread (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that applies_to_thread filters which threads get the provider.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 218, in test_applies_to_thread
09:27:59      self.assertEqual(
09:27:59  AssertionError: 5 != 1 : Thread with ID 1 should have 1 synthetic frame
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ======================================================================
09:27:59  FAIL: test_prepend_frames (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that we can add frames before real stack.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 84, in test_prepend_frames
09:27:59      self.assertEqual(new_frame_count, original_frame_count + 2)
09:27:59  AssertionError: 5 != 7
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ======================================================================
09:27:59  FAIL: test_remove_frame_provider_by_id (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that RemoveScriptedFrameProvider removes a specific provider by ID.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 272, in test_remove_frame_provider_by_id
09:27:59      self.assertEqual(thread.GetNumFrames(), 3, "Should have 3 synthetic frames")
09:27:59  AssertionError: 5 != 3 : Should have 3 synthetic frames
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ======================================================================
09:27:59  FAIL: test_replace_all_frames (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that we can replace the entire stack.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 41, in test_replace_all_frames
09:27:59      self.assertEqual(thread.GetNumFrames(), 3, "Should have 3 synthetic frames")
09:27:59  AssertionError: 5 != 3 : Should have 3 synthetic frames
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ======================================================================
09:27:59  FAIL: test_scripted_frame_objects (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that provider can return ScriptedFrame objects.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 159, in test_scripted_frame_objects
09:27:59      self.assertEqual(frame0.GetFunctionName(), "custom_scripted_frame_0")
09:27:59  AssertionError: 'thread_func(int)' != 'custom_scripted_frame_0'
09:27:59  - thread_func(int)
09:27:59  + custom_scripted_frame_0
09:27:59  
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ----------------------------------------------------------------------
09:27:59  Ran 6 tests in 14.242s
09:27:59  
09:27:59  FAILED (failures=6)
```

Reverts llvm/llvm-project#161870</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The new test fails on x86 and arm64 public macOS bots:
```
09:27:59  ======================================================================
09:27:59  FAIL: test_append_frames (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that we can add frames after real stack.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 122, in test_append_frames
09:27:59      self.assertEqual(new_frame_count, original_frame_count + 1)
09:27:59  AssertionError: 5 != 6
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ======================================================================
09:27:59  FAIL: test_applies_to_thread (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that applies_to_thread filters which threads get the provider.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 218, in test_applies_to_thread
09:27:59      self.assertEqual(
09:27:59  AssertionError: 5 != 1 : Thread with ID 1 should have 1 synthetic frame
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ======================================================================
09:27:59  FAIL: test_prepend_frames (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that we can add frames before real stack.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 84, in test_prepend_frames
09:27:59      self.assertEqual(new_frame_count, original_frame_count + 2)
09:27:59  AssertionError: 5 != 7
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ======================================================================
09:27:59  FAIL: test_remove_frame_provider_by_id (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that RemoveScriptedFrameProvider removes a specific provider by ID.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 272, in test_remove_frame_provider_by_id
09:27:59      self.assertEqual(thread.GetNumFrames(), 3, "Should have 3 synthetic frames")
09:27:59  AssertionError: 5 != 3 : Should have 3 synthetic frames
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ======================================================================
09:27:59  FAIL: test_replace_all_frames (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that we can replace the entire stack.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 41, in test_replace_all_frames
09:27:59      self.assertEqual(thread.GetNumFrames(), 3, "Should have 3 synthetic frames")
09:27:59  AssertionError: 5 != 3 : Should have 3 synthetic frames
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ======================================================================
09:27:59  FAIL: test_scripted_frame_objects (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that provider can return ScriptedFrame objects.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 159, in test_scripted_frame_objects
09:27:59      self.assertEqual(frame0.GetFunctionName(), "custom_scripted_frame_0")
09:27:59  AssertionError: 'thread_func(int)' != 'custom_scripted_frame_0'
09:27:59  - thread_func(int)
09:27:59  + custom_scripted_frame_0
09:27:59  
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ----------------------------------------------------------------------
09:27:59  Ran 6 tests in 14.242s
09:27:59  
09:27:59  FAILED (failures=6)
```

Reverts llvm/llvm-project#161870</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Introduce ScriptedFrameProvider for real threads (#161870)</title>
<updated>2025-11-11T20:18:45+00:00</updated>
<author>
<name>Med Ismail Bennani</name>
<email>ismail@bennani.ma</email>
</author>
<published>2025-11-11T20:18:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=1e467e44851a9da96c16c0dcd16725f996e6abf7'/>
<id>1e467e44851a9da96c16c0dcd16725f996e6abf7</id>
<content type='text'>
This patch extends ScriptedFrame to work with real (non-scripted)
threads,
enabling frame providers to synthesize frames for native processes.

Previously, ScriptedFrame only worked within
ScriptedProcess/ScriptedThread
contexts. This patch decouples ScriptedFrame from ScriptedThread,
allowing
users to augment or replace stack frames in real debugging sessions for
use
cases like custom calling conventions, reconstructing corrupted frames
from
core files, or adding diagnostic frames.

Key changes:

- ScriptedFrame::Create() now accepts ThreadSP instead of requiring
ScriptedThread, extracting architecture from the target triple rather
than ScriptedProcess.arch

- Added SBTarget::RegisterScriptedFrameProvider() and
ClearScriptedFrameProvider() APIs, with Target storing a
SyntheticFrameProviderDescriptor template for new threads

- Added "target frame-provider register/clear" commands for CLI access

- Thread class gains LoadScriptedFrameProvider(),
ClearScriptedFrameProvider(),
and GetFrameProvider() methods for per-thread frame provider management

- New SyntheticStackFrameList overrides FetchFramesUpTo() to lazily
provide
frames from either the frame provider or the real stack

This enables practical use of the SyntheticFrameProvider infrastructure
in
real debugging workflows.

rdar://161834688

Signed-off-by: Med Ismail Bennani &lt;ismail@bennani.ma&gt;

Signed-off-by: Med Ismail Bennani &lt;ismail@bennani.ma&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This patch extends ScriptedFrame to work with real (non-scripted)
threads,
enabling frame providers to synthesize frames for native processes.

Previously, ScriptedFrame only worked within
ScriptedProcess/ScriptedThread
contexts. This patch decouples ScriptedFrame from ScriptedThread,
allowing
users to augment or replace stack frames in real debugging sessions for
use
cases like custom calling conventions, reconstructing corrupted frames
from
core files, or adding diagnostic frames.

Key changes:

- ScriptedFrame::Create() now accepts ThreadSP instead of requiring
ScriptedThread, extracting architecture from the target triple rather
than ScriptedProcess.arch

- Added SBTarget::RegisterScriptedFrameProvider() and
ClearScriptedFrameProvider() APIs, with Target storing a
SyntheticFrameProviderDescriptor template for new threads

- Added "target frame-provider register/clear" commands for CLI access

- Thread class gains LoadScriptedFrameProvider(),
ClearScriptedFrameProvider(),
and GetFrameProvider() methods for per-thread frame provider management

- New SyntheticStackFrameList overrides FetchFramesUpTo() to lazily
provide
frames from either the frame provider or the real stack

This enables practical use of the SyntheticFrameProvider infrastructure
in
real debugging workflows.

rdar://161834688

Signed-off-by: Med Ismail Bennani &lt;ismail@bennani.ma&gt;

Signed-off-by: Med Ismail Bennani &lt;ismail@bennani.ma&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Use StopInfoSP instead of StopInfo* (NFC)</title>
<updated>2025-07-18T21:29:20+00:00</updated>
<author>
<name>Jonas Devlieghere</name>
<email>jonas@devlieghere.com</email>
</author>
<published>2025-07-18T21:15:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=3641448e08961d8b8621fafa01167f96d948ee9e'/>
<id>3641448e08961d8b8621fafa01167f96d948ee9e</id>
<content type='text'>
Don't make assumptions about the lifetime of the underlying object and
use the shared_ptr to participate in reference counting and extend the
lifetime of the object to the end of the lexical scope.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Don't make assumptions about the lifetime of the underlying object and
use the shared_ptr to participate in reference counting and extend the
lifetime of the object to the end of the lexical scope.
</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Fix data race in statusline format handling (#142489)</title>
<updated>2025-06-04T02:12:30+00:00</updated>
<author>
<name>Jonas Devlieghere</name>
<email>jonas@devlieghere.com</email>
</author>
<published>2025-06-04T02:12:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=6760857bf3ad82a44c56d45a6a88a21b3fe521be'/>
<id>6760857bf3ad82a44c56d45a6a88a21b3fe521be</id>
<content type='text'>
This fixes a data race between the main thread and the default event
handler thread. The statusline format option value was protected by a
mutex, but it was returned as a pointer, allowing one thread to access
it while another was modifying it.

Avoid the data race by returning format values by value instead of by
pointer.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This fixes a data race between the main thread and the default event
handler thread. The statusline format option value was protected by a
mutex, but it was returned as a pointer, allowing one thread to access
it while another was modifying it.

Avoid the data race by returning format values by value instead of by
pointer.</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Create ThreadPlanStepOut ctor that never skips frames (#136163)</title>
<updated>2025-04-17T21:13:28+00:00</updated>
<author>
<name>Felipe de Azevedo Piovezan</name>
<email>fpiovezan@apple.com</email>
</author>
<published>2025-04-17T21:13:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=12becfff035a33141a0b2fb3ea5d5558738ce7eb'/>
<id>12becfff035a33141a0b2fb3ea5d5558738ce7eb</id>
<content type='text'>
The function QueueThreadPlanForStepOutNoShouldStop has the semantics of
"go this parent frame"; ThreadPlanStepOut needs to respect that, not
skipping over any frames it finds uninteresting. This commit creates a
constructor that respects such instruction.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The function QueueThreadPlanForStepOutNoShouldStop has the semantics of
"go this parent frame"; ThreadPlanStepOut needs to respect that, not
skipping over any frames it finds uninteresting. This commit creates a
constructor that respects such instruction.</pre>
</div>
</content>
</entry>
<entry>
<title>Reapply "[lldb] Implement basic support for reverse-continue (#125242)" (again) (#128156)</title>
<updated>2025-03-17T15:06:25+00:00</updated>
<author>
<name>Pavel Labath</name>
<email>pavel@labath.sk</email>
</author>
<published>2025-03-17T15:06:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=1b237198dc9d308c6d589e01637ec7496b48b3e0'/>
<id>1b237198dc9d308c6d589e01637ec7496b48b3e0</id>
<content type='text'>
This reverts commit
https://github.com/llvm/llvm-project/commit/87b7f63a117c340a6d9ca47959335fd7ef6c7ad2,
reapplying

https://github.com/llvm/llvm-project/commit/7e66cf74fb4e6a103f923e34700a7b6f20ac2a9b
with a small (and probably temporary)
change to generate more debug info to help with diagnosing buildbot
issues.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commit
https://github.com/llvm/llvm-project/commit/87b7f63a117c340a6d9ca47959335fd7ef6c7ad2,
reapplying

https://github.com/llvm/llvm-project/commit/7e66cf74fb4e6a103f923e34700a7b6f20ac2a9b
with a small (and probably temporary)
change to generate more debug info to help with diagnosing buildbot
issues.</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Upgrade CompilerType::GetBitSize to return llvm::Expected  (#129601)</title>
<updated>2025-03-05T18:21:19+00:00</updated>
<author>
<name>Adrian Prantl</name>
<email>aprantl@apple.com</email>
</author>
<published>2025-03-05T18:21:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=878a64f94a264ea4b564d6063614ddb0b5da3f6c'/>
<id>878a64f94a264ea4b564d6063614ddb0b5da3f6c</id>
<content type='text'>
This patch pushes the error handling boundary for the GetBitSize()
methods from Runtime into the Type and CompilerType APIs. This makes it
easier to diagnose problems thanks to more meaningful error messages
being available. GetBitSize() is often the first thing LLDB asks about a
type, so this method is particularly important for a better user
experience.

rdar://145667239</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This patch pushes the error handling boundary for the GetBitSize()
methods from Runtime into the Type and CompilerType APIs. This makes it
easier to diagnose problems thanks to more meaningful error messages
being available. GetBitSize() is often the first thing LLDB asks about a
type, so this method is particularly important for a better user
experience.

rdar://145667239</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Change lldb's breakpoint handling behavior, reland (#126988)</title>
<updated>2025-02-13T19:30:10+00:00</updated>
<author>
<name>Jason Molenda</name>
<email>jmolenda@apple.com</email>
</author>
<published>2025-02-13T19:30:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=b666ac3b63e01bfa602318c877ea2395fea53f89'/>
<id>b666ac3b63e01bfa602318c877ea2395fea53f89</id>
<content type='text'>
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</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "Reland "[lldb] Implement basic support for reverse-continue" (#125242)"</title>
<updated>2025-01-31T21:11:20+00:00</updated>
<author>
<name>Adrian Prantl</name>
<email>aprantl@apple.com</email>
</author>
<published>2025-01-31T21:11:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=87b7f63a117c340a6d9ca47959335fd7ef6c7ad2'/>
<id>87b7f63a117c340a6d9ca47959335fd7ef6c7ad2</id>
<content type='text'>
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/
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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/
</pre>
</div>
</content>
</entry>
<entry>
<title>Reland "[lldb] Implement basic support for reverse-continue" (#125242)</title>
<updated>2025-01-31T15:56:33+00:00</updated>
<author>
<name>David Spickett</name>
<email>david.spickett@linaro.org</email>
</author>
<published>2025-01-31T15:56:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=7e66cf74fb4e6a103f923e34700a7b6f20ac2a9b'/>
<id>7e66cf74fb4e6a103f923e34700a7b6f20ac2a9b</id>
<content type='text'>
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".</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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".</pre>
</div>
</content>
</entry>
</feed>
