"""
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

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.assertTrue(variables.IsValid())
        self.assertTrue(variables.GetValueAtIndex(0).name == "_handler_one")

        # 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")
