"""
Test scripted frame provider functionality.
"""

import os

import lldb
import lldbsuite.test.lldbplatformutil as lldbplatformutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import TestBase
from lldbsuite.test import lldbutil


@requireNotWasm("multithreaded C++ inferior; wasm has no threads or exceptions")
class ScriptedFrameProviderTestCase(TestBase):
    NO_DEBUG_INFO_TESTCASE = True

    def setUp(self):
        TestBase.setUp(self)
        self.source = "main.cpp"

    def test_replace_all_frames(self):
        """Test that we can replace the entire stack."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Import the test frame provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Attach the Replace provider.
        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.ReplaceFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Verify we have exactly 3 synthetic frames.
        self.assertEqual(thread.GetNumFrames(), 3, "Should have 3 synthetic frames")

        # Verify frame indices and PCs (dictionary-based frames don't have custom function names).
        frame0 = thread.GetFrameAtIndex(0)
        self.assertIsNotNone(frame0)
        self.assertEqual(frame0.GetPC(), 0x1000)

        frame1 = thread.GetFrameAtIndex(1)
        self.assertIsNotNone(frame1)
        self.assertIn("thread_func", frame1.GetFunctionName())

        frame2 = thread.GetFrameAtIndex(2)
        self.assertIsNotNone(frame2)
        self.assertEqual(frame2.GetPC(), 0x3000)

    def test_prepend_frames(self):
        """Test that we can add frames before real stack."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Get original frame count and PC.
        original_frame_count = thread.GetNumFrames()
        self.assertGreaterEqual(
            original_frame_count, 2, "Should have at least 2 real frames"
        )

        # Import and attach Prepend provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.PrependFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Verify we have 2 more frames.
        new_frame_count = thread.GetNumFrames()
        self.assertEqual(new_frame_count, original_frame_count + 2)

        # Verify first 2 frames are synthetic (check PCs, not function names).
        frame0 = thread.GetFrameAtIndex(0)
        self.assertEqual(frame0.GetPC(), 0x9000)

        frame1 = thread.GetFrameAtIndex(1)
        self.assertEqual(frame1.GetPC(), 0xA000)

        # Verify frame 2 is the original real frame 0.
        frame2 = thread.GetFrameAtIndex(2)
        self.assertIn("thread_func", frame2.GetFunctionName())

    def test_append_frames(self):
        """Test that we can add frames after real stack."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Get original frame count.
        original_frame_count = thread.GetNumFrames()

        # Import and attach Append provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.AppendFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Verify we have 1 more frame.
        new_frame_count = thread.GetNumFrames()
        self.assertEqual(new_frame_count, original_frame_count + 1)

        # Verify first frames are still real.
        frame0 = thread.GetFrameAtIndex(0)
        self.assertIn("thread_func", frame0.GetFunctionName())

        frame_n_plus_1 = thread.GetFrameAtIndex(new_frame_count - 1)
        self.assertEqual(frame_n_plus_1.GetPC(), 0x10)

    def test_scripted_frame_thread_member(self):
        """Test that ScriptedFrame.thread is correctly set via GetThreadByID.

        This is a regression test for a bug where ScriptedFrame.__init__ used
        GetThreadByIndexID(tid) instead of GetThreadByID(tid). Since thread ID
        and index ID differ, the wrong API would produce an invalid thread.
        """
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.ThreadValidatingFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # The ThreadValidatingFrame encodes thread validity in its function name.
        frame0 = thread.GetFrameAtIndex(0)
        func_name = frame0.GetFunctionName()

        # If GetThreadByIndexID were used instead of GetThreadByID, the thread
        # would be invalid and the function name would be "thread_INVALID".
        self.assertNotEqual(
            func_name,
            "thread_INVALID",
            "ScriptedFrame.thread should be valid "
            "(GetThreadByID vs GetThreadByIndexID)",
        )
        self.assertIn("thread_valid_id_", func_name)

        # Verify the encoded thread ID matches the actual thread ID.
        expected_tid = thread.GetThreadID()
        self.assertIn(
            hex(expected_tid),
            func_name,
            f"ScriptedFrame.thread ID should match: expected {expected_tid:#x} "
            f"in '{func_name}'",
        )

    def test_scripted_frame_objects(self):
        """Test that provider can return ScriptedFrame objects."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Import the provider that returns ScriptedFrame objects.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.ScriptedFrameObjectProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Verify we have 5 frames.
        self.assertEqual(
            thread.GetNumFrames(), 5, "Should have 5 custom scripted frames"
        )

        # Verify frame properties from CustomScriptedFrame.
        frame0 = thread.GetFrameAtIndex(0)
        self.assertIsNotNone(frame0)
        self.assertEqual(frame0.GetFunctionName(), "custom_scripted_frame_0")
        self.assertEqual(frame0.GetPC(), 0x5000)
        self.assertTrue(frame0.IsSynthetic(), "Frame should be marked as synthetic")

        frame1 = thread.GetFrameAtIndex(1)
        self.assertIsNotNone(frame1)
        self.assertEqual(frame1.GetPC(), 0x6000)

        frame2 = thread.GetFrameAtIndex(2)
        self.assertIsNotNone(frame2)
        self.assertEqual(frame2.GetFunctionName(), "custom_scripted_frame_2")
        self.assertEqual(frame2.GetPC(), 0x7000)
        self.assertTrue(frame2.IsSynthetic(), "Frame should be marked as synthetic")

    def test_applies_to_thread(self):
        """Test that applies_to_thread filters which threads get the provider."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # We should have at least 2 threads (worker threads) at the breakpoint.
        num_threads = process.GetNumThreads()
        self.assertGreaterEqual(
            num_threads, 2, "Should have at least 2 threads at breakpoint"
        )

        # Import the test frame provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Collect original thread info before applying provider.
        thread_info = {}
        for i in range(num_threads):
            t = process.GetThreadAtIndex(i)
            thread_info[t.GetIndexID()] = {
                "frame_count": t.GetNumFrames(),
                "pc": t.GetFrameAtIndex(0).GetPC(),
            }

        # Register the ThreadFilterFrameProvider which only applies to thread ID 1.
        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.ThreadFilterFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Check each thread.
        thread_id_1_found = False
        # On ARM32, FixCodeAddress clears bit 0, so synthetic PCs get modified.
        is_arm_32bit = lldbplatformutil.getArchitecture() == "arm"
        expected_synthetic_pc = 0xFFFE if is_arm_32bit else 0xFFFF

        for i in range(num_threads):
            t = process.GetThreadAtIndex(i)
            thread_id = t.GetIndexID()

            if thread_id == 1:
                # Thread with ID 1 should have synthetic frame.
                thread_id_1_found = True
                self.assertEqual(
                    t.GetNumFrames(),
                    1,
                    f"Thread with ID 1 should have 1 synthetic frame",
                )
                self.assertEqual(
                    t.GetFrameAtIndex(0).GetPC(),
                    expected_synthetic_pc,
                    f"Thread with ID 1 should have synthetic PC {expected_synthetic_pc:#x}",
                )
            else:
                # Other threads should keep their original frames.
                self.assertEqual(
                    t.GetNumFrames(),
                    thread_info[thread_id]["frame_count"],
                    f"Thread with ID {thread_id} should not be affected by provider",
                )
                self.assertEqual(
                    t.GetFrameAtIndex(0).GetPC(),
                    thread_info[thread_id]["pc"],
                    f"Thread with ID {thread_id} should have its original PC",
                )

        # We should have found at least one thread with ID 1.
        self.assertTrue(
            thread_id_1_found,
            "Should have found a thread with ID 1 to test filtering",
        )

    def test_remove_frame_provider_by_id(self):
        """Test that RemoveScriptedFrameProvider removes a specific provider by ID."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Import the test frame providers.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Get original frame count.
        original_frame_count = thread.GetNumFrames()
        original_pc = thread.GetFrameAtIndex(0).GetPC()

        # Register the first provider and get its ID.
        error = lldb.SBError()
        provider_id_1 = target.RegisterScriptedFrameProvider(
            "test_frame_providers.ReplaceFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider 1: {error}")

        # Verify first provider is active (3 synthetic frames).
        self.assertEqual(thread.GetNumFrames(), 3, "Should have 3 synthetic frames")
        self.assertEqual(
            thread.GetFrameAtIndex(0).GetPC(), 0x1000, "Should have first provider's PC"
        )

        # Register a second provider and get its ID.
        provider_id_2 = target.RegisterScriptedFrameProvider(
            "test_frame_providers.PrependFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider 2: {error}")

        # Verify IDs are different
        self.assertNotEqual(
            provider_id_1, provider_id_2, "Provider IDs should be unique"
        )

        # Now remove the first provider by ID
        result = target.RemoveScriptedFrameProvider(provider_id_1)
        self.assertSuccess(
            result, f"Should successfully remove provider with ID {provider_id_1}"
        )

        # After removing the first provider, the second provider should still be
        # active. The PrependFrameProvider adds 2 frames before the real stack.
        # Since ReplaceFrameProvider had 3 frames, and we removed it, we should now
        # have the original frames (from real stack) with PrependFrameProvider applied.
        new_frame_count = thread.GetNumFrames()
        self.assertEqual(
            new_frame_count,
            original_frame_count + 2,
            "Should have original frames + 2 prepended frames",
        )

        # First two frames should be from PrependFrameProvider.
        self.assertEqual(
            thread.GetFrameAtIndex(0).GetPC(),
            0x9000,
            "First frame should be from PrependFrameProvider",
        )
        self.assertEqual(
            thread.GetFrameAtIndex(1).GetPC(),
            0xA000,
            "Second frame should be from PrependFrameProvider",
        )

        # Remove the second provider.
        result = target.RemoveScriptedFrameProvider(provider_id_2)
        self.assertSuccess(
            result, f"Should successfully remove provider with ID {provider_id_2}"
        )

        # After removing both providers, frames should be back to original.
        self.assertEqual(
            thread.GetNumFrames(),
            original_frame_count,
            "Should restore original frame count",
        )
        self.assertEqual(
            thread.GetFrameAtIndex(0).GetPC(),
            original_pc,
            "Should restore original PC",
        )

        # Try to remove a provider that doesn't exist.
        result = target.RemoveScriptedFrameProvider(999999)
        self.assertTrue(result.Fail(), "Should fail to remove non-existent provider")

    def test_circular_dependency_fix(self):
        """Test that accessing input_frames in __init__ doesn't cause circular dependency.

        This test verifies the fix for the circular dependency issue where:
        1. Thread::GetStackFrameList() creates the frame provider
        2. Provider's __init__ accesses input_frames and calls methods on frames
        3. SBFrame methods trigger ExecutionContextRef::GetFrameSP()
        4. Before the fix: GetFrameSP() would call Thread::GetStackFrameList() again -> circular dependency!
        5. After the fix: GetFrameSP() uses the remembered frame list -> no circular dependency

        The fix works by:
        - StackFrame stores m_frame_list_wp (weak pointer to originating list)
        - ExecutionContextRef stores m_frame_list_wp when created from a frame
        - ExecutionContextRef::GetFrameSP() tries the remembered list first before asking the thread
        """
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Get original frame count and PC.
        original_frame_count = thread.GetNumFrames()
        original_pc = thread.GetFrameAtIndex(0).GetPC()
        self.assertGreaterEqual(
            original_frame_count, 2, "Should have at least 2 real frames"
        )

        # Import the provider that accesses input frames in __init__.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Register the CircularDependencyTestProvider.
        # Before the fix, this would crash or hang due to circular dependency.
        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.CircularDependencyTestProvider",
            lldb.SBStructuredData(),
            error,
        )

        # If we get here without crashing, the fix is working!
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Verify the provider worked correctly,
        # Should have 1 synthetic frame + all original frames.
        new_frame_count = thread.GetNumFrames()
        self.assertEqual(
            new_frame_count,
            original_frame_count + 1,
            "Should have original frames + 1 synthetic frame",
        )

        # On ARM32, FixCodeAddress clears bit 0, so synthetic PCs get modified.
        is_arm_32bit = lldbplatformutil.getArchitecture() == "arm"
        expected_synthetic_pc = 0xDEADBEEE if is_arm_32bit else 0xDEADBEEF

        # First frame should be synthetic.
        frame0 = thread.GetFrameAtIndex(0)
        self.assertIsNotNone(frame0)
        self.assertEqual(
            frame0.GetPC(),
            expected_synthetic_pc,
            f"First frame should be synthetic frame with PC {expected_synthetic_pc:#x}",
        )

        # Second frame should be the original first frame.
        frame1 = thread.GetFrameAtIndex(1)
        self.assertIsNotNone(frame1)
        self.assertEqual(
            frame1.GetPC(),
            original_pc,
            "Second frame should be original first frame",
        )

        # Verify we can still call methods on frames (no circular dependency!).
        for i in range(min(3, new_frame_count)):
            frame = thread.GetFrameAtIndex(i)
            self.assertIsNotNone(frame)
            # These calls should not trigger circular dependency.
            pc = frame.GetPC()
            self.assertNotEqual(pc, 0, f"Frame {i} should have valid PC")

    def test_python_source_frames(self):
        """Test that frames can point to Python source files and display properly."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Get original frame count.
        original_frame_count = thread.GetNumFrames()
        self.assertGreaterEqual(
            original_frame_count, 2, "Should have at least 2 real frames"
        )

        # Import the provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Register the PythonSourceFrameProvider.
        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.PythonSourceFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Verify we have 3 more frames (Python frames).
        new_frame_count = thread.GetNumFrames()
        self.assertEqual(
            new_frame_count,
            original_frame_count + 3,
            "Should have original frames + 3 Python frames",
        )

        # Verify first three frames are Python source frames.
        frame0 = thread.GetFrameAtIndex(0)
        self.assertIsNotNone(frame0)
        self.assertEqual(
            frame0.GetFunctionName(),
            "compute_fibonacci",
            "First frame should be compute_fibonacci",
        )
        self.assertTrue(frame0.IsSynthetic(), "Frame should be marked as synthetic")
        # PC-less frames should show invalid address and not crash.
        self.assertEqual(
            frame0.GetPC(),
            lldb.LLDB_INVALID_ADDRESS,
            "PC-less frame should have LLDB_INVALID_ADDRESS",
        )

        self.assertEqual(
            frame0.GetFP(),
            lldb.LLDB_INVALID_ADDRESS,
            "PC-less frame FP should return LLDB_INVALID_ADDRESS",
        )
        self.assertEqual(
            frame0.GetSP(),
            lldb.LLDB_INVALID_ADDRESS,
            "PC-less frame SP should return LLDB_INVALID_ADDRESS",
        )
        self.assertEqual(
            frame0.GetCFA(),
            0,
            "PC-less frame CFA should return 0",
        )

        frame1 = thread.GetFrameAtIndex(1)
        self.assertIsNotNone(frame1)
        self.assertEqual(
            frame1.GetFunctionName(),
            "process_data",
            "Second frame should be process_data",
        )
        self.assertTrue(frame1.IsSynthetic(), "Frame should be marked as synthetic")

        frame2 = thread.GetFrameAtIndex(2)
        self.assertIsNotNone(frame2)
        self.assertEqual(frame2.GetFunctionName(), "main", "Third frame should be main")
        self.assertTrue(frame2.IsSynthetic(), "Frame should be marked as synthetic")

        # Verify line entry information is present.
        line_entry0 = frame0.GetLineEntry()
        self.assertTrue(line_entry0.IsValid(), "Frame 0 should have a valid line entry")
        self.assertEqual(line_entry0.GetLine(), 7, "Frame 0 should point to line 7")
        file_spec0 = line_entry0.GetFileSpec()
        self.assertTrue(file_spec0.IsValid(), "Frame 0 should have valid file spec")
        self.assertEqual(
            file_spec0.GetFilename(),
            "python_helper.py",
            "Frame 0 should point to python_helper.py",
        )

        line_entry1 = frame1.GetLineEntry()
        self.assertTrue(line_entry1.IsValid(), "Frame 1 should have a valid line entry")
        self.assertEqual(line_entry1.GetLine(), 16, "Frame 1 should point to line 16")

        line_entry2 = frame2.GetLineEntry()
        self.assertTrue(line_entry2.IsValid(), "Frame 2 should have a valid line entry")
        self.assertEqual(line_entry2.GetLine(), 27, "Frame 2 should point to line 27")

        # Verify the frames display properly in backtrace.
        # This tests that PC-less frames don't show 0xffffffffffffffff.
        self.runCmd("bt")
        output = self.res.GetOutput()

        # Should show function names.
        self.assertIn("compute_fibonacci", output)
        self.assertIn("process_data", output)
        self.assertIn("main", output)

        # Should show Python file.
        self.assertIn("python_helper.py", output)

        # Should show line numbers.
        self.assertIn(":7", output)  # compute_fibonacci line.
        self.assertIn(":16", output)  # process_data line.
        self.assertIn(":27", output)  # main line.

        # Should NOT show invalid address (0xffffffffffffffff).
        self.assertNotIn("0xffffffffffffffff", output.lower())

        # Verify frame 3 is the original real frame 0.
        frame3 = thread.GetFrameAtIndex(3)
        self.assertIsNotNone(frame3)
        self.assertIn("thread_func", frame3.GetFunctionName())

    def test_valid_pc_no_module_frames(self):
        """Test that frames with valid PC but no module display correctly in backtrace."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Get original frame count.
        original_frame_count = thread.GetNumFrames()
        self.assertGreaterEqual(
            original_frame_count, 2, "Should have at least 2 real frames"
        )

        # Import the provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Register the ValidPCNoModuleFrameProvider.
        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.ValidPCNoModuleFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Verify we have 2 more frames (the synthetic frames).
        new_frame_count = thread.GetNumFrames()
        self.assertEqual(
            new_frame_count,
            original_frame_count + 2,
            "Should have original frames + 2 synthetic frames",
        )

        # Verify first two frames have valid PCs and function names.
        frame0 = thread.GetFrameAtIndex(0)
        self.assertIsNotNone(frame0)
        self.assertEqual(
            frame0.GetFunctionName(),
            "unknown_function_1",
            "First frame should be unknown_function_1",
        )
        self.assertTrue(frame0.IsSynthetic(), "Frame should be marked as synthetic")
        self.assertEqual(
            frame0.GetPC(), 0x1234000, "First frame should have PC 0x1234000"
        )

        frame1 = thread.GetFrameAtIndex(1)
        self.assertIsNotNone(frame1)
        self.assertEqual(
            frame1.GetFunctionName(),
            "unknown_function_2",
            "Second frame should be unknown_function_2",
        )
        self.assertTrue(frame1.IsSynthetic(), "Frame should be marked as synthetic")
        self.assertEqual(
            frame1.GetPC(), 0x5678000, "Second frame should have PC 0x5678000"
        )

        # Verify the frames display properly in backtrace.
        # The backtrace should show the PC values without crashing or displaying
        # invalid addresses like 0xffffffffffffffff.
        self.runCmd("bt")
        output = self.res.GetOutput()

        # Should show function names.
        self.assertIn("unknown_function_1", output)
        self.assertIn("unknown_function_2", output)

        # Should show PC addresses in hex format.
        self.assertIn("1234000", output)
        self.assertIn("5678000", output)

        # Verify PC and function name are properly separated by space.
        self.assertIn("1234000 unknown_function_1", output)
        self.assertIn("5678000 unknown_function_2", output)

        # Should NOT show invalid address.
        self.assertNotIn("ffffff", output.lower())

        # Verify frame 2 is the original real frame 0.
        frame2 = thread.GetFrameAtIndex(2)
        self.assertIsNotNone(frame2)
        self.assertIn("thread_func", frame2.GetFunctionName())

    def test_chained_frame_providers(self):
        """Test that multiple frame providers chain together."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Get original frame count.
        original_frame_count = thread.GetNumFrames()
        self.assertGreaterEqual(
            original_frame_count, 2, "Should have at least 2 real frames"
        )

        # Import the test frame providers.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Register 3 providers with different priorities.
        # Each provider adds 1 frame at the beginning.
        error = lldb.SBError()

        # Provider 1: Priority 10 - adds "foo" frame
        provider_id_1 = target.RegisterScriptedFrameProvider(
            "test_frame_providers.AddFooFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register foo provider: {error}")

        # Provider 2: Priority 20 - adds "bar" frame
        provider_id_2 = target.RegisterScriptedFrameProvider(
            "test_frame_providers.AddBarFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register bar provider: {error}")

        # Provider 3: Priority 30 - adds "baz" frame
        provider_id_3 = target.RegisterScriptedFrameProvider(
            "test_frame_providers.AddBazFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register baz provider: {error}")

        # Verify we have 3 more frames (one from each provider).
        new_frame_count = thread.GetNumFrames()
        self.assertEqual(
            new_frame_count,
            original_frame_count + 3,
            "Should have original frames + 3 chained frames",
        )

        # Verify the chaining order: baz, bar, foo, then real frames.
        # Since priority is lower = higher, the order should be:
        # Provider 1 (priority 10) transforms real frames first -> adds "foo"
        # Provider 2 (priority 20) transforms Provider 1's output -> adds "bar"
        # Provider 3 (priority 30) transforms Provider 2's output -> adds "baz"
        # So final stack is: baz, bar, foo, real frames...

        frame0 = thread.GetFrameAtIndex(0)
        self.assertIsNotNone(frame0)
        self.assertEqual(
            frame0.GetFunctionName(),
            "baz",
            "Frame 0 should be 'baz' from last provider in chain",
        )
        self.assertEqual(frame0.GetPC(), 0xBAC)

        frame1 = thread.GetFrameAtIndex(1)
        self.assertIsNotNone(frame1)
        self.assertEqual(
            frame1.GetFunctionName(),
            "bar",
            "Frame 1 should be 'bar' from second provider in chain",
        )
        self.assertEqual(frame1.GetPC(), 0xBAA)

        frame2 = thread.GetFrameAtIndex(2)
        self.assertIsNotNone(frame2)
        self.assertEqual(
            frame2.GetFunctionName(),
            "foo",
            "Frame 2 should be 'foo' from first provider in chain",
        )
        self.assertEqual(frame2.GetPC(), 0xF00)

        # Frame 3 should be the original real frame 0.
        frame3 = thread.GetFrameAtIndex(3)
        self.assertIsNotNone(frame3)
        self.assertIn("thread_func", frame3.GetFunctionName())

    def test_get_values(self):
        """Test a frame that provides values."""
        self.build()
        # Set the breakpoint after the variable_in_main variable exists and can be queried.
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self,
            "Breakpoint for variable tests",
            lldb.SBFileSpec(self.source),
            only_one_thread=False,
        )

        # Get original frame count.
        original_frame_count = thread.GetNumFrames()
        self.assertGreaterEqual(
            original_frame_count, 2, "Should have at least 2 real frames"
        )

        # Import the test frame providers.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Register a provider that can provide variables.
        error = lldb.SBError()
        target.RegisterScriptedFrameProvider(
            "test_frame_providers.ValueProvidingFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")

        # Verify we have 1 more frame.
        new_frame_count = thread.GetNumFrames()
        self.assertEqual(
            new_frame_count,
            original_frame_count + 1,
            "Should have original frames + 1 extra frames",
        )

        # Check that we can get variables from this frame.
        frame0 = thread.GetFrameAtIndex(0)
        self.assertIsNotNone(frame0)

        # Ensure that we can get synthetic variables with `SetIncludeSynthetic`.
        options = lldb.SBVariablesOptions()
        options.SetIncludeSynthetic(True)
        variables = frame0.GetVariables(options)
        self.assertFalse(variables.IsValid())
        self.assertEqual(variables.GetSize(), 0)

        options.SetIncludeLocals(True)
        variables = frame0.GetVariables(options)
        self.assertTrue(variables.IsValid())
        self.assertEqual(variables.GetSize(), 2)
        self.assertEqual(variables.GetValueAtIndex(0).name, "variable_in_main")
        self.assertEqual(variables.GetValueAtIndex(1).name, "_handler_one")

        # Ensure that we get synthetic variables in the other overloads.
        # (arguments, locals, statics, in_scope_only)
        variables = frame0.GetVariables(False, False, False, False)
        self.assertFalse(variables.IsValid())
        self.assertEqual(variables.GetSize(), 0)
        variables = frame0.GetVariables(False, True, False, False)
        self.assertTrue(variables.IsValid())
        self.assertEqual(variables.GetSize(), 2)
        self.assertEqual(variables.GetValueAtIndex(0).name, "variable_in_main")
        self.assertEqual(variables.GetValueAtIndex(1).name, "_handler_one")

        # (arguments, locals, statics, in_scope_only, use_dynamic)
        variables = frame0.GetVariables(
            False, True, False, False, lldb.eNoDynamicValues
        )
        self.assertTrue(variables.IsValid())
        self.assertEqual(variables.GetSize(), 2)
        self.assertEqual(variables.GetValueAtIndex(0).name, "variable_in_main")
        self.assertEqual(variables.GetValueAtIndex(1).name, "_handler_one")

        # Synthetic variables are always in scope.
        variables = frame0.GetVariables(False, False, False, True)
        self.assertFalse(variables.IsValid())
        self.assertEqual(variables.GetSize(), 0)
        variables = frame0.GetVariables(False, True, False, True)
        self.assertTrue(variables.IsValid())
        # We don't see `variable_in_main` here, because it doesn't have the synthetic flag.
        self.assertEqual(variables.GetSize(), 1)
        self.assertEqual(variables.GetValueAtIndex(0).name, "_handler_one")

        # A variable reports the ValueType the frame classified it as, not the
        # one that follows from how its ValueObject was built. `_handler_one`
        # comes from an expression, so the two differ.
        self.assertEqual(
            variables.GetValueAtIndex(0).GetValueType(),
            lldb.eValueTypeVariableLocal | lldb.eValueTypeSyntheticFlag,
        )
        # Classifying a variable must not cost its data or its type.
        self.assertEqual(variables.GetValueAtIndex(0).GetValueAsUnsigned(), 1)
        self.assertEqual(variables.GetValueAtIndex(0).GetTypeName(), "uint32_t")
        # Reaching the same variable by name has to agree with the enumeration.
        self.assertEqual(
            frame0.FindVariable("_handler_one").GetValueType(),
            lldb.eValueTypeVariableLocal | lldb.eValueTypeSyntheticFlag,
        )
        self.assertEqual(frame0.FindVariable("_handler_one").GetValueAsUnsigned(), 1)

        # Check the `frame variable` command(s) handle synthetic variables the
        # way we expect by printing them.
        self.expect("frame var", substrs=["variable_in_main", "_handler_one"])

        # Then, try and run it without synthetic variables and ensure we don't
        # get any, but we still get the others.
        interp = self.dbg.GetCommandInterpreter()
        command_result = lldb.SBCommandReturnObject()
        result = interp.HandleCommand("frame var -e", command_result)
        self.assertEqual(
            result, lldb.eReturnStatusSuccessFinishResult, "frame var -e didn't succeed"
        )
        output = command_result.GetOutput()
        self.assertIn("variable_in_main", output, "Didn't find a regular variable")
        self.assertNotIn("_handler_one", output, "Found an synthetic variable")

        # Check that we can get values from paths. `_handler_one` is a special
        # value we provide through only our expression handler in the frame
        # implementation. We can't evaluate expressions on the special value
        # just because the test implementation doesn't handle it, and we
        # delegate all expression handling to the implementation.
        one = frame0.GetValueForVariablePath("_handler_one")
        self.assertEqual(one.unsigned, 1)
        # Ensure I can still access and do arithmetic on regular variables.
        varp1 = frame0.GetValueForVariablePath("variable_in_main + 1")
        self.assertEqual(varp1.unsigned, 124)

    def test_frame_validity_after_step(self):
        """Test that SBFrame references from ScriptedFrameProvider remain valid after stepping.

        This test verifies that ExecutionContextRef properly handles frame list identifiers
        when the underlying stack changes. After stepping, old frame references should become
        invalid gracefully without crashing.
        """
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        # Import the test frame provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Register a provider that prepends synthetic frames.
        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.PrependFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")

        # Get frame references before stepping.
        frame0_before = thread.GetFrameAtIndex(0)
        frame1_before = thread.GetFrameAtIndex(1)
        frame2_before = thread.GetFrameAtIndex(2)

        self.assertIsNotNone(frame0_before)
        self.assertIsNotNone(frame1_before)
        self.assertIsNotNone(frame2_before)

        # Verify frames are valid and have expected PCs.
        self.assertTrue(frame0_before.IsValid(), "Frame 0 should be valid before step")
        self.assertTrue(frame1_before.IsValid(), "Frame 1 should be valid before step")
        self.assertTrue(frame2_before.IsValid(), "Frame 2 should be valid before step")

        pc0_before = frame0_before.GetPC()
        pc1_before = frame1_before.GetPC()
        pc2_before = frame2_before.GetPC()

        self.assertEqual(pc0_before, 0x9000, "Frame 0 should have synthetic PC 0x9000")
        self.assertEqual(pc1_before, 0xA000, "Frame 1 should have synthetic PC 0xA000")

        # Step the thread, which will invalidate the old frame list.
        thread.StepInstruction(False)

        # After stepping, the frame list has changed. Old frame references should
        # detect this and become invalid, but shouldn't crash.
        # The key here is that GetPC() and other operations should handle the
        # "frame provider no longer available" case gracefully.

        # Try to access the old frames - they should either:
        # 1. Return invalid/default values gracefully, or
        # 2. Still work if the frame provider is re-applied.

        # Get new frames after stepping.
        frame0_after = thread.GetFrameAtIndex(0)
        self.assertIsNotNone(frame0_after)
        self.assertTrue(
            frame0_after.IsValid(), "New frame 0 should be valid after step"
        )

        # The old frame references might or might not be valid depending on whether
        # the frame provider is still active. What's important is that accessing
        # them doesn't crash and handles the situation gracefully.
        # We'll just verify we can call methods on them without crashing.
        try:
            _ = frame0_before.GetPC()
            _ = frame0_before.IsValid()
            _ = frame0_before.GetFunctionName()
        except Exception as e:
            self.fail(f"Accessing old frame reference should not crash: {e}")

    def test_provider_lifecycle_with_frame_validity(self):
        """Test provider registration/removal at breakpoints and SBFrame validity across lifecycle.

        This test verifies:
        1. Registering a provider while stopped at a breakpoint.
        2. SBFrame references from synthetic frames persist across continues.
        3. SBFrame references can access variables in real frames while provider is active.
        4. Removing a provider while stopped at a breakpoint.
        5. SBFrame references from removed provider don't crash when accessed.
        """
        self.build()
        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
        self.assertTrue(target.IsValid(), "Target should be valid")

        # Import the test frame provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # Set up breakpoints at the return statements in foo, bar, and baz.
        # This ensures local variables are initialized.
        bp_foo = target.BreakpointCreateBySourceRegex(
            "Break in foo", lldb.SBFileSpec(self.source)
        )
        bp_bar = target.BreakpointCreateBySourceRegex(
            "Break in bar", lldb.SBFileSpec(self.source)
        )
        bp_baz = target.BreakpointCreateBySourceRegex(
            "Break in baz", lldb.SBFileSpec(self.source)
        )

        self.assertTrue(bp_foo.IsValid(), "Breakpoint at foo should be valid")
        self.assertTrue(bp_bar.IsValid(), "Breakpoint at bar should be valid")
        self.assertTrue(bp_baz.IsValid(), "Breakpoint at baz should be valid")

        # Launch the process.
        process = target.LaunchSimple(None, None, self.get_process_working_directory())
        self.assertTrue(process.IsValid(), "Process should be valid")

        # We should hit the foo breakpoint first.
        self.assertEqual(
            process.GetState(), lldb.eStateStopped, "Process should be stopped at foo"
        )
        thread = process.GetSelectedThread()
        self.assertIsNotNone(thread, "Should have a selected thread")

        # Register the provider at foo breakpoint.
        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.PrependFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertTrue(error.Success(), f"Failed to register provider: {error}")
        self.assertNotEqual(provider_id, 0, "Provider ID should be non-zero")

        # Get individual frames BEFORE getting the full backtrace.
        # This tests accessing frames before forcing evaluation of all frames.
        frame0 = thread.GetFrameAtIndex(0)
        frame1 = thread.GetFrameAtIndex(1)
        frame2 = thread.GetFrameAtIndex(2)

        self.assertIsNotNone(frame0, "Frame 0 should exist")
        self.assertIsNotNone(frame1, "Frame 1 should exist")
        self.assertIsNotNone(frame2, "Frame 2 should exist")

        # First two frames should be synthetic with expected PCs.
        pc0 = frame0.GetPC()
        pc1 = frame1.GetPC()

        self.assertEqual(pc0, 0x9000, "Frame 0 should have synthetic PC 0x9000")
        self.assertEqual(pc1, 0xA000, "Frame 1 should have synthetic PC 0xA000")

        # Frame 2 should be the real foo frame.
        self.assertIn("foo", frame2.GetFunctionName(), "Frame 2 should be in foo")

        # Save references to the synthetic frames.
        saved_frames = [frame0, frame1, frame2]

        # Test accessing saved frames at foo BEFORE getting full backtrace.
        try:
            _ = saved_frames[0].GetPC()
            _ = saved_frames[1].GetPC()
            _ = saved_frames[2].GetFunctionName()
        except Exception as e:
            self.fail(
                f"Accessing saved frames at foo before full backtrace should not crash: {e}"
            )

        # Now verify the provider is active by checking frame count.
        # PrependFrameProvider adds 2 synthetic frames.
        # This forces a full backtrace evaluation.
        original_frame_count = thread.GetNumFrames()
        self.assertGreater(
            original_frame_count,
            2,
            "Should have at least synthetic frames + real frames",
        )

        # Test accessing saved frames at foo AFTER getting full backtrace.
        try:
            _ = saved_frames[0].GetPC()
            _ = saved_frames[1].GetPC()
            _ = saved_frames[2].GetFunctionName()
        except Exception as e:
            self.fail(
                f"Accessing saved frames at foo after full backtrace should not crash: {e}"
            )

        # Verify we can access variables in frame2 (real frame).
        foo_local = frame2.FindVariable("foo_local")
        self.assertTrue(foo_local.IsValid(), "Should find foo_local variable")
        self.assertEqual(
            foo_local.GetValueAsUnsigned(), 20, "foo_local should be 20 (10 * 2)"
        )

        # Continue to bar breakpoint.
        threads = lldbutil.continue_to_breakpoint(process, bp_bar)
        self.assertIsNotNone(threads, "Should have stopped at bar breakpoint")
        self.assertEqual(len(threads), 1, "Should have one thread stopped at bar")
        thread = threads[0]

        # Verify the saved frames are still accessible without crashing at bar.
        # Do this BEFORE getting the full backtrace.
        # Note: They might not be "valid" in the traditional sense since we've moved
        # to a different execution context, but they shouldn't crash.
        try:
            _ = saved_frames[0].GetPC()
            _ = saved_frames[1].GetPC()
        except Exception as e:
            self.fail(
                f"Accessing saved frames at bar before full backtrace should not crash: {e}"
            )

        # Verify the provider is still active by getting frame count.
        # This forces full backtrace evaluation.
        current_frame_count = thread.GetNumFrames()
        self.assertGreater(
            current_frame_count, 2, "Should still have synthetic frames at bar"
        )

        # Access the saved frames again AFTER getting the full backtrace.
        # This ensures that forcing a full backtrace evaluation doesn't break
        # the saved frame references.
        try:
            _ = saved_frames[0].GetPC()
            _ = saved_frames[1].GetPC()
        except Exception as e:
            self.fail(
                f"Accessing saved frames at bar after full backtrace should not crash: {e}"
            )

        # Get current frames at bar.
        bar_frame0 = thread.GetFrameAtIndex(0)
        bar_frame1 = thread.GetFrameAtIndex(1)
        bar_frame2 = thread.GetFrameAtIndex(2)

        # Verify current frames have synthetic PCs.
        self.assertEqual(
            bar_frame0.GetPC(), 0x9000, "Frame 0 at bar should have synthetic PC"
        )
        self.assertEqual(
            bar_frame1.GetPC(), 0xA000, "Frame 1 at bar should have synthetic PC"
        )
        self.assertIn("bar", bar_frame2.GetFunctionName(), "Frame 2 should be in bar")

        # Verify we can access variables in the bar frame.
        bar_local = bar_frame2.FindVariable("bar_local")
        self.assertTrue(bar_local.IsValid(), "Should find bar_local variable")
        self.assertEqual(
            bar_local.GetValueAsUnsigned(), 25, "bar_local should be 25 (5 * 5)"
        )

        # Continue to baz breakpoint.
        threads = lldbutil.continue_to_breakpoint(process, bp_baz)
        self.assertIsNotNone(threads, "Should have stopped at baz breakpoint")
        self.assertEqual(len(threads), 1, "Should have one thread stopped at baz")
        thread = threads[0]

        # Verify the saved frames are still accessible without crashing at baz.
        # Do this BEFORE getting the full backtrace.
        try:
            _ = saved_frames[0].GetPC()
            _ = saved_frames[1].GetPC()
            _ = saved_frames[2].GetFunctionName()
        except Exception as e:
            self.fail(
                f"Accessing saved frames at baz before full backtrace should not crash: {e}"
            )

        # Get the frame count to force full backtrace evaluation at baz.
        baz_frame_count = thread.GetNumFrames()
        self.assertGreater(
            baz_frame_count, 2, "Should still have synthetic frames at baz"
        )

        # Verify the saved frames are still accessible AFTER getting full backtrace at baz.
        try:
            _ = saved_frames[0].GetPC()
            _ = saved_frames[1].GetPC()
            _ = saved_frames[2].GetFunctionName()
        except Exception as e:
            self.fail(
                f"Accessing saved frames at baz after full backtrace should not crash: {e}"
            )

        # Now manually remove the provider.
        result = target.RemoveScriptedFrameProvider(provider_id)
        self.assertSuccess(
            result, f"Should successfully remove provider with ID {provider_id}"
        )
        # Verify frames no longer have synthetic frames.
        final_frame_count = thread.GetNumFrames()

        # Without the provider, we should have fewer frames (no synthetic ones).
        self.assertLess(
            final_frame_count,
            original_frame_count,
            "Frame count should decrease after provider removal",
        )

        # First frame should now be the real baz frame (no synthetic frames).
        baz_frame0 = thread.GetFrameAtIndex(0)
        self.assertIn(
            "baz", baz_frame0.GetFunctionName(), "Frame 0 should now be real baz frame"
        )

        # The synthetic PC values should no longer appear.
        for i in range(final_frame_count):
            frame = thread.GetFrameAtIndex(i)
            pc = frame.GetPC()
            self.assertNotEqual(
                pc, 0x9000, f"Frame {i} should not have synthetic PC 0x9000"
            )
            self.assertNotEqual(
                pc, 0xA000, f"Frame {i} should not have synthetic PC 0xA000"
            )

        # Verify the originally saved frames are now truly invalid/stale.
        # They should still not crash when accessed.
        try:
            _ = saved_frames[0].GetPC()
            _ = saved_frames[0].IsValid()
            _ = saved_frames[1].GetPC()
            _ = saved_frames[1].IsValid()
        except Exception as e:
            self.fail(f"Accessing invalidated frames should not crash: {e}")

    def test_event_broadcasting(self):
        """Test that adding/removing frame providers broadcasts eBroadcastBitStackChanged."""
        self.build()

        listener = lldb.SBListener("stack_changed_listener")
        listener.StartListeningForEventClass(
            self.dbg,
            lldb.SBThread.GetBroadcasterClassName(),
            lldb.SBThread.eBroadcastBitStackChanged,
        )

        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        expected_thread_ids = {
            process.GetThreadAtIndex(i).GetIndexID()
            for i in range(process.GetNumThreads())
        }

        def collect_stack_changed_thread_ids(count):
            event = lldb.SBEvent()
            thread_ids = set()
            for _ in range(count):
                if not listener.WaitForEvent(5, event):
                    break
                self.assertEqual(
                    event.GetType(),
                    lldb.SBThread.eBroadcastBitStackChanged,
                    "Event should be stack changed",
                )
                thread_ids.add(lldb.SBThread.GetThreadFromEvent(event).GetIndexID())
            return thread_ids

        # Import the test frame provider.
        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        # 1. Test registration.
        error = lldb.SBError()
        provider_id = target.RegisterScriptedFrameProvider(
            "test_frame_providers.ReplaceFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertSuccess(error, f"Failed to register provider: {error}")
        self.assertEqual(
            collect_stack_changed_thread_ids(len(expected_thread_ids)),
            expected_thread_ids,
            "All threads should broadcast eBroadcastBitStackChanged on registration",
        )

        # 2. Test removal.
        result = target.RemoveScriptedFrameProvider(provider_id)
        self.assertSuccess(result, f"Failed to remove provider: {result}")
        self.assertEqual(
            collect_stack_changed_thread_ids(len(expected_thread_ids)),
            expected_thread_ids,
            "All threads should broadcast eBroadcastBitStackChanged on removal",
        )

        # 3. Test clear.
        target.RegisterScriptedFrameProvider(
            "test_frame_providers.ReplaceFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        # Consume registration
        collect_stack_changed_thread_ids(len(expected_thread_ids))

        self.runCmd("target frame-provider clear")
        self.assertEqual(
            collect_stack_changed_thread_ids(len(expected_thread_ids)),
            expected_thread_ids,
            "All threads should broadcast eBroadcastBitStackChanged on clear",
        )

    def test_incremental_fetch_synthetic_frame_identity(self):
        """Test that incrementally fetched PC-less synthetic frames each get a
        unique StackID so they resolve to the correct frame."""
        self.build()
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Break here", lldb.SBFileSpec(self.source), only_one_thread=False
        )

        script_path = os.path.join(self.getSourceDir(), "test_frame_providers.py")
        self.runCmd("command script import " + script_path)

        error = lldb.SBError()
        target.RegisterScriptedFrameProvider(
            "test_frame_providers.PythonSourceFrameProvider",
            lldb.SBStructuredData(),
            error,
        )
        self.assertSuccess(error)

        # Fetch frames one at a time to trigger separate FetchFramesUpTo calls.
        frame0 = thread.GetFrameAtIndex(0)
        frame1 = thread.GetFrameAtIndex(1)

        self.assertEqual(frame0.GetFunctionName(), "compute_fibonacci")
        self.assertEqual(frame1.GetFunctionName(), "process_data")
