1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
"""
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",
)
|