blob: f348ce492e547f733e70e6b24b30ddf33bdfb98c [file] [log] [blame]
"""
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",
)