""" Test SBFrameList API. """ import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * from lldbsuite.test import lldbutil class FrameListAPITestCase(TestBase): def test_frame_list_api(self): """Test SBThread.GetFrames() returns a valid SBFrameList.""" self.build() self.frame_list_api() def test_frame_list_iterator(self): """Test SBFrameList iterator functionality.""" self.build() self.frame_list_iterator() def test_frame_list_indexing(self): """Test SBFrameList indexing and length.""" self.build() self.frame_list_indexing() def test_frame_list_get_thread(self): """Test SBFrameList.GetThread() returns correct thread.""" self.build() self.frame_list_get_thread() def setUp(self): TestBase.setUp(self) self.main_source = "main.cpp" def frame_list_api(self): """Test SBThread.GetFrames() returns a valid SBFrameList.""" exe = self.getBuildArtifact("a.out") target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( self, "Set break point at this line", lldb.SBFileSpec(self.main_source) ) self.assertTrue( thread.IsValid(), "There should be a thread stopped due to breakpoint" ) # Test GetFrames() returns a valid SBFrameList frame_list = thread.GetFrames() self.assertTrue(frame_list.IsValid(), "Frame list should be valid") self.assertGreater( frame_list.GetSize(), 0, "Frame list should have at least one frame" ) # Verify frame list size matches thread frame count self.assertEqual( frame_list.GetSize(), thread.GetNumFrames(), "Frame list size should match thread frame count", ) # Verify frames are the same for i in range(frame_list.GetSize()): frame_from_list = frame_list.GetFrameAtIndex(i) frame_from_thread = thread.GetFrameAtIndex(i) self.assertTrue( frame_from_list.IsValid(), f"Frame {i} from list should be valid" ) self.assertEqual( frame_from_list.GetPC(), frame_from_thread.GetPC(), f"Frame {i} PC should match", ) def frame_list_iterator(self): """Test SBFrameList iterator functionality.""" exe = self.getBuildArtifact("a.out") target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( self, "Set break point at this line", lldb.SBFileSpec(self.main_source) ) self.assertTrue( thread.IsValid(), "There should be a thread stopped due to breakpoint" ) frame_list = thread.GetFrames() # Test iteration frame_count = 0 for frame in frame_list: self.assertTrue(frame.IsValid(), "Each frame should be valid") frame_count += 1 self.assertEqual( frame_count, frame_list.GetSize(), "Iterator should visit all frames", ) # Test that we can iterate multiple times second_count = 0 for frame in frame_list: second_count += 1 self.assertEqual( frame_count, second_count, "Should be able to iterate multiple times" ) def frame_list_indexing(self): """Test SBFrameList indexing and length.""" exe = self.getBuildArtifact("a.out") target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( self, "Set break point at this line", lldb.SBFileSpec(self.main_source) ) self.assertTrue( thread.IsValid(), "There should be a thread stopped due to breakpoint" ) frame_list = thread.GetFrames() # Test len() self.assertEqual( len(frame_list), frame_list.GetSize(), "len() should return frame count" ) # Test positive indexing first_frame = frame_list[0] self.assertTrue(first_frame.IsValid(), "First frame should be valid") self.assertEqual( first_frame.GetPC(), thread.GetFrameAtIndex(0).GetPC(), "Indexed frame should match", ) # Test negative indexing if len(frame_list) > 0: last_frame = frame_list[-1] self.assertTrue(last_frame.IsValid(), "Last frame should be valid") self.assertEqual( last_frame.GetPC(), thread.GetFrameAtIndex(len(frame_list) - 1).GetPC(), "Negative indexing should work", ) # Test out of bounds returns None out_of_bounds = frame_list[10000] self.assertIsNone(out_of_bounds, "Out of bounds index should return None") # Test bool conversion self.assertTrue(bool(frame_list), "Non-empty frame list should be truthy") # Test Clear() frame_list.Clear() # Note: Clear() clears the underlying StackFrameList cache, # but the frame list object itself should still be valid self.assertTrue( frame_list.IsValid(), "Frame list should still be valid after Clear()" ) def frame_list_get_thread(self): """Test SBFrameList.GetThread() returns correct thread.""" exe = self.getBuildArtifact("a.out") target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( self, "Set break point at this line", lldb.SBFileSpec(self.main_source) ) self.assertTrue( thread.IsValid(), "There should be a thread stopped due to breakpoint" ) frame_list = thread.GetFrames() self.assertTrue(frame_list.IsValid(), "Frame list should be valid") # Test GetThread() returns the correct thread thread_from_list = frame_list.GetThread() self.assertTrue( thread_from_list.IsValid(), "Thread from frame list should be valid" ) self.assertEqual( thread_from_list.GetThreadID(), thread.GetThreadID(), "Frame list should return the correct thread", ) # Verify it's the same thread object self.assertEqual( thread_from_list.GetProcess().GetProcessID(), thread.GetProcess().GetProcessID(), "Thread should belong to same process", )